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