summaryrefslogtreecommitdiff
path: root/unittests/ADT/APIntTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/ADT/APIntTest.cpp')
-rw-r--r--unittests/ADT/APIntTest.cpp138
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