1 //===-- Unittests for the 128 bit integer class ---------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/CPP/UInt.h"
10 
11 #include "utils/UnitTest/Test.h"
12 
13 // We want to test __llvm_libc::cpp::UInt<128> explicitly. So, for convenience,
14 // we use a sugar which does not conflict with the UInt128 type which can
15 // resolve to __uint128_t if the platform has it.
16 using LL_UInt128 = __llvm_libc::cpp::UInt<128>;
17 
TEST(LlvmLibcUInt128ClassTest,BasicInit)18 TEST(LlvmLibcUInt128ClassTest, BasicInit) {
19   LL_UInt128 empty;
20   LL_UInt128 half_val(12345);
21   LL_UInt128 full_val({12345, 67890});
22   ASSERT_TRUE(half_val != full_val);
23 }
24 
TEST(LlvmLibcUInt128ClassTest,AdditionTests)25 TEST(LlvmLibcUInt128ClassTest, AdditionTests) {
26   LL_UInt128 val1(12345);
27   LL_UInt128 val2(54321);
28   LL_UInt128 result1(66666);
29   EXPECT_EQ(val1 + val2, result1);
30   EXPECT_EQ((val1 + val2), (val2 + val1)); // addition is reciprocal
31 
32   // Test overflow
33   LL_UInt128 val3({0xf000000000000001, 0});
34   LL_UInt128 val4({0x100000000000000f, 0});
35   LL_UInt128 result2({0x10, 0x1});
36   EXPECT_EQ(val3 + val4, result2);
37   EXPECT_EQ(val3 + val4, val4 + val3);
38 }
39 
TEST(LlvmLibcUInt128ClassTest,MultiplicationTests)40 TEST(LlvmLibcUInt128ClassTest, MultiplicationTests) {
41   LL_UInt128 val1({5, 0});
42   LL_UInt128 val2({10, 0});
43   LL_UInt128 result1({50, 0});
44   EXPECT_EQ((val1 * val2), result1);
45   EXPECT_EQ((val1 * val2), (val2 * val1)); // multiplication is reciprocal
46 
47   // Check that the multiplication works accross the whole number
48   LL_UInt128 val3({0xf, 0});
49   LL_UInt128 val4({0x1111111111111111, 0x1111111111111111});
50   LL_UInt128 result2({0xffffffffffffffff, 0xffffffffffffffff});
51   EXPECT_EQ((val3 * val4), result2);
52   EXPECT_EQ((val3 * val4), (val4 * val3));
53 
54   // Check that multiplication doesn't reorder the bits.
55   LL_UInt128 val5({2, 0});
56   LL_UInt128 val6({0x1357024675316420, 0x0123456776543210});
57   LL_UInt128 result3({0x26ae048cea62c840, 0x02468aceeca86420});
58 
59   EXPECT_EQ((val5 * val6), result3);
60   EXPECT_EQ((val5 * val6), (val6 * val5));
61 
62   // Make sure that multiplication handles overflow correctly.
63   LL_UInt128 val7(2);
64   LL_UInt128 val8({0x8000800080008000, 0x8000800080008000});
65   LL_UInt128 result4({0x0001000100010000, 0x0001000100010001});
66   EXPECT_EQ((val7 * val8), result4);
67   EXPECT_EQ((val7 * val8), (val8 * val7));
68 
69   // val9 is the 128 bit mantissa of 1e60 as a float, val10 is the mantissa for
70   // 1e-60. They almost cancel on the high bits, but the result we're looking
71   // for is just the low bits. The full result would be
72   // 0x7fffffffffffffffffffffffffffffff3a4f32d17f40d08f917cf11d1e039c50
73   LL_UInt128 val9({0x01D762422C946590, 0x9F4F2726179A2245});
74   LL_UInt128 val10({0x3792F412CB06794D, 0xCDB02555653131B6});
75   LL_UInt128 result5({0x917cf11d1e039c50, 0x3a4f32d17f40d08f});
76   EXPECT_EQ((val9 * val10), result5);
77   EXPECT_EQ((val9 * val10), (val10 * val9));
78 }
79 
TEST(LlvmLibcUInt128ClassTest,ShiftLeftTests)80 TEST(LlvmLibcUInt128ClassTest, ShiftLeftTests) {
81   LL_UInt128 val1(0x0123456789abcdef);
82   LL_UInt128 result1(0x123456789abcdef0);
83   EXPECT_EQ((val1 << 4), result1);
84 
85   LL_UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});
86   LL_UInt128 result2({0x02468ace00000000, 0x9abcdef013579bdf});
87   EXPECT_EQ((val2 << 32), result2);
88   LL_UInt128 val22 = val2;
89   val22 <<= 32;
90   EXPECT_EQ(val22, result2);
91 
92   LL_UInt128 result3({0, 0x13579bdf02468ace});
93   EXPECT_EQ((val2 << 64), result3);
94 
95   LL_UInt128 result4({0, 0x02468ace00000000});
96   EXPECT_EQ((val2 << 96), result4);
97 
98   LL_UInt128 result5({0, 0x2468ace000000000});
99   EXPECT_EQ((val2 << 100), result5);
100 
101   LL_UInt128 result6({0, 0});
102   EXPECT_EQ((val2 << 128), result6);
103   EXPECT_EQ((val2 << 256), result6);
104 }
105 
TEST(LlvmLibcUInt128ClassTest,ShiftRightTests)106 TEST(LlvmLibcUInt128ClassTest, ShiftRightTests) {
107   LL_UInt128 val1(0x0123456789abcdef);
108   LL_UInt128 result1(0x00123456789abcde);
109   EXPECT_EQ((val1 >> 4), result1);
110 
111   LL_UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});
112   LL_UInt128 result2({0x9abcdef013579bdf, 0x0000000012345678});
113   EXPECT_EQ((val2 >> 32), result2);
114   LL_UInt128 val22 = val2;
115   val22 >>= 32;
116   EXPECT_EQ(val22, result2);
117 
118   LL_UInt128 result3({0x123456789abcdef0, 0});
119   EXPECT_EQ((val2 >> 64), result3);
120 
121   LL_UInt128 result4({0x0000000012345678, 0});
122   EXPECT_EQ((val2 >> 96), result4);
123 
124   LL_UInt128 result5({0x0000000001234567, 0});
125   EXPECT_EQ((val2 >> 100), result5);
126 
127   LL_UInt128 result6({0, 0});
128   EXPECT_EQ((val2 >> 128), result6);
129   EXPECT_EQ((val2 >> 256), result6);
130 }
131 
TEST(LlvmLibcUInt128ClassTest,AndTests)132 TEST(LlvmLibcUInt128ClassTest, AndTests) {
133   LL_UInt128 base({0xffff00000000ffff, 0xffffffff00000000});
134   LL_UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
135   uint64_t val64 = 0xf0f0f0f00f0f0f0f;
136   int val32 = 0x0f0f0f0f;
137   LL_UInt128 result128({0xf0f0000000000f0f, 0xff00ff0000000000});
138   LL_UInt128 result64(0xf0f0000000000f0f);
139   LL_UInt128 result32(0x00000f0f);
140   EXPECT_EQ((base & val128), result128);
141   EXPECT_EQ((base & val64), result64);
142   EXPECT_EQ((base & val32), result32);
143 }
144 
TEST(LlvmLibcUInt128ClassTest,OrTests)145 TEST(LlvmLibcUInt128ClassTest, OrTests) {
146   LL_UInt128 base({0xffff00000000ffff, 0xffffffff00000000});
147   LL_UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
148   uint64_t val64 = 0xf0f0f0f00f0f0f0f;
149   int val32 = 0x0f0f0f0f;
150   LL_UInt128 result128({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
151   LL_UInt128 result64({0xfffff0f00f0fffff, 0xffffffff00000000});
152   LL_UInt128 result32({0xffff00000f0fffff, 0xffffffff00000000});
153   EXPECT_EQ((base | val128), result128);
154   EXPECT_EQ((base | val64), result64);
155   EXPECT_EQ((base | val32), result32);
156 }
157 
TEST(LlvmLibcUInt128ClassTest,CompoundAssignments)158 TEST(LlvmLibcUInt128ClassTest, CompoundAssignments) {
159   LL_UInt128 x({0xffff00000000ffff, 0xffffffff00000000});
160   LL_UInt128 b({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
161 
162   LL_UInt128 a = x;
163   a |= b;
164   LL_UInt128 or_result({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
165   EXPECT_EQ(a, or_result);
166 
167   a = x;
168   a &= b;
169   LL_UInt128 and_result({0xf0f0000000000f0f, 0xff00ff0000000000});
170   EXPECT_EQ(a, and_result);
171 
172   a = x;
173   a ^= b;
174   LL_UInt128 xor_result({0x0f0ff0f00f0ff0f0, 0x00ff00ff00ff00ff});
175   EXPECT_EQ(a, xor_result);
176 
177   a = LL_UInt128(uint64_t(0x0123456789abcdef));
178   LL_UInt128 shift_left_result(uint64_t(0x123456789abcdef0));
179   a <<= 4;
180   EXPECT_EQ(a, shift_left_result);
181 
182   a = LL_UInt128(uint64_t(0x123456789abcdef1));
183   LL_UInt128 shift_right_result(uint64_t(0x0123456789abcdef));
184   a >>= 4;
185   EXPECT_EQ(a, shift_right_result);
186 
187   a = LL_UInt128({0xf000000000000001, 0});
188   b = LL_UInt128({0x100000000000000f, 0});
189   LL_UInt128 add_result({0x10, 0x1});
190   a += b;
191   EXPECT_EQ(a, add_result);
192 
193   a = LL_UInt128({0xf, 0});
194   b = LL_UInt128({0x1111111111111111, 0x1111111111111111});
195   LL_UInt128 mul_result({0xffffffffffffffff, 0xffffffffffffffff});
196   a *= b;
197   EXPECT_EQ(a, mul_result);
198 }
199 
TEST(LlvmLibcUInt128ClassTest,UnaryPredecrement)200 TEST(LlvmLibcUInt128ClassTest, UnaryPredecrement) {
201   LL_UInt128 a = LL_UInt128({0x1111111111111111, 0x1111111111111111});
202   ++a;
203   EXPECT_EQ(a, LL_UInt128({0x1111111111111112, 0x1111111111111111}));
204 
205   a = LL_UInt128({0xffffffffffffffff, 0x0});
206   ++a;
207   EXPECT_EQ(a, LL_UInt128({0x0, 0x1}));
208 
209   a = LL_UInt128({0xffffffffffffffff, 0xffffffffffffffff});
210   ++a;
211   EXPECT_EQ(a, LL_UInt128({0x0, 0x0}));
212 }
213 
TEST(LlvmLibcUInt128ClassTest,EqualsTests)214 TEST(LlvmLibcUInt128ClassTest, EqualsTests) {
215   LL_UInt128 a1({0xffffffff00000000, 0xffff00000000ffff});
216   LL_UInt128 a2({0xffffffff00000000, 0xffff00000000ffff});
217   LL_UInt128 b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});
218   LL_UInt128 a_reversed({0xffff00000000ffff, 0xffffffff00000000});
219   LL_UInt128 a_upper(0xffff00000000ffff);
220   LL_UInt128 a_lower(0xffffffff00000000);
221   ASSERT_TRUE(a1 == a1);
222   ASSERT_TRUE(a1 == a2);
223   ASSERT_FALSE(a1 == b);
224   ASSERT_FALSE(a1 == a_reversed);
225   ASSERT_FALSE(a1 == a_lower);
226   ASSERT_FALSE(a1 == a_upper);
227   ASSERT_TRUE(a_lower != a_upper);
228 }
229 
TEST(LlvmLibcUInt128ClassTest,ComparisonTests)230 TEST(LlvmLibcUInt128ClassTest, ComparisonTests) {
231   LL_UInt128 a({0xffffffff00000000, 0xffff00000000ffff});
232   LL_UInt128 b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});
233   EXPECT_GT(a, b);
234   EXPECT_GE(a, b);
235   EXPECT_LT(b, a);
236   EXPECT_LE(b, a);
237 
238   LL_UInt128 x(0xffffffff00000000);
239   LL_UInt128 y(0x00000000ffffffff);
240   EXPECT_GT(x, y);
241   EXPECT_GE(x, y);
242   EXPECT_LT(y, x);
243   EXPECT_LE(y, x);
244 
245   EXPECT_LE(a, a);
246   EXPECT_GE(a, a);
247 }
248