Index: include/llvm/ADT/APInt.h =================================================================== --- include/llvm/ADT/APInt.h +++ include/llvm/ADT/APInt.h @@ -223,6 +223,12 @@ /// out-of-line slow case for countPopulation unsigned countPopulationSlowCase() const; + /// out-of-line slow case for setLowBits. + void setLowBitsSlowCase(unsigned loBits); + + /// out-of-line slow case for setHighBits. + void setHighBitsSlowCase(unsigned hiBits); + public: /// \name Constructors /// @{ @@ -1241,6 +1247,39 @@ /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1. void setBits(unsigned loBit, unsigned hiBit); + /// Set the bottom loBits bits. + void setLowBits(unsigned loBits) { + assert(loBits <= BitWidth && "Too many bits to set!"); + // Handle a degenerate case, to avoid shifting by word size. + if (loBits == 0) + return; + // For small values, return quickly. + if (loBits <= APINT_BITS_PER_WORD) { + uint64_t Mask = UINT64_MAX >> (APINT_BITS_PER_WORD - loBits); + if (isSingleWord()) + VAL |= Mask; + else + pVal[0] |= Mask; + } else { + setLowBitsSlowCase(loBits); + } + } + + /// Set the top hiBits bits. + void setHighBits(unsigned hiBits) { + assert(hiBits <= BitWidth && "Too many bits to set!"); + // Handle a degenerate case, to avoid shifting by word size. + if (hiBits == 0) + return; + // For small values, return quickly. + if (isSingleWord()) { + VAL |= UINT64_MAX << (BitWidth - hiBits); + clearUnusedBits(); + } else { + setHighBitsSlowCase(hiBits); + } + } + /// \brief Set every bit to 0. void clearAllBits() { if (isSingleWord()) Index: lib/Support/APInt.cpp =================================================================== --- lib/Support/APInt.cpp +++ lib/Support/APInt.cpp @@ -599,6 +599,33 @@ } } +void APInt::setLowBitsSlowCase(unsigned loBits) { + unsigned lastWord = whichWord(loBits); + + // Fill all ones up to the last word. + for (unsigned word = 0; word < lastWord; ++word) + pVal[word] = UINT64_MAX; + + // Last word needs special handling. + unsigned wordBits = whichBit(loBits); + if (wordBits == 0) + return; + pVal[lastWord] |= UINT64_MAX >> (APINT_BITS_PER_WORD - wordBits); +} + +void APInt::setHighBitsSlowCase(unsigned hiBits) { + unsigned lastWord = whichWord(BitWidth - hiBits); + + // Fill all ones down to the last word. + for (unsigned word = getNumWords() - 1; word > lastWord; --word) + pVal[word] = UINT64_MAX; + + // Last word needs special handling. + unsigned wordBits = whichBit(BitWidth - hiBits); + pVal[lastWord] |= UINT64_MAX << wordBits; + clearUnusedBits(); +} + /// Set the given bit to 0 whose position is given as "bitPosition". /// @brief Set a given bit to 0. void APInt::clearBit(unsigned bitPosition) { Index: unittests/ADT/APIntTest.cpp =================================================================== --- unittests/ADT/APIntTest.cpp +++ unittests/ADT/APIntTest.cpp @@ -1541,3 +1541,125 @@ EXPECT_EQ(0u, i64hi32.countTrailingOnes()); EXPECT_EQ(32u, i64hi32.countPopulation()); } + +TEST(APIntTest, setLowBits) { + APInt i64lo32(64, 0); + i64lo32.setLowBits(32); + EXPECT_EQ(0u, i64lo32.countLeadingOnes()); + EXPECT_EQ(32u, i64lo32.countLeadingZeros()); + EXPECT_EQ(32u, i64lo32.getActiveBits()); + EXPECT_EQ(0u, i64lo32.countTrailingZeros()); + EXPECT_EQ(32u, i64lo32.countTrailingOnes()); + EXPECT_EQ(32u, i64lo32.countPopulation()); + + APInt i128lo64(128, 0); + i128lo64.setLowBits(64); + EXPECT_EQ(0u, i128lo64.countLeadingOnes()); + EXPECT_EQ(64u, i128lo64.countLeadingZeros()); + EXPECT_EQ(64u, i128lo64.getActiveBits()); + EXPECT_EQ(0u, i128lo64.countTrailingZeros()); + EXPECT_EQ(64u, i128lo64.countTrailingOnes()); + EXPECT_EQ(64u, i128lo64.countPopulation()); + + APInt i128lo24(128, 0); + i128lo24.setLowBits(24); + EXPECT_EQ(0u, i128lo24.countLeadingOnes()); + EXPECT_EQ(104u, i128lo24.countLeadingZeros()); + EXPECT_EQ(24u, i128lo24.getActiveBits()); + EXPECT_EQ(0u, i128lo24.countTrailingZeros()); + EXPECT_EQ(24u, i128lo24.countTrailingOnes()); + EXPECT_EQ(24u, i128lo24.countPopulation()); + + APInt i128lo104(128, 0); + i128lo104.setLowBits(104); + EXPECT_EQ(0u, i128lo104.countLeadingOnes()); + EXPECT_EQ(24u, i128lo104.countLeadingZeros()); + EXPECT_EQ(104u, i128lo104.getActiveBits()); + EXPECT_EQ(0u, i128lo104.countTrailingZeros()); + EXPECT_EQ(104u, i128lo104.countTrailingOnes()); + EXPECT_EQ(104u, i128lo104.countPopulation()); + + APInt i128lo0(128, 0); + i128lo0.setLowBits(0); + EXPECT_EQ(0u, i128lo0.countLeadingOnes()); + EXPECT_EQ(128u, i128lo0.countLeadingZeros()); + EXPECT_EQ(0u, i128lo0.getActiveBits()); + EXPECT_EQ(128u, i128lo0.countTrailingZeros()); + EXPECT_EQ(0u, i128lo0.countTrailingOnes()); + EXPECT_EQ(0u, i128lo0.countPopulation()); + + APInt i80lo79(80, 0); + i80lo79.setLowBits(79); + EXPECT_EQ(0u, i80lo79.countLeadingOnes()); + EXPECT_EQ(1u, i80lo79.countLeadingZeros()); + EXPECT_EQ(79u, i80lo79.getActiveBits()); + EXPECT_EQ(0u, i80lo79.countTrailingZeros()); + EXPECT_EQ(79u, i80lo79.countTrailingOnes()); + EXPECT_EQ(79u, i80lo79.countPopulation()); +} + +TEST(APIntTest, setHighBits) { + APInt i64hi32(64, 0); + i64hi32.setHighBits(32); + EXPECT_EQ(32u, i64hi32.countLeadingOnes()); + EXPECT_EQ(0u, i64hi32.countLeadingZeros()); + EXPECT_EQ(64u, i64hi32.getActiveBits()); + EXPECT_EQ(32u, i64hi32.countTrailingZeros()); + EXPECT_EQ(0u, i64hi32.countTrailingOnes()); + EXPECT_EQ(32u, i64hi32.countPopulation()); + + APInt i128hi64(128, 0); + i128hi64.setHighBits(64); + EXPECT_EQ(64u, i128hi64.countLeadingOnes()); + EXPECT_EQ(0u, i128hi64.countLeadingZeros()); + EXPECT_EQ(128u, i128hi64.getActiveBits()); + EXPECT_EQ(64u, i128hi64.countTrailingZeros()); + EXPECT_EQ(0u, i128hi64.countTrailingOnes()); + EXPECT_EQ(64u, i128hi64.countPopulation()); + + APInt i128hi24(128, 0); + i128hi24.setHighBits(24); + EXPECT_EQ(24u, i128hi24.countLeadingOnes()); + EXPECT_EQ(0u, i128hi24.countLeadingZeros()); + EXPECT_EQ(128u, i128hi24.getActiveBits()); + EXPECT_EQ(104u, i128hi24.countTrailingZeros()); + EXPECT_EQ(0u, i128hi24.countTrailingOnes()); + EXPECT_EQ(24u, i128hi24.countPopulation()); + + APInt i128hi104(128, 0); + i128hi104.setHighBits(104); + EXPECT_EQ(104u, i128hi104.countLeadingOnes()); + EXPECT_EQ(0u, i128hi104.countLeadingZeros()); + EXPECT_EQ(128u, i128hi104.getActiveBits()); + EXPECT_EQ(24u, i128hi104.countTrailingZeros()); + EXPECT_EQ(0u, i128hi104.countTrailingOnes()); + EXPECT_EQ(104u, i128hi104.countPopulation()); + + APInt i128hi0(128, 0); + i128hi0.setHighBits(0); + EXPECT_EQ(0u, i128hi0.countLeadingOnes()); + EXPECT_EQ(128u, i128hi0.countLeadingZeros()); + EXPECT_EQ(0u, i128hi0.getActiveBits()); + EXPECT_EQ(128u, i128hi0.countTrailingZeros()); + EXPECT_EQ(0u, i128hi0.countTrailingOnes()); + EXPECT_EQ(0u, i128hi0.countPopulation()); + + APInt i80hi1(80, 0); + i80hi1.setHighBits(1); + EXPECT_EQ(1u, i80hi1.countLeadingOnes()); + EXPECT_EQ(0u, i80hi1.countLeadingZeros()); + EXPECT_EQ(80u, i80hi1.getActiveBits()); + EXPECT_EQ(79u, i80hi1.countTrailingZeros()); + EXPECT_EQ(0u, i80hi1.countTrailingOnes()); + EXPECT_EQ(1u, i80hi1.countPopulation()); + + APInt i32hi16(32, 0); + i32hi16.setHighBits(16); + EXPECT_EQ(16u, i32hi16.countLeadingOnes()); + EXPECT_EQ(0u, i32hi16.countLeadingZeros()); + EXPECT_EQ(32u, i32hi16.getActiveBits()); + EXPECT_EQ(16u, i32hi16.countTrailingZeros()); + EXPECT_EQ(0u, i32hi16.countTrailingOnes()); + EXPECT_EQ(16u, i32hi16.countPopulation()); + +}