aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorok Edwin <edwintorok@gmail.com>2009-01-27 18:06:03 +0000
committerTorok Edwin <edwintorok@gmail.com>2009-01-27 18:06:03 +0000
commit2d0f1c57c3f95e43a8b18bfe8481d90b665d5efe (patch)
tree72e1a5c7d8ff8f4caa92d81768de94e6e64bacb1
parent101a90f3d3c3ad9159676ba744b59b3a9d0b4af5 (diff)
APInt's countLeadingOnes() was broken for negative i128 values,
causing assertion failures in getSExtValue(). Fix it by making highWordBits actually contain what its name says, and add some more unit-tests for APInt. This fixes PR3419. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63107 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Support/APInt.cpp8
-rw-r--r--unittests/ADT/APInt.cpp79
2 files changed, 84 insertions, 3 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 367c75be1a..3d38a0c606 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -683,7 +683,13 @@ unsigned APInt::countLeadingOnes() const {
return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth);
unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD;
- unsigned shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits);
+ unsigned shift;
+ if (!highWordBits) {
+ highWordBits = APINT_BITS_PER_WORD;
+ shift = 0;
+ } else {
+ shift = APINT_BITS_PER_WORD - highWordBits;
+ }
int i = getNumWords() - 1;
unsigned Count = countLeadingOnes_64(pVal[i], shift);
if (Count == highWordBits) {
diff --git a/unittests/ADT/APInt.cpp b/unittests/ADT/APInt.cpp
index 5bca5b6b40..cbcc1390bc 100644
--- a/unittests/ADT/APInt.cpp
+++ b/unittests/ADT/APInt.cpp
@@ -18,8 +18,83 @@ namespace {
TEST(APIntTest, ShiftLeftByZero) {
APInt One = APInt::getNullValue(65) + 1;
APInt Shl = One.shl(0);
- EXPECT_EQ(Shl[0], true);
- EXPECT_EQ(Shl[1], false);
+ EXPECT_EQ(true, Shl[0]);
+ EXPECT_EQ(false, Shl[1]);
+}
+
+TEST(APIntTest, I128NegativeCount) {
+ APInt Minus3(128, (uint64_t)-3, true);
+ EXPECT_EQ(126u, Minus3.countLeadingOnes());
+ EXPECT_EQ(-3, Minus3.getSExtValue());
+
+ APInt Minus1(128, (uint64_t)-1, true);
+ EXPECT_EQ(0u, Minus1.countLeadingZeros());
+ EXPECT_EQ(128u, Minus1.countLeadingOnes());
+ EXPECT_EQ(128u, Minus1.getActiveBits());
+ EXPECT_EQ(0u, Minus1.countTrailingZeros());
+ EXPECT_EQ(128u, Minus1.countTrailingOnes());
+ EXPECT_EQ(128u, Minus1.countPopulation());
+ EXPECT_EQ(-1, Minus1.getSExtValue());
+}
+
+TEST(APIntTest, I33Count) {
+ APInt i33minus2(33, -2, true);
+ EXPECT_EQ(0u, i33minus2.countLeadingZeros());
+ EXPECT_EQ(32u, i33minus2.countLeadingOnes());
+ EXPECT_EQ(33u, i33minus2.getActiveBits());
+ EXPECT_EQ(1u, i33minus2.countTrailingZeros());
+ EXPECT_EQ(32u, i33minus2.countPopulation());
+ EXPECT_EQ(-2, i33minus2.getSExtValue());
+ EXPECT_EQ(((uint64_t)-2)&((1ull<<33) -1), i33minus2.getZExtValue());
+}
+
+TEST(APIntTest, I65Count) {
+ APInt i65minus(65, 0, true);
+ i65minus.set(64);
+ EXPECT_EQ(0u, i65minus.countLeadingZeros());
+ EXPECT_EQ(1u, i65minus.countLeadingOnes());
+ EXPECT_EQ(65u, i65minus.getActiveBits());
+ EXPECT_EQ(64u, i65minus.countTrailingZeros());
+ EXPECT_EQ(1u, i65minus.countPopulation());
+}
+
+TEST(APIntTest, I128PositiveCount) {
+ APInt u128max = APInt::getAllOnesValue(128);
+ EXPECT_EQ(128u, u128max.countLeadingOnes());
+ EXPECT_EQ(0u, u128max.countLeadingZeros());
+ EXPECT_EQ(128u, u128max.getActiveBits());
+ EXPECT_EQ(0u, u128max.countTrailingZeros());
+ EXPECT_EQ(128u, u128max.countTrailingOnes());
+ EXPECT_EQ(128u, u128max.countPopulation());
+
+ APInt u64max(128, (uint64_t)-1, false);
+ EXPECT_EQ(64u, u64max.countLeadingZeros());
+ EXPECT_EQ(0u, u64max.countLeadingOnes());
+ EXPECT_EQ(64u, u64max.getActiveBits());
+ EXPECT_EQ(0u, u64max.countTrailingZeros());
+ EXPECT_EQ(64u, u64max.countTrailingOnes());
+ EXPECT_EQ(64u, u64max.countPopulation());
+ EXPECT_EQ((uint64_t)~0ull, u64max.getZExtValue());
+
+ APInt zero(128, 0, true);
+ EXPECT_EQ(128u, zero.countLeadingZeros());
+ EXPECT_EQ(0u, zero.countLeadingOnes());
+ EXPECT_EQ(0u, zero.getActiveBits());
+ EXPECT_EQ(128u, zero.countTrailingZeros());
+ EXPECT_EQ(0u, zero.countTrailingOnes());
+ EXPECT_EQ(0u, zero.countPopulation());
+ EXPECT_EQ(0u, zero.getSExtValue());
+ EXPECT_EQ(0u, zero.getZExtValue());
+
+ APInt one(128, 1, true);
+ EXPECT_EQ(127u, one.countLeadingZeros());
+ EXPECT_EQ(0u, one.countLeadingOnes());
+ EXPECT_EQ(1u, one.getActiveBits());
+ EXPECT_EQ(0u, one.countTrailingZeros());
+ EXPECT_EQ(1u, one.countTrailingOnes());
+ EXPECT_EQ(1u, one.countPopulation());
+ EXPECT_EQ(1, one.getSExtValue());
+ EXPECT_EQ(1u, one.getZExtValue());
}
}