[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