[llvm] ad37a45 - [APInt] Fix isAllOnes and extractBits for zero width values.

Chris Lattner via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 6 12:37:59 PDT 2021


Author: Chris Lattner
Date: 2021-10-06T12:37:53-07:00
New Revision: ad37a45a2e137fe05591f3fe7d23b5b921e7ff1d

URL: https://github.com/llvm/llvm-project/commit/ad37a45a2e137fe05591f3fe7d23b5b921e7ff1d
DIFF: https://github.com/llvm/llvm-project/commit/ad37a45a2e137fe05591f3fe7d23b5b921e7ff1d.diff

LOG: [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

Added: 
    

Modified: 
    llvm/include/llvm/ADT/APInt.h
    llvm/lib/Support/APInt.cpp
    llvm/unittests/ADT/APIntTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 7fef9c9b58b4..2b25806a2c61 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -343,14 +343,12 @@ class LLVM_NODISCARD APInt {
   /// \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 298dcf6cad7e..15b099a12667 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 59a8f4cd0f8f..83bbc5e8e46e 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);


        


More information about the llvm-commits mailing list