[APInt] Fix isAllOnes and extractBits for zero width values.
authorChris Lattner <clattner@nondot.org>
Wed, 6 Oct 2021 16:53:50 +0000 (09:53 -0700)
committerChris Lattner <clattner@nondot.org>
Wed, 6 Oct 2021 19:37:53 +0000 (12:37 -0700)
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
llvm/lib/Support/APInt.cpp
llvm/unittests/ADT/APIntTest.cpp

index 7fef9c9..2b25806 100644 (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;
   }
 
index 298dcf6..15b099a 100644 (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");
 
index 59a8f4c..83bbc5e 100644 (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);