diff options
Diffstat (limited to 'unittests/ADT/APIntTest.cpp')
-rw-r--r-- | unittests/ADT/APIntTest.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 05fad386064c..48f91195e446 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -1060,6 +1060,38 @@ TEST(APIntTest, divremuint) { APInt{1024, 1}); } +TEST(APIntTest, divrem_simple) { + // Test simple cases. + APInt A(65, 2), B(65, 2); + APInt Q, R; + + // X / X + APInt::sdivrem(A, B, Q, R); + EXPECT_EQ(Q, APInt(65, 1)); + EXPECT_EQ(R, APInt(65, 0)); + APInt::udivrem(A, B, Q, R); + EXPECT_EQ(Q, APInt(65, 1)); + EXPECT_EQ(R, APInt(65, 0)); + + // 0 / X + APInt O(65, 0); + APInt::sdivrem(O, B, Q, R); + EXPECT_EQ(Q, APInt(65, 0)); + EXPECT_EQ(R, APInt(65, 0)); + APInt::udivrem(O, B, Q, R); + EXPECT_EQ(Q, APInt(65, 0)); + EXPECT_EQ(R, APInt(65, 0)); + + // X / 1 + APInt I(65, 1); + APInt::sdivrem(A, I, Q, R); + EXPECT_EQ(Q, A); + EXPECT_EQ(R, APInt(65, 0)); + APInt::udivrem(A, I, Q, R); + EXPECT_EQ(Q, A); + EXPECT_EQ(R, APInt(65, 0)); +} + TEST(APIntTest, fromString) { EXPECT_EQ(APInt(32, 0), APInt(32, "0", 2)); EXPECT_EQ(APInt(32, 1), APInt(32, "1", 2)); @@ -1659,6 +1691,38 @@ TEST(APIntTest, isShiftedMask) { } } +// Test that self-move works, but only when we're using MSVC. +#if defined(_MSC_VER) +#if defined(__clang__) +// Disable the pragma warning from versions of Clang without -Wself-move +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" +// Disable the warning that triggers on exactly what is being tested. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wself-move" +#endif +TEST(APIntTest, SelfMoveAssignment) { + APInt X(32, 0xdeadbeef); + X = std::move(X); + EXPECT_EQ(32u, X.getBitWidth()); + EXPECT_EQ(0xdeadbeefULL, X.getLimitedValue()); + + uint64_t Bits[] = {0xdeadbeefdeadbeefULL, 0xdeadbeefdeadbeefULL}; + APInt Y(128, Bits); + Y = std::move(Y); + EXPECT_EQ(128u, Y.getBitWidth()); + EXPECT_EQ(~0ULL, Y.getLimitedValue()); + const uint64_t *Raw = Y.getRawData(); + EXPECT_EQ(2u, Y.getNumWords()); + EXPECT_EQ(0xdeadbeefdeadbeefULL, Raw[0]); + EXPECT_EQ(0xdeadbeefdeadbeefULL, Raw[1]); +} +#if defined(__clang__) +#pragma clang diagnostic pop +#pragma clang diagnostic pop +#endif +#endif // _MSC_VER + TEST(APIntTest, reverseBits) { EXPECT_EQ(1, APInt(1, 1).reverseBits()); EXPECT_EQ(0, APInt(1, 0).reverseBits()); @@ -1768,6 +1832,13 @@ TEST(APIntTest, extractBits) { i257.extractBits(128, 1).getSExtValue()); EXPECT_EQ(static_cast<int64_t>(0xFFFFFFFFFF80007Full), i257.extractBits(129, 1).getSExtValue()); + + EXPECT_EQ(APInt(48, 0), + APInt(144, "281474976710655", 10).extractBits(48, 48)); + EXPECT_EQ(APInt(48, 0x0000ffffffffffffull), + APInt(144, "281474976710655", 10).extractBits(48, 0)); + EXPECT_EQ(APInt(48, 0x00007fffffffffffull), + APInt(144, "281474976710655", 10).extractBits(48, 1)); } TEST(APIntTest, getLowBitsSet) { @@ -2219,4 +2290,71 @@ TEST(APIntTest, multiply) { EXPECT_EQ(64U, i96.countTrailingZeros()); } +TEST(APIntTest, RoundingUDiv) { + for (uint64_t Ai = 1; Ai <= 255; Ai++) { + APInt A(8, Ai); + APInt Zero(8, 0); + EXPECT_EQ(0, APIntOps::RoundingUDiv(Zero, A, APInt::Rounding::UP)); + EXPECT_EQ(0, APIntOps::RoundingUDiv(Zero, A, APInt::Rounding::DOWN)); + EXPECT_EQ(0, APIntOps::RoundingUDiv(Zero, A, APInt::Rounding::TOWARD_ZERO)); + + for (uint64_t Bi = 1; Bi <= 255; Bi++) { + APInt B(8, Bi); + { + APInt Quo = APIntOps::RoundingUDiv(A, B, APInt::Rounding::UP); + auto Prod = Quo.zext(16) * B.zext(16); + EXPECT_TRUE(Prod.uge(Ai)); + if (Prod.ugt(Ai)) { + EXPECT_TRUE(((Quo - 1).zext(16) * B.zext(16)).ult(Ai)); + } + } + { + APInt Quo = A.udiv(B); + EXPECT_EQ(Quo, APIntOps::RoundingUDiv(A, B, APInt::Rounding::TOWARD_ZERO)); + EXPECT_EQ(Quo, APIntOps::RoundingUDiv(A, B, APInt::Rounding::DOWN)); + } + } + } +} + +TEST(APIntTest, RoundingSDiv) { + for (int64_t Ai = -128; Ai <= 127; Ai++) { + APInt A(8, Ai); + + if (Ai != 0) { + APInt Zero(8, 0); + EXPECT_EQ(0, APIntOps::RoundingSDiv(Zero, A, APInt::Rounding::UP)); + EXPECT_EQ(0, APIntOps::RoundingSDiv(Zero, A, APInt::Rounding::DOWN)); + EXPECT_EQ(0, APIntOps::RoundingSDiv(Zero, A, APInt::Rounding::TOWARD_ZERO)); + } + + for (uint64_t Bi = -128; Bi <= 127; Bi++) { + if (Bi == 0) + continue; + + APInt B(8, Bi); + { + APInt Quo = APIntOps::RoundingSDiv(A, B, APInt::Rounding::UP); + auto Prod = Quo.sext(16) * B.sext(16); + EXPECT_TRUE(Prod.uge(A)); + if (Prod.ugt(A)) { + EXPECT_TRUE(((Quo - 1).sext(16) * B.sext(16)).ult(A)); + } + } + { + APInt Quo = APIntOps::RoundingSDiv(A, B, APInt::Rounding::DOWN); + auto Prod = Quo.sext(16) * B.sext(16); + EXPECT_TRUE(Prod.ule(A)); + if (Prod.ult(A)) { + EXPECT_TRUE(((Quo + 1).sext(16) * B.sext(16)).ugt(A)); + } + } + { + APInt Quo = A.sdiv(B); + EXPECT_EQ(Quo, APIntOps::RoundingSDiv(A, B, APInt::Rounding::TOWARD_ZERO)); + } + } + } +} + } // end anonymous namespace |