diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -343,14 +343,12 @@ /// \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 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -444,7 +444,6 @@ } 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 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -2948,6 +2948,7 @@ // 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 @@ 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);