Index: include/llvm/ADT/APInt.h =================================================================== --- include/llvm/ADT/APInt.h +++ include/llvm/ADT/APInt.h @@ -1239,6 +1239,12 @@ /// Set the given bit to 1 whose position is given as "bitPosition". void setBit(unsigned bitPosition); + /// \brief Set the bits from loBit (inclusive) to hiBit (exclusive) to 1. + /// + /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1. + /// If hiBit is less than loBit then the set bits "wrap". + void setBits(unsigned loBit, unsigned hiBit); + /// \brief Set every bit to 0. void clearAllBits() { if (isSingleWord()) Index: lib/Support/APInt.cpp =================================================================== --- lib/Support/APInt.cpp +++ lib/Support/APInt.cpp @@ -565,6 +565,23 @@ pVal[whichWord(bitPosition)] |= maskBit(bitPosition); } +void APInt::setBits(unsigned loBit, unsigned hiBit) { + assert(hiBit <= BitWidth && "hiBit out of range"); + assert(loBit < BitWidth && "loBit out of range"); + + if (isSingleWord()) + *this |= APInt::getBitsSet(BitWidth, loBit, hiBit); + else if (hiBit < loBit) { + for (unsigned bit = 0; bit != hiBit; ++bit) + setBit(bit); + for (unsigned bit = loBit; bit != BitWidth; ++bit) + setBit(bit); + } else { + for (unsigned bit = loBit; bit != hiBit; ++bit) + setBit(bit); + } +} + /// 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: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -5218,8 +5218,7 @@ return false; unsigned CstSizeInBits = Cst->getType()->getPrimitiveSizeInBits(); if (isa<UndefValue>(Cst)) { - unsigned HiBits = BitOffset + CstSizeInBits; - Undefs |= APInt::getBitsSet(SizeInBits, BitOffset, HiBits); + Undefs.setBits(BitOffset, BitOffset + CstSizeInBits); return true; } if (auto *CInt = dyn_cast<ConstantInt>(Cst)) { @@ -5240,8 +5239,7 @@ const SDValue &Src = Op.getOperand(i); unsigned BitOffset = i * SrcEltSizeInBits; if (Src.isUndef()) { - unsigned HiBits = BitOffset + SrcEltSizeInBits; - UndefBits |= APInt::getBitsSet(SizeInBits, BitOffset, HiBits); + UndefBits.setBits(BitOffset, BitOffset + SrcEltSizeInBits); continue; } auto *Cst = cast<ConstantSDNode>(Src); @@ -26329,7 +26327,7 @@ break; LLVM_FALLTHROUGH; case X86ISD::SETCC: - KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1); + KnownZero.setBits(1, BitWidth); break; case X86ISD::MOVMSK: { unsigned NumLoBits = Op.getOperand(0).getValueType().getVectorNumElements(); @@ -26350,7 +26348,7 @@ DAG.computeKnownBits(N0, KnownZero, KnownOne, DemandedSrcElts, Depth + 1); KnownOne = KnownOne.zext(BitWidth); KnownZero = KnownZero.zext(BitWidth); - KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - InBitWidth); + KnownZero.setBits(InBitWidth, BitWidth); break; } } Index: lib/Target/X86/X86ShuffleDecodeConstantPool.cpp =================================================================== --- lib/Target/X86/X86ShuffleDecodeConstantPool.cpp +++ lib/Target/X86/X86ShuffleDecodeConstantPool.cpp @@ -60,8 +60,7 @@ unsigned BitOffset = i * CstEltSizeInBits; if (isa<UndefValue>(COp)) { - unsigned HiBits = BitOffset + CstEltSizeInBits; - UndefBits |= APInt::getBitsSet(CstSizeInBits, BitOffset, HiBits); + UndefBits.setBits(BitOffset, BitOffset + CstEltSizeInBits); continue; } Index: unittests/ADT/APIntTest.cpp =================================================================== --- unittests/ADT/APIntTest.cpp +++ unittests/ADT/APIntTest.cpp @@ -63,6 +63,26 @@ EXPECT_EQ(((uint64_t)-2)&((1ull<<33) -1), i33minus2.getZExtValue()); } +TEST(APIntTest, i61_Count) { + APInt i61(61, 1 << 15); + EXPECT_EQ(45u, i61.countLeadingZeros()); + EXPECT_EQ(0u, i61.countLeadingOnes()); + EXPECT_EQ(16u, i61.getActiveBits()); + EXPECT_EQ(15u, i61.countTrailingZeros()); + EXPECT_EQ(1u, i61.countPopulation()); + EXPECT_EQ((1 << 15), i61.getSExtValue()); + EXPECT_EQ((1 << 15), i61.getZExtValue()); + + i61.setBits(8, 19); + EXPECT_EQ(42u, i61.countLeadingZeros()); + EXPECT_EQ(0u, i61.countLeadingOnes()); + EXPECT_EQ(19u, i61.getActiveBits()); + EXPECT_EQ(8u, i61.countTrailingZeros()); + EXPECT_EQ(11u, i61.countPopulation()); + EXPECT_EQ((1 << 19)-(1 << 8), i61.getSExtValue()); + EXPECT_EQ((1 << 19)-(1 << 8), i61.getZExtValue()); +} + TEST(APIntTest, i65_Count) { APInt i65(65, 0, true); EXPECT_EQ(65u, i65.countLeadingZeros()); @@ -118,6 +138,26 @@ EXPECT_EQ(1u, one.countPopulation()); EXPECT_EQ(1, one.getSExtValue()); EXPECT_EQ(1u, one.getZExtValue()); + + APInt s128(128, 2, true); + EXPECT_EQ(126u, s128.countLeadingZeros()); + EXPECT_EQ(0u, s128.countLeadingOnes()); + EXPECT_EQ(2u, s128.getActiveBits()); + EXPECT_EQ(1u, s128.countTrailingZeros()); + EXPECT_EQ(0u, s128.countTrailingOnes()); + EXPECT_EQ(1u, s128.countPopulation()); + EXPECT_EQ(2, s128.getSExtValue()); + EXPECT_EQ(2u, s128.getZExtValue()); + + s128.setBits(63, 1); + EXPECT_EQ(0u, s128.countLeadingZeros()); + EXPECT_EQ(65u, s128.countLeadingOnes()); + EXPECT_EQ(128u, s128.getActiveBits()); + EXPECT_EQ(64u, s128.getMinSignedBits()); + EXPECT_EQ(0u, s128.countTrailingZeros()); + EXPECT_EQ(2u, s128.countTrailingOnes()); + EXPECT_EQ(67u, s128.countPopulation()); + EXPECT_EQ(static_cast<int64_t>((~0ull << 63)|3), s128.getSExtValue()); } TEST(APIntTest, i1) {