[llvm] r297114 - [APInt] Add getBitsSetFrom and setBitsFrom to set upper bits starting at a bit

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


Author: ctopper
Date: Mon Mar  6 20:58:36 2017
New Revision: 297114

URL: http://llvm.org/viewvc/llvm-project?rev=297114&view=rev
Log:
[APInt] Add getBitsSetFrom and setBitsFrom to set upper bits starting at a bit

We currently have methods to set a specified number of low bits, a specified number of high bits, or a range of bits. But looking at some existing code it seems sometimes we want to set the high bits starting from a certain bit. Currently we do this with something like getHighBits(BitWidth, BitWidth - StartBit). Or once we start switching to setHighBits, setHighBits(BitWidth - StartBit) or setHighBits(getBitWidth() - StartBit).

Particularly for the latter case it would be better to have a convenience method like setBitsFrom(StartBit) so we don't need to mention the bit width that's already known to the APInt object.

I considered just making setBits have a default value of UINT_MAX for the hiBit argument and we would internally MIN it with the bit width. So if it wasn't specified it would be treated as bit width. This would require removing the assertion we currently have on the value of hiBit and may not be as readable.

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

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=297114&r1=297113&r2=297114&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APInt.h (original)
+++ llvm/trunk/include/llvm/ADT/APInt.h Mon Mar  6 20:58:36 2017
@@ -510,6 +510,23 @@ public:
     return Res;
   }
 
+  /// \brief Get a value with upper bits starting at loBit set.
+  ///
+  /// Constructs an APInt value that has a contiguous range of bits set. The
+  /// bits from loBit (inclusive) to numBits (exclusive) will be set. All other
+  /// bits will be zero. For example, with parameters(32, 12) you would get
+  /// 0xFFFFF000.
+  ///
+  /// \param numBits the intended bit width of the result
+  /// \param loBit the index of the lowest bit to set.
+  ///
+  /// \returns An APInt value with the requested bits set.
+  static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {
+    APInt Res(numBits, 0);
+    Res.setBitsFrom(loBit);
+    return Res;
+  }
+
   /// \brief Get a value with high bits set
   ///
   /// Constructs an APInt value that has the top hiBitsSet bits set.
@@ -1222,6 +1239,11 @@ public:
     }
   }
 
+  /// Set the top bits starting from loBit.
+  void setBitsFrom(unsigned loBit) {
+    return setBits(loBit, BitWidth);
+  }
+
   /// Set the bottom loBits bits.
   void setLowBits(unsigned loBits) {
     return setBits(0, loBits);

Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=297114&r1=297113&r2=297114&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Mon Mar  6 20:58:36 2017
@@ -1584,6 +1584,16 @@ TEST(APIntTest, getBitsSet) {
   EXPECT_EQ(32u, i64hi32.countPopulation());
 }
 
+TEST(APIntTest, getBitsSetFrom) {
+  APInt i64hi31 = APInt::getBitsSetFrom(64, 33);
+  EXPECT_EQ(31u, i64hi31.countLeadingOnes());
+  EXPECT_EQ(0u, i64hi31.countLeadingZeros());
+  EXPECT_EQ(64u, i64hi31.getActiveBits());
+  EXPECT_EQ(33u, i64hi31.countTrailingZeros());
+  EXPECT_EQ(0u, i64hi31.countTrailingOnes());
+  EXPECT_EQ(31u, i64hi31.countPopulation());
+}
+
 TEST(APIntTest, setLowBits) {
   APInt i64lo32(64, 0);
   i64lo32.setLowBits(32);
@@ -1704,3 +1714,14 @@ TEST(APIntTest, setHighBits) {
   EXPECT_EQ(0u, i32hi16.countTrailingOnes());
   EXPECT_EQ(16u, i32hi16.countPopulation());
 }
+
+TEST(APIntTest, setBitsFrom) {
+  APInt i64from63(64, 0);
+  i64from63.setBitsFrom(63);
+  EXPECT_EQ(1u, i64from63.countLeadingOnes());
+  EXPECT_EQ(0u, i64from63.countLeadingZeros());
+  EXPECT_EQ(64u, i64from63.getActiveBits());
+  EXPECT_EQ(63u, i64from63.countTrailingZeros());
+  EXPECT_EQ(0u, i64from63.countTrailingOnes());
+  EXPECT_EQ(1u, i64from63.countPopulation());
+}




More information about the llvm-commits mailing list