1 //===- MPIntTest.cpp - Tests for MPInt ------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/DynamicAPInt.h"
10 #include "llvm/ADT/SlowDynamicAPInt.h"
11 #include "gtest/gtest.h"
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
>;
20 // This is for pretty-printing the test name with the name of the class in use.
24 static std::string
GetName(int) { // NOLINT; gtest mandates this name.
25 if (std::is_same
<T
, DynamicAPInt
>())
27 if (std::is_same
<T
, detail::SlowDynamicAPInt
>())
29 llvm_unreachable("Unknown class!");
32 TYPED_TEST_SUITE(IntTest
, TypeList
, TypeNames
);
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
);
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);
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);
70 EXPECT_FALSE(Ten
!= Ten
);
71 EXPECT_FALSE(Ten
< Ten
);
72 EXPECT_FALSE(Ten
> Ten
);
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);
107 EXPECT_FALSE(Ten
!= 10);
108 EXPECT_FALSE(Ten
< 10);
109 EXPECT_FALSE(Ten
> 10);
116 EXPECT_FALSE(10 != Ten
);
117 EXPECT_FALSE(10 < Ten
);
118 EXPECT_FALSE(10 > Ten
);
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.
130 EXPECT_EQ(X
, (Y
* Y
) / 16);
135 EXPECT_EQ(Y
, 1ll << 62);
137 TypeParam
Min(std::numeric_limits
<int64_t>::min());
139 EXPECT_EQ(floorDiv(Min
, -One
), -Min
);
140 EXPECT_EQ(ceilDiv(Min
, -One
), -Min
);
141 EXPECT_EQ(abs(Min
), -Min
);
148 EXPECT_EQ(W
, TypeParam(Min
) - 1);
153 TypeParam
Max(std::numeric_limits
<int64_t>::max());
156 EXPECT_EQ(V
, Max
+ 1);
162 TYPED_TEST(IntTest
, floorCeilModAbsLcmGcd
) {
163 TypeParam
X(1ll << 50), One(1), Two(2), Three(3);
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
);
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
);
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);
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);
189 EXPECT_EQ(abs(Y
), Y
);
190 EXPECT_EQ(abs(-Y
), Y
);
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
);