summaryrefslogtreecommitdiff
path: root/unittests/ADT
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/ADT')
-rw-r--r--unittests/ADT/APIntTest.cpp132
-rw-r--r--unittests/ADT/BitVectorTest.cpp122
2 files changed, 219 insertions, 35 deletions
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index 65481f5b2f220..5d3afe9a159f3 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -37,11 +37,6 @@ TEST(APIntTest, i64_ArithmeticRightShiftNegative) {
EXPECT_EQ(neg_one, neg_one.ashr(7));
}
-TEST(APIntTest, i64_LogicalRightShiftNegative) {
- const APInt neg_one(128, static_cast<uint64_t>(-1), true);
- EXPECT_EQ(0, neg_one.lshr(257));
-}
-
TEST(APIntTest, i128_NegativeCount) {
APInt Minus3(128, static_cast<uint64_t>(-3), true);
EXPECT_EQ(126u, Minus3.countLeadingOnes());
@@ -1606,36 +1601,6 @@ TEST(APIntTest, isShiftedMask) {
}
}
-#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
-}
-
TEST(APIntTest, reverseBits) {
EXPECT_EQ(1, APInt(1, 1).reverseBits());
EXPECT_EQ(0, APInt(1, 0).reverseBits());
@@ -2025,3 +1990,100 @@ TEST(APIntTest, GCD) {
APInt C = GreatestCommonDivisor(A, B);
EXPECT_EQ(C, HugePrime);
}
+
+TEST(APIntTest, LogicalRightShift) {
+ APInt i256(APInt::getHighBitsSet(256, 2));
+
+ i256.lshrInPlace(1);
+ EXPECT_EQ(1U, i256.countLeadingZeros());
+ EXPECT_EQ(253U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256.lshrInPlace(62);
+ EXPECT_EQ(63U, i256.countLeadingZeros());
+ EXPECT_EQ(191U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256.lshrInPlace(65);
+ EXPECT_EQ(128U, i256.countLeadingZeros());
+ EXPECT_EQ(126U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256.lshrInPlace(64);
+ EXPECT_EQ(192U, i256.countLeadingZeros());
+ EXPECT_EQ(62U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256.lshrInPlace(63);
+ EXPECT_EQ(255U, i256.countLeadingZeros());
+ EXPECT_EQ(0U, i256.countTrailingZeros());
+ EXPECT_EQ(1U, i256.countPopulation());
+
+ // Ensure we handle large shifts of multi-word.
+ const APInt neg_one(128, static_cast<uint64_t>(-1), true);
+ EXPECT_EQ(0, neg_one.lshr(128));
+}
+
+TEST(APIntTest, LeftShift) {
+ APInt i256(APInt::getLowBitsSet(256, 2));
+
+ i256 <<= 1;
+ EXPECT_EQ(253U, i256.countLeadingZeros());
+ EXPECT_EQ(1U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256 <<= 62;
+ EXPECT_EQ(191U, i256.countLeadingZeros());
+ EXPECT_EQ(63U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256 <<= 65;
+ EXPECT_EQ(126U, i256.countLeadingZeros());
+ EXPECT_EQ(128U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256 <<= 64;
+ EXPECT_EQ(62U, i256.countLeadingZeros());
+ EXPECT_EQ(192U, i256.countTrailingZeros());
+ EXPECT_EQ(2U, i256.countPopulation());
+
+ i256 <<= 63;
+ EXPECT_EQ(0U, i256.countLeadingZeros());
+ EXPECT_EQ(255U, i256.countTrailingZeros());
+ EXPECT_EQ(1U, i256.countPopulation());
+
+ // Ensure we handle large shifts of multi-word.
+ const APInt neg_one(128, static_cast<uint64_t>(-1), true);
+ EXPECT_EQ(0, neg_one.shl(128));
+}
+
+TEST(APIntTest, isSubsetOf) {
+ APInt i32_1(32, 1);
+ APInt i32_2(32, 2);
+ APInt i32_3(32, 3);
+ EXPECT_FALSE(i32_3.isSubsetOf(i32_1));
+ EXPECT_TRUE(i32_1.isSubsetOf(i32_3));
+ EXPECT_FALSE(i32_2.isSubsetOf(i32_1));
+ EXPECT_FALSE(i32_1.isSubsetOf(i32_2));
+ EXPECT_TRUE(i32_3.isSubsetOf(i32_3));
+
+ APInt i128_1(128, 1);
+ APInt i128_2(128, 2);
+ APInt i128_3(128, 3);
+ EXPECT_FALSE(i128_3.isSubsetOf(i128_1));
+ EXPECT_TRUE(i128_1.isSubsetOf(i128_3));
+ EXPECT_FALSE(i128_2.isSubsetOf(i128_1));
+ EXPECT_FALSE(i128_1.isSubsetOf(i128_2));
+ EXPECT_TRUE(i128_3.isSubsetOf(i128_3));
+
+ i128_1 <<= 64;
+ i128_2 <<= 64;
+ i128_3 <<= 64;
+ EXPECT_FALSE(i128_3.isSubsetOf(i128_1));
+ EXPECT_TRUE(i128_1.isSubsetOf(i128_3));
+ EXPECT_FALSE(i128_2.isSubsetOf(i128_1));
+ EXPECT_FALSE(i128_1.isSubsetOf(i128_2));
+ EXPECT_TRUE(i128_3.isSubsetOf(i128_3));
+}
+
+} // end anonymous namespace
diff --git a/unittests/ADT/BitVectorTest.cpp b/unittests/ADT/BitVectorTest.cpp
index 98ef66735ad23..71b6be36c3bd8 100644
--- a/unittests/ADT/BitVectorTest.cpp
+++ b/unittests/ADT/BitVectorTest.cpp
@@ -345,6 +345,128 @@ TYPED_TEST(BitVectorTest, BinOps) {
EXPECT_FALSE(B.anyCommon(A));
}
+typedef std::vector<std::pair<int, int>> RangeList;
+
+template <typename VecType>
+static inline VecType createBitVector(uint32_t Size,
+ const RangeList &setRanges) {
+ VecType V;
+ V.resize(Size);
+ for (auto &R : setRanges)
+ V.set(R.first, R.second);
+ return V;
+}
+
+TYPED_TEST(BitVectorTest, ShiftOpsSingleWord) {
+ // Test that shift ops work when the desired shift amount is less
+ // than one word.
+
+ // 1. Case where the number of bits in the BitVector also fit into a single
+ // word.
+ TypeParam A = createBitVector<TypeParam>(12, {{2, 4}, {8, 10}});
+ TypeParam B = A;
+
+ EXPECT_EQ(4U, A.count());
+ EXPECT_TRUE(A.test(2));
+ EXPECT_TRUE(A.test(3));
+ EXPECT_TRUE(A.test(8));
+ EXPECT_TRUE(A.test(9));
+
+ A >>= 1;
+ EXPECT_EQ(createBitVector<TypeParam>(12, {{1, 3}, {7, 9}}), A);
+
+ A <<= 1;
+ EXPECT_EQ(B, A);
+
+ A >>= 10;
+ EXPECT_EQ(createBitVector<TypeParam>(12, {}), A);
+
+ A = B;
+ A <<= 10;
+ EXPECT_EQ(createBitVector<TypeParam>(12, {}), A);
+
+ // 2. Case where the number of bits in the BitVector do not fit into a single
+ // word.
+
+ // 31----------------------------------------------------------------------0
+ // XXXXXXXX XXXXXXXX XXXXXXXX 00000111 | 11111110 00000000 00001111 11111111
+ A = createBitVector<TypeParam>(40, {{0, 12}, {25, 35}});
+ EXPECT_EQ(40U, A.size());
+ EXPECT_EQ(22U, A.count());
+
+ // 2a. Make sure that left shifting some 1 bits out of the vector works.
+ // 31----------------------------------------------------------------------0
+ // Before:
+ // XXXXXXXX XXXXXXXX XXXXXXXX 00000111 | 11111110 00000000 00001111 11111111
+ // After:
+ // XXXXXXXX XXXXXXXX XXXXXXXX 11111100 | 00000000 00011111 11111110 00000000
+ A <<= 9;
+ EXPECT_EQ(createBitVector<TypeParam>(40, {{9, 21}, {34, 40}}), A);
+
+ // 2b. Make sure that keeping the number of one bits unchanged works.
+ // 31----------------------------------------------------------------------0
+ // Before:
+ // XXXXXXXX XXXXXXXX XXXXXXXX 11111100 | 00000000 00011111 11111110 00000000
+ // After:
+ // XXXXXXXX XXXXXXXX XXXXXXXX 00000011 | 11110000 00000000 01111111 11111000
+ A >>= 6;
+ EXPECT_EQ(createBitVector<TypeParam>(40, {{3, 15}, {28, 34}}), A);
+
+ // 2c. Make sure that right shifting some 1 bits out of the vector works.
+ // 31----------------------------------------------------------------------0
+ // Before:
+ // XXXXXXXX XXXXXXXX XXXXXXXX 00000011 | 11110000 00000000 01111111 11111000
+ // After:
+ // XXXXXXXX XXXXXXXX XXXXXXXX 00000000 | 00000000 11111100 00000000 00011111
+ A >>= 10;
+ EXPECT_EQ(createBitVector<TypeParam>(40, {{0, 5}, {18, 24}}), A);
+
+ // 3. Big test.
+ A = createBitVector<TypeParam>(300, {{1, 30}, {60, 95}, {200, 275}});
+ A <<= 29;
+ EXPECT_EQ(createBitVector<TypeParam>(
+ 300, {{1 + 29, 30 + 29}, {60 + 29, 95 + 29}, {200 + 29, 300}}),
+ A);
+}
+
+TYPED_TEST(BitVectorTest, ShiftOpsMultiWord) {
+ // Test that shift ops work when the desired shift amount is greater than or
+ // equal to the size of a single word.
+ auto A = createBitVector<TypeParam>(300, {{1, 30}, {60, 95}, {200, 275}});
+
+ // Make a copy so we can re-use it later.
+ auto B = A;
+
+ // 1. Shift left by an exact multiple of the word size. This should invoke
+ // only a memmove and no per-word bit operations.
+ A <<= 64;
+ auto Expected = createBitVector<TypeParam>(
+ 300, {{1 + 64, 30 + 64}, {60 + 64, 95 + 64}, {200 + 64, 300}});
+ EXPECT_EQ(Expected, A);
+
+ // 2. Shift left by a non multiple of the word size. This should invoke both
+ // a memmove and per-word bit operations.
+ A = B;
+ A <<= 93;
+ EXPECT_EQ(createBitVector<TypeParam>(
+ 300, {{1 + 93, 30 + 93}, {60 + 93, 95 + 93}, {200 + 93, 300}}),
+ A);
+
+ // 1. Shift right by an exact multiple of the word size. This should invoke
+ // only a memmove and no per-word bit operations.
+ A = B;
+ A >>= 64;
+ EXPECT_EQ(
+ createBitVector<TypeParam>(300, {{0, 95 - 64}, {200 - 64, 275 - 64}}), A);
+
+ // 2. Shift left by a non multiple of the word size. This should invoke both
+ // a memmove and per-word bit operations.
+ A = B;
+ A >>= 93;
+ EXPECT_EQ(
+ createBitVector<TypeParam>(300, {{0, 95 - 93}, {200 - 93, 275 - 93}}), A);
+}
+
TYPED_TEST(BitVectorTest, RangeOps) {
TypeParam A;
A.resize(256);