From 2d0f1c57c3f95e43a8b18bfe8481d90b665d5efe Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Tue, 27 Jan 2009 18:06:03 +0000 Subject: [PATCH] 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 --- lib/Support/APInt.cpp | 8 ++++- unittests/ADT/APInt.cpp | 79 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 367c75be1af..3d38a0c6066 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 5bca5b6b406..cbcc1390bca 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()); } } -- 2.34.1