From ad37a45a2e137fe05591f3fe7d23b5b921e7ff1d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 6 Oct 2021 09:53:50 -0700 Subject: [PATCH] [APInt] Fix isAllOnes and extractBits for zero width values. isAllOnes() should return true for zero bit values because there are no zeros in it. Thanks to Jay Foad for pointing this out. Differential Revision: https://reviews.llvm.org/D111241 --- llvm/include/llvm/ADT/APInt.h | 12 +++++------- llvm/lib/Support/APInt.cpp | 1 - llvm/unittests/ADT/APIntTest.cpp | 2 ++ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h index 7fef9c9..2b25806 100644 --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -343,14 +343,12 @@ public: /// \returns true if this APInt is non-positive. bool isNonPositive() const { return !isStrictlyPositive(); } - /// Determine if all bits are set. + /// Determine if all bits are set. This is true for zero-width values. bool isAllOnes() const { - if (isSingleWord()) { - // Calculate the shift amount, handling the zero-bit wide case without UB. - unsigned ShiftAmt = - (APINT_BITS_PER_WORD - BitWidth) % APINT_BITS_PER_WORD; - return U.VAL == WORDTYPE_MAX >> ShiftAmt; - } + if (BitWidth == 0) + return true; + if (isSingleWord()) + return U.VAL == WORDTYPE_MAX >> (APINT_BITS_PER_WORD - BitWidth); return countTrailingOnesSlowCase() == BitWidth; } diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 298dcf6..15b099a 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -444,7 +444,6 @@ void APInt::insertBits(uint64_t subBits, unsigned bitPosition, unsigned numBits) } APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const { - assert(numBits > 0 && "Can't extract zero bits"); assert(bitPosition < BitWidth && (numBits + bitPosition) <= BitWidth && "Illegal bit extraction"); diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index 59a8f4c..83bbc5e 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -2948,6 +2948,7 @@ TEST(APIntTest, ZeroWidth) { // Methods like getLowBitsSet work with zero bits. EXPECT_EQ(0U, APInt::getLowBitsSet(0, 0).getBitWidth()); EXPECT_EQ(0U, APInt::getSplat(0, ZW).getBitWidth()); + EXPECT_EQ(0U, APInt(4, 10).extractBits(0, 2).getBitWidth()); // Logical operators. ZW |= ZW2; @@ -2990,6 +2991,7 @@ TEST(APIntTest, ZeroWidth) { EXPECT_EQ(0U, ZW.getLoBits(0).getBitWidth()); EXPECT_EQ(0, ZW.zext(4)); EXPECT_EQ(0U, APInt(4, 3).trunc(0).getBitWidth()); + EXPECT_TRUE(ZW.isAllOnes()); SmallString<42> STR; ZW.toStringUnsigned(STR); -- 2.7.4