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 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 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 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 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 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 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 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 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 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 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 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