diff options
Diffstat (limited to 'unittests/ADT')
-rw-r--r-- | unittests/ADT/APIntTest.cpp | 132 | ||||
-rw-r--r-- | unittests/ADT/BitVectorTest.cpp | 122 |
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); |