1 //===- MPIntTest.cpp - Tests for MPInt ------------------------------------===// 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 "llvm/ADT/DynamicAPInt.h" 10 #include "llvm/ADT/SlowDynamicAPInt.h" 11 #include "gtest/gtest.h" 12 13 using namespace llvm; 14 15 namespace { 16 // googletest boilerplate to run the same tests with both MPInt and SlowMPInt. 17 template <typename> class IntTest : public testing::Test {}; 18 using TypeList = testing::Types<DynamicAPInt, detail::SlowDynamicAPInt>; 19 20 // This is for pretty-printing the test name with the name of the class in use. 21 class TypeNames { 22 public: 23 template <typename T> 24 static std::string GetName(int) { // NOLINT; gtest mandates this name. 25 if (std::is_same<T, DynamicAPInt>()) 26 return "MPInt"; 27 if (std::is_same<T, detail::SlowDynamicAPInt>()) 28 return "SlowMPInt"; 29 llvm_unreachable("Unknown class!"); 30 } 31 }; 32 TYPED_TEST_SUITE(IntTest, TypeList, TypeNames); 33 34 TYPED_TEST(IntTest, ops) { 35 TypeParam Two(2), Five(5), Seven(7), Ten(10); 36 EXPECT_EQ(Five + Five, Ten); 37 EXPECT_EQ(Five * Five, 2 * Ten + Five); 38 EXPECT_EQ(Five * Five, 3 * Ten - Five); 39 EXPECT_EQ(Five * Two, Ten); 40 EXPECT_EQ(Five / Two, Two); 41 EXPECT_EQ(Five % Two, Two / Two); 42 43 EXPECT_EQ(-Ten % Seven, -10 % 7); 44 EXPECT_EQ(Ten % -Seven, 10 % -7); 45 EXPECT_EQ(-Ten % -Seven, -10 % -7); 46 EXPECT_EQ(Ten % Seven, 10 % 7); 47 48 EXPECT_EQ(-Ten / Seven, -10 / 7); 49 EXPECT_EQ(Ten / -Seven, 10 / -7); 50 EXPECT_EQ(-Ten / -Seven, -10 / -7); 51 EXPECT_EQ(Ten / Seven, 10 / 7); 52 53 TypeParam X = Ten; 54 X += Five; 55 EXPECT_EQ(X, 15); 56 X *= Two; 57 EXPECT_EQ(X, 30); 58 X /= Seven; 59 EXPECT_EQ(X, 4); 60 X -= Two * 10; 61 EXPECT_EQ(X, -16); 62 X *= 2 * Two; 63 EXPECT_EQ(X, -64); 64 X /= Two / -2; 65 EXPECT_EQ(X, 64); 66 67 EXPECT_LE(Ten, Ten); 68 EXPECT_GE(Ten, Ten); 69 EXPECT_EQ(Ten, Ten); 70 EXPECT_FALSE(Ten != Ten); 71 EXPECT_FALSE(Ten < Ten); 72 EXPECT_FALSE(Ten > Ten); 73 EXPECT_LT(Five, Ten); 74 EXPECT_GT(Ten, Five); 75 } 76 77 TYPED_TEST(IntTest, ops64Overloads) { 78 TypeParam Two(2), Five(5), Seven(7), Ten(10); 79 EXPECT_EQ(Five + 5, Ten); 80 EXPECT_EQ(Five + 5, 5 + Five); 81 EXPECT_EQ(Five * 5, 2 * Ten + 5); 82 EXPECT_EQ(Five * 5, 3 * Ten - 5); 83 EXPECT_EQ(Five * Two, Ten); 84 EXPECT_EQ(5 / Two, 2); 85 EXPECT_EQ(Five / 2, 2); 86 EXPECT_EQ(2 % Two, 0); 87 EXPECT_EQ(2 - Two, 0); 88 EXPECT_EQ(2 % Two, Two % 2); 89 90 TypeParam X = Ten; 91 X += 5; 92 EXPECT_EQ(X, 15); 93 X *= 2; 94 EXPECT_EQ(X, 30); 95 X /= 7; 96 EXPECT_EQ(X, 4); 97 X -= 20; 98 EXPECT_EQ(X, -16); 99 X *= 4; 100 EXPECT_EQ(X, -64); 101 X /= -1; 102 EXPECT_EQ(X, 64); 103 104 EXPECT_LE(Ten, 10); 105 EXPECT_GE(Ten, 10); 106 EXPECT_EQ(Ten, 10); 107 EXPECT_FALSE(Ten != 10); 108 EXPECT_FALSE(Ten < 10); 109 EXPECT_FALSE(Ten > 10); 110 EXPECT_LT(Five, 10); 111 EXPECT_GT(Ten, 5); 112 113 EXPECT_LE(10, Ten); 114 EXPECT_GE(10, Ten); 115 EXPECT_EQ(10, Ten); 116 EXPECT_FALSE(10 != Ten); 117 EXPECT_FALSE(10 < Ten); 118 EXPECT_FALSE(10 > Ten); 119 EXPECT_LT(5, Ten); 120 EXPECT_GT(10, Five); 121 } 122 123 TYPED_TEST(IntTest, overflows) { 124 TypeParam X(1ll << 60); 125 EXPECT_EQ((X * X - X * X * X * X) / (X * X * X), 1 - (1ll << 60)); 126 TypeParam Y(1ll << 62); 127 EXPECT_EQ((Y + Y + Y + Y + Y + Y) / Y, 6); 128 EXPECT_EQ(-(2 * (-Y)), 2 * Y); // -(-2^63) overflow. 129 X *= X; 130 EXPECT_EQ(X, (Y * Y) / 16); 131 Y += Y; 132 Y += Y; 133 Y += Y; 134 Y /= 8; 135 EXPECT_EQ(Y, 1ll << 62); 136 137 TypeParam Min(std::numeric_limits<int64_t>::min()); 138 TypeParam One(1); 139 EXPECT_EQ(floorDiv(Min, -One), -Min); 140 EXPECT_EQ(ceilDiv(Min, -One), -Min); 141 EXPECT_EQ(abs(Min), -Min); 142 143 TypeParam Z = Min; 144 Z /= -1; 145 EXPECT_EQ(Z, -Min); 146 TypeParam W(Min); 147 --W; 148 EXPECT_EQ(W, TypeParam(Min) - 1); 149 TypeParam U(Min); 150 U -= 1; 151 EXPECT_EQ(U, W); 152 153 TypeParam Max(std::numeric_limits<int64_t>::max()); 154 TypeParam V = Max; 155 ++V; 156 EXPECT_EQ(V, Max + 1); 157 TypeParam T = Max; 158 T += 1; 159 EXPECT_EQ(T, V); 160 } 161 162 TYPED_TEST(IntTest, floorCeilModAbsLcmGcd) { 163 TypeParam X(1ll << 50), One(1), Two(2), Three(3); 164 165 // Run on small values and large values. 166 for (const TypeParam &Y : {X, X * X}) { 167 EXPECT_EQ(floorDiv(3 * Y, Three), Y); 168 EXPECT_EQ(ceilDiv(3 * Y, Three), Y); 169 EXPECT_EQ(floorDiv(3 * Y - 1, Three), Y - 1); 170 EXPECT_EQ(ceilDiv(3 * Y - 1, Three), Y); 171 EXPECT_EQ(floorDiv(3 * Y - 2, Three), Y - 1); 172 EXPECT_EQ(ceilDiv(3 * Y - 2, Three), Y); 173 174 EXPECT_EQ(mod(3 * Y, Three), 0); 175 EXPECT_EQ(mod(3 * Y + 1, Three), One); 176 EXPECT_EQ(mod(3 * Y + 2, Three), Two); 177 178 EXPECT_EQ(floorDiv(3 * Y, Y), 3); 179 EXPECT_EQ(ceilDiv(3 * Y, Y), 3); 180 EXPECT_EQ(floorDiv(3 * Y - 1, Y), 2); 181 EXPECT_EQ(ceilDiv(3 * Y - 1, Y), 3); 182 EXPECT_EQ(floorDiv(3 * Y - 2, Y), 2); 183 EXPECT_EQ(ceilDiv(3 * Y - 2, Y), 3); 184 185 EXPECT_EQ(mod(3 * Y, Y), 0); 186 EXPECT_EQ(mod(3 * Y + 1, Y), 1); 187 EXPECT_EQ(mod(3 * Y + 2, Y), 2); 188 189 EXPECT_EQ(abs(Y), Y); 190 EXPECT_EQ(abs(-Y), Y); 191 192 EXPECT_EQ(gcd(3 * Y, Three), Three); 193 EXPECT_EQ(lcm(Y, Three), 3 * Y); 194 EXPECT_EQ(gcd(2 * Y, 3 * Y), Y); 195 EXPECT_EQ(lcm(2 * Y, 3 * Y), 6 * Y); 196 EXPECT_EQ(gcd(15 * Y, 6 * Y), 3 * Y); 197 EXPECT_EQ(lcm(15 * Y, 6 * Y), 30 * Y); 198 } 199 } 200 } // namespace 201