diff options
-rw-r--r-- | llvm/include/llvm/ADT/APInt.h | 50 | ||||
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonGenExtract.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 2 | ||||
-rw-r--r-- | llvm/unittests/ADT/APIntTest.cpp | 29 |
8 files changed, 54 insertions, 43 deletions
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h index 0ae321abe8d..045df3c9087 100644 --- a/llvm/include/llvm/ADT/APInt.h +++ b/llvm/include/llvm/ADT/APInt.h @@ -420,6 +420,36 @@ public: /// width without remainder. bool isSplat(unsigned SplatSizeInBits) const; + /// \returns true if this APInt value is a sequence of \param numBits ones + /// starting at the least significant bit with the remainder zero. + bool isMask(unsigned numBits) const { + assert(numBits != 0 && "numBits must be non-zero"); + assert(numBits <= BitWidth && "numBits out of range"); + if (isSingleWord()) + return VAL == (UINT64_MAX >> (APINT_BITS_PER_WORD - numBits)); + unsigned Ones = countTrailingOnes(); + return (numBits == Ones) && ((Ones + countLeadingZeros()) == BitWidth); + } + + /// \returns true if this APInt is a non-empty sequence of ones starting at + /// the least significant bit with the remainder zero. + /// Ex. isMask(0x0000FFFFU) == true. + bool isMask() const { + if (isSingleWord()) + return isMask_64(VAL); + unsigned Ones = countTrailingOnes(); + return (Ones > 0) && ((Ones + countLeadingZeros()) == BitWidth); + } + + /// \brief Return true if this APInt value contains a sequence of ones with + /// the remainder zero. + bool isShiftedMask() const { + if (isSingleWord()) + return isShiftedMask_64(VAL); + unsigned Ones = countPopulation(); + return (Ones + countTrailingZeros() + countLeadingZeros()) == BitWidth; + } + /// @} /// \name Value Generators /// @{ @@ -1907,26 +1937,6 @@ inline const APInt &umax(const APInt &A, const APInt &B) { return A.ugt(B) ? A : B; } -/// \returns true if the argument APInt value is a sequence of ones starting at -/// the least significant bit with the remainder zero. -inline bool isMask(unsigned numBits, const APInt &APIVal) { - return numBits <= APIVal.getBitWidth() && - APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits); -} - -/// \returns true if the argument is a non-empty sequence of ones starting at -/// the least significant bit with the remainder zero (32 bit version). -/// Ex. isMask(0x0000FFFFU) == true. -inline bool isMask(const APInt &Value) { - return (Value != 0) && ((Value + 1) & Value) == 0; -} - -/// \brief Return true if the argument APInt value contains a sequence of ones -/// with the remainder zero. -inline bool isShiftedMask(const APInt &APIVal) { - return (APIVal != 0) && isMask((APIVal - 1) | APIVal); -} - /// \brief Compute GCD of two APInt values. /// /// This function returns the greatest common divisor of the two APInt values diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 986209acfd0..ca32cf3c7c3 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -5321,7 +5321,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { // If C is a low-bits mask, the zero extend is serving to // mask off the high bits. Complement the operand and // re-apply the zext. - if (APIntOps::isMask(Z0TySize, CI->getValue())) + if (CI->getValue().isMask(Z0TySize)) return getZeroExtendExpr(getNotSCEV(Z0), UTy); // If C is a single bit, it may be in the sign-bit position diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 0d1f2c7a380..34b9ff8638f 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -4905,7 +4905,7 @@ bool CodeGenPrepare::optimizeLoadExt(LoadInst *Load) { // // Also avoid hoisting if we didn't see any ands with the exact DemandBits // mask, since these are the only ands that will be removed by isel. - if (ActiveBits <= 1 || !APIntOps::isMask(ActiveBits, DemandBits) || + if (ActiveBits <= 1 || !DemandBits.isMask(ActiveBits) || WidestAndBits != DemandBits) return false; diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index eee7c666536..82c61faaa54 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3337,7 +3337,7 @@ SDValue DAGCombiner::visitANDLike(SDValue N0, SDValue N1, SDNode *N) { unsigned MaskBits = AndMask.countTrailingOnes(); EVT HalfVT = EVT::getIntegerVT(*DAG.getContext(), Size / 2); - if (APIntOps::isMask(AndMask) && + if (AndMask.isMask() && // Required bits must not span the two halves of the integer and // must fit in the half size type. (ShiftBits + MaskBits <= Size / 2) && @@ -3377,7 +3377,7 @@ bool DAGCombiner::isAndLoadExtLoad(ConstantSDNode *AndC, LoadSDNode *LoadN, bool &NarrowLoad) { uint32_t ActiveBits = AndC->getAPIntValue().getActiveBits(); - if (ActiveBits == 0 || !APIntOps::isMask(ActiveBits, AndC->getAPIntValue())) + if (ActiveBits == 0 || !AndC->getAPIntValue().isMask(ActiveBits)) return false; ExtVT = EVT::getIntegerVT(*DAG.getContext(), ActiveBits); diff --git a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp index f6f3a593428..c99ad5130ae 100644 --- a/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp +++ b/llvm/lib/Target/Hexagon/HexagonGenExtract.cpp @@ -197,13 +197,13 @@ bool HexagonGenExtract::convert(Instruction *In) { // It is still ok to generate extract, but only if the mask eliminates // those bits (i.e. M does not have any bits set beyond U). APInt C = APInt::getHighBitsSet(BW, BW-U); - if (M.intersects(C) || !APIntOps::isMask(W, M)) + if (M.intersects(C) || !M.isMask(W)) return false; } else { // Check if M starts with a contiguous sequence of W times 1 bits. Get // the low U bits of M (which eliminates the 0 bits shifted in on the // left), and check if the result is APInt's "mask": - if (!APIntOps::isMask(W, M.getLoBits(U))) + if (!M.getLoBits(U).isMask(W)) return false; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 57d8139acba..b01fcc90823 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -31532,7 +31532,7 @@ static SDValue combineAndMaskToShift(SDNode *N, SelectionDAG &DAG, APInt SplatVal; if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) || - !APIntOps::isMask(SplatVal)) + !SplatVal.isMask()) return SDValue(); if (!SupportedVectorShiftWithImm(VT0.getSimpleVT(), Subtarget, ISD::SRL)) @@ -32127,7 +32127,7 @@ static SDValue detectUSatPattern(SDValue In, EVT VT) { if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C)) { // C should be equal to UINT32_MAX / UINT16_MAX / UINT8_MAX according // the element size of the destination type. - return APIntOps::isMask(VT.getScalarSizeInBits(), C) ? In.getOperand(0) : + return C.isMask(VT.getScalarSizeInBits()) ? In.getOperand(0) : SDValue(); } return SDValue(); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 7182576b695..b126992103e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -1558,7 +1558,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, break; case Intrinsic::amdgcn_buffer_load: case Intrinsic::amdgcn_buffer_load_format: { - if (VWidth == 1 || !APIntOps::isMask(DemandedElts)) + if (VWidth == 1 || !DemandedElts.isMask()) return nullptr; // TODO: Handle 3 vectors when supported in code gen. diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp index bada3404607..9962cc9fa78 100644 --- a/llvm/unittests/ADT/APIntTest.cpp +++ b/llvm/unittests/ADT/APIntTest.cpp @@ -1559,43 +1559,44 @@ TEST(APIntTest, IsSplat) { } TEST(APIntTest, isMask) { - EXPECT_FALSE(APIntOps::isMask(APInt(32, 0x01010101))); - EXPECT_FALSE(APIntOps::isMask(APInt(32, 0xf0000000))); - EXPECT_FALSE(APIntOps::isMask(APInt(32, 0xffff0000))); - EXPECT_FALSE(APIntOps::isMask(APInt(32, 0xff << 1))); + EXPECT_FALSE(APInt(32, 0x01010101).isMask()); + EXPECT_FALSE(APInt(32, 0xf0000000).isMask()); + EXPECT_FALSE(APInt(32, 0xffff0000).isMask()); + EXPECT_FALSE(APInt(32, 0xff << 1).isMask()); for (int N : { 1, 2, 3, 4, 7, 8, 16, 32, 64, 127, 128, 129, 256 }) { - EXPECT_FALSE(APIntOps::isMask(APInt(N, 0))); + EXPECT_FALSE(APInt(N, 0).isMask()); APInt One(N, 1); for (int I = 1; I <= N; ++I) { APInt MaskVal = One.shl(I) - 1; - EXPECT_TRUE(APIntOps::isMask(MaskVal)); + EXPECT_TRUE(MaskVal.isMask()); + EXPECT_TRUE(MaskVal.isMask(I)); } } } TEST(APIntTest, isShiftedMask) { - EXPECT_FALSE(APIntOps::isShiftedMask(APInt(32, 0x01010101))); - EXPECT_TRUE(APIntOps::isShiftedMask(APInt(32, 0xf0000000))); - EXPECT_TRUE(APIntOps::isShiftedMask(APInt(32, 0xffff0000))); - EXPECT_TRUE(APIntOps::isShiftedMask(APInt(32, 0xff << 1))); + EXPECT_FALSE(APInt(32, 0x01010101).isShiftedMask()); + EXPECT_TRUE(APInt(32, 0xf0000000).isShiftedMask()); + EXPECT_TRUE(APInt(32, 0xffff0000).isShiftedMask()); + EXPECT_TRUE(APInt(32, 0xff << 1).isShiftedMask()); for (int N : { 1, 2, 3, 4, 7, 8, 16, 32, 64, 127, 128, 129, 256 }) { - EXPECT_FALSE(APIntOps::isShiftedMask(APInt(N, 0))); + EXPECT_FALSE(APInt(N, 0).isShiftedMask()); APInt One(N, 1); for (int I = 1; I < N; ++I) { APInt MaskVal = One.shl(I) - 1; - EXPECT_TRUE(APIntOps::isShiftedMask(MaskVal)); + EXPECT_TRUE(MaskVal.isShiftedMask()); } for (int I = 1; I < N - 1; ++I) { APInt MaskVal = One.shl(I); - EXPECT_TRUE(APIntOps::isShiftedMask(MaskVal)); + EXPECT_TRUE(MaskVal.isShiftedMask()); } for (int I = 1; I < N; ++I) { APInt MaskVal = APInt::getHighBitsSet(N, I); - EXPECT_TRUE(APIntOps::isShiftedMask(MaskVal)); + EXPECT_TRUE(MaskVal.isShiftedMask()); } } } |