[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
This commit is contained in:
Chris Lattner 2021-10-06 09:53:50 -07:00
parent 8c08f21b60
commit ad37a45a2e
3 changed files with 7 additions and 8 deletions

View File

@ -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;
}

View File

@ -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");

View File

@ -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);