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