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 using UInt128 = __llvm_libc::cpp::UInt<128>;
14 
15 TEST(LlvmLibcUInt128ClassTest, BasicInit) {
16   UInt128 empty;
17   UInt128 half_val(12345);
18   UInt128 full_val({12345, 67890});
19   ASSERT_TRUE(half_val != full_val);
20 }
21 
22 TEST(LlvmLibcUInt128ClassTest, AdditionTests) {
23   UInt128 val1(12345);
24   UInt128 val2(54321);
25   UInt128 result1(66666);
26   EXPECT_EQ(val1 + val2, result1);
27   EXPECT_EQ((val1 + val2), (val2 + val1)); // addition is reciprocal
28 
29   // Test overflow
30   UInt128 val3({0xf000000000000001, 0});
31   UInt128 val4({0x100000000000000f, 0});
32   UInt128 result2({0x10, 0x1});
33   EXPECT_EQ(val3 + val4, result2);
34   EXPECT_EQ(val3 + val4, val4 + val3);
35 }
36 
37 TEST(LlvmLibcUInt128ClassTest, MultiplicationTests) {
38   UInt128 val1({5, 0});
39   UInt128 val2({10, 0});
40   UInt128 result1({50, 0});
41   EXPECT_EQ((val1 * val2), result1);
42   EXPECT_EQ((val1 * val2), (val2 * val1)); // multiplication is reciprocal
43 
44   // Check that the multiplication works accross the whole number
45   UInt128 val3({0xf, 0});
46   UInt128 val4({0x1111111111111111, 0x1111111111111111});
47   UInt128 result2({0xffffffffffffffff, 0xffffffffffffffff});
48   EXPECT_EQ((val3 * val4), result2);
49   EXPECT_EQ((val3 * val4), (val4 * val3));
50 
51   // Check that multiplication doesn't reorder the bits.
52   UInt128 val5({2, 0});
53   UInt128 val6({0x1357024675316420, 0x0123456776543210});
54   UInt128 result3({0x26ae048cea62c840, 0x02468aceeca86420});
55 
56   EXPECT_EQ((val5 * val6), result3);
57   EXPECT_EQ((val5 * val6), (val6 * val5));
58 
59   // Make sure that multiplication handles overflow correctly.
60   UInt128 val7(2);
61   UInt128 val8({0x8000800080008000, 0x8000800080008000});
62   UInt128 result4({0x0001000100010000, 0x0001000100010001});
63   EXPECT_EQ((val7 * val8), result4);
64   EXPECT_EQ((val7 * val8), (val8 * val7));
65 
66   // val9 is the 128 bit mantissa of 1e60 as a float, val10 is the mantissa for
67   // 1e-60. They almost cancel on the high bits, but the result we're looking
68   // for is just the low bits. The full result would be
69   // 0x7fffffffffffffffffffffffffffffff3a4f32d17f40d08f917cf11d1e039c50
70   UInt128 val9({0x01D762422C946590, 0x9F4F2726179A2245});
71   UInt128 val10({0x3792F412CB06794D, 0xCDB02555653131B6});
72   UInt128 result5({0x917cf11d1e039c50, 0x3a4f32d17f40d08f});
73   EXPECT_EQ((val9 * val10), result5);
74   EXPECT_EQ((val9 * val10), (val10 * val9));
75 }
76 
77 TEST(LlvmLibcUInt128ClassTest, ShiftLeftTests) {
78   UInt128 val1(0x0123456789abcdef);
79   UInt128 result1(0x123456789abcdef0);
80   EXPECT_EQ((val1 << 4), result1);
81 
82   UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});
83   UInt128 result2({0x02468ace00000000, 0x9abcdef013579bdf});
84   EXPECT_EQ((val2 << 32), result2);
85 
86   UInt128 result3({0, 0x13579bdf02468ace});
87   EXPECT_EQ((val2 << 64), result3);
88 
89   UInt128 result4({0, 0x02468ace00000000});
90   EXPECT_EQ((val2 << 96), result4);
91 
92   UInt128 result5({0, 0x2468ace000000000});
93   EXPECT_EQ((val2 << 100), result5);
94 
95   UInt128 result6({0, 0});
96   EXPECT_EQ((val2 << 128), result6);
97   EXPECT_EQ((val2 << 256), result6);
98 }
99 
100 TEST(LlvmLibcUInt128ClassTest, ShiftRightTests) {
101   UInt128 val1(0x0123456789abcdef);
102   UInt128 result1(0x00123456789abcde);
103   EXPECT_EQ((val1 >> 4), result1);
104 
105   UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});
106   UInt128 result2({0x9abcdef013579bdf, 0x0000000012345678});
107   EXPECT_EQ((val2 >> 32), result2);
108 
109   UInt128 result3({0x123456789abcdef0, 0});
110   EXPECT_EQ((val2 >> 64), result3);
111 
112   UInt128 result4({0x0000000012345678, 0});
113   EXPECT_EQ((val2 >> 96), result4);
114 
115   UInt128 result5({0x0000000001234567, 0});
116   EXPECT_EQ((val2 >> 100), result5);
117 
118   UInt128 result6({0, 0});
119   EXPECT_EQ((val2 >> 128), result6);
120   EXPECT_EQ((val2 >> 256), result6);
121 }
122 
123 TEST(LlvmLibcUInt128ClassTest, AndTests) {
124   UInt128 base({0xffff00000000ffff, 0xffffffff00000000});
125   UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
126   uint64_t val64 = 0xf0f0f0f00f0f0f0f;
127   int val32 = 0x0f0f0f0f;
128   UInt128 result128({0xf0f0000000000f0f, 0xff00ff0000000000});
129   UInt128 result64(0xf0f0000000000f0f);
130   UInt128 result32(0x00000f0f);
131   EXPECT_EQ((base & val128), result128);
132   EXPECT_EQ((base & val64), result64);
133   EXPECT_EQ((base & val32), result32);
134 }
135 
136 TEST(LlvmLibcUInt128ClassTest, OrTests) {
137   UInt128 base({0xffff00000000ffff, 0xffffffff00000000});
138   UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
139   uint64_t val64 = 0xf0f0f0f00f0f0f0f;
140   int val32 = 0x0f0f0f0f;
141   UInt128 result128({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
142   UInt128 result64({0xfffff0f00f0fffff, 0xffffffff00000000});
143   UInt128 result32({0xffff00000f0fffff, 0xffffffff00000000});
144   EXPECT_EQ((base | val128), result128);
145   EXPECT_EQ((base | val64), result64);
146   EXPECT_EQ((base | val32), result32);
147 }
148 
149 TEST(LlvmLibcUInt128ClassTest, EqualsTests) {
150   UInt128 a1({0xffffffff00000000, 0xffff00000000ffff});
151   UInt128 a2({0xffffffff00000000, 0xffff00000000ffff});
152   UInt128 b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});
153   UInt128 a_reversed({0xffff00000000ffff, 0xffffffff00000000});
154   UInt128 a_upper(0xffff00000000ffff);
155   UInt128 a_lower(0xffffffff00000000);
156   ASSERT_TRUE(a1 == a1);
157   ASSERT_TRUE(a1 == a2);
158   ASSERT_FALSE(a1 == b);
159   ASSERT_FALSE(a1 == a_reversed);
160   ASSERT_FALSE(a1 == a_lower);
161   ASSERT_FALSE(a1 == a_upper);
162   ASSERT_TRUE(a_lower != a_upper);
163 }
164