[llvm] r297112 - [APInt] Implement getLowBitsSet/getHighBitsSet/getBitsSet using setLowBits/setHighBits/setBits

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 6 18:19:46 PST 2017


Author: ctopper
Date: Mon Mar  6 20:19:45 2017
New Revision: 297112

URL: http://llvm.org/viewvc/llvm-project?rev=297112&view=rev
Log:
[APInt] Implement getLowBitsSet/getHighBitsSet/getBitsSet using setLowBits/setHighBits/setBits

This patch implements getLowBitsSet/getHighBitsSet/getBitsSet in terms of the new setLowBits/setHighBits/setBits methods by making an all 0s APInt and then calling the appropriate set method.

This also adds support to setBits to allow loBits/hiBits to be in the other order to match with getBitsSet behavior.

Differential Revision: https://reviews.llvm.org/D30563

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

Modified: llvm/trunk/include/llvm/ADT/APInt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=297112&r1=297111&r2=297112&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APInt.h (original)
+++ llvm/trunk/include/llvm/ADT/APInt.h Mon Mar  6 20:19:45 2017
@@ -505,12 +505,9 @@ public:
   ///
   /// \returns An APInt value with the requested bits set.
   static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {
-    assert(hiBit <= numBits && "hiBit out of range");
-    assert(loBit < numBits && "loBit out of range");
-    if (hiBit < loBit)
-      return getLowBitsSet(numBits, hiBit) |
-             getHighBitsSet(numBits, numBits - loBit);
-    return getLowBitsSet(numBits, hiBit - loBit).shl(loBit);
+    APInt Res(numBits, 0);
+    Res.setBits(loBit, hiBit);
+    return Res;
   }
 
   /// \brief Get a value with high bits set
@@ -520,15 +517,9 @@ public:
   /// \param numBits the bitwidth of the result
   /// \param hiBitsSet the number of high-order bits set in the result.
   static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
-    assert(hiBitsSet <= numBits && "Too many bits to set!");
-    // Handle a degenerate case, to avoid shifting by word size
-    if (hiBitsSet == 0)
-      return APInt(numBits, 0);
-    unsigned shiftAmt = numBits - hiBitsSet;
-    // For small values, return quickly
-    if (numBits <= APINT_BITS_PER_WORD)
-      return APInt(numBits, UINT64_MAX << shiftAmt);
-    return getAllOnesValue(numBits).shl(shiftAmt);
+    APInt Res(numBits, 0);
+    Res.setHighBits(hiBitsSet);
+    return Res;
   }
 
   /// \brief Get a value with low bits set
@@ -538,14 +529,9 @@ public:
   /// \param numBits the bitwidth of the result
   /// \param loBitsSet the number of low-order bits set in the result.
   static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
-    assert(loBitsSet <= numBits && "Too many bits to set!");
-    // Handle a degenerate case, to avoid shifting by word size
-    if (loBitsSet == 0)
-      return APInt(numBits, 0);
-    // For small values, return quickly.
-    if (loBitsSet <= APINT_BITS_PER_WORD)
-      return APInt(numBits, UINT64_MAX >> (APINT_BITS_PER_WORD - loBitsSet));
-    return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
+    APInt Res(numBits, 0);
+    Res.setLowBits(loBitsSet);
+    return Res;
   }
 
   /// \brief Return a value containing V broadcasted over NewLen bits.
@@ -1216,9 +1202,14 @@ public:
   /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
   void setBits(unsigned loBit, unsigned hiBit) {
     assert(hiBit <= BitWidth && "hiBit out of range");
-    assert(loBit <= hiBit && "loBit out of range");
+    assert(loBit <= BitWidth && "loBit out of range");
     if (loBit == hiBit)
       return;
+    if (loBit > hiBit) {
+      setLowBits(hiBit);
+      setHighBits(BitWidth - loBit);
+      return;
+    }
     if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) {
       uint64_t mask = UINT64_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
       mask <<= loBit;

Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=297112&r1=297111&r2=297112&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Mon Mar  6 20:19:45 2017
@@ -1557,6 +1557,24 @@ TEST(APIntTest, getLowBitsSet) {
 }
 
 TEST(APIntTest, getHighBitsSet) {
+  APInt i64hi1lo1 = APInt::getBitsSet(64, 63, 1);
+  EXPECT_EQ(1u, i64hi1lo1.countLeadingOnes());
+  EXPECT_EQ(0u, i64hi1lo1.countLeadingZeros());
+  EXPECT_EQ(64u, i64hi1lo1.getActiveBits());
+  EXPECT_EQ(0u, i64hi1lo1.countTrailingZeros());
+  EXPECT_EQ(1u, i64hi1lo1.countTrailingOnes());
+  EXPECT_EQ(2u, i64hi1lo1.countPopulation());
+
+  APInt i127hi1lo1 = APInt::getBitsSet(127, 126, 1);
+  EXPECT_EQ(1u, i127hi1lo1.countLeadingOnes());
+  EXPECT_EQ(0u, i127hi1lo1.countLeadingZeros());
+  EXPECT_EQ(127u, i127hi1lo1.getActiveBits());
+  EXPECT_EQ(0u, i127hi1lo1.countTrailingZeros());
+  EXPECT_EQ(1u, i127hi1lo1.countTrailingOnes());
+  EXPECT_EQ(2u, i127hi1lo1.countPopulation());
+}
+
+TEST(APIntTest, getBitsSet) {
   APInt i64hi32 = APInt::getHighBitsSet(64, 32);
   EXPECT_EQ(32u, i64hi32.countLeadingOnes());
   EXPECT_EQ(0u, i64hi32.countLeadingZeros());




More information about the llvm-commits mailing list