Index: include/llvm/ADT/APInt.h =================================================================== --- include/llvm/ADT/APInt.h +++ include/llvm/ADT/APInt.h @@ -505,12 +505,9 @@ /// /// \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 @@ /// \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 @@ /// \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. @@ -1244,10 +1230,15 @@ /// 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 <= APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) { + 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; if (isSingleWord()) Index: unittests/ADT/APIntTest.cpp =================================================================== --- unittests/ADT/APIntTest.cpp +++ unittests/ADT/APIntTest.cpp @@ -1533,6 +1533,24 @@ } 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());