summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ADT/APInt.h50
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp2
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp2
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp4
-rw-r--r--llvm/lib/Target/Hexagon/HexagonGenExtract.cpp4
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp4
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp2
-rw-r--r--llvm/unittests/ADT/APIntTest.cpp29
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());
}
}
}
OpenPOWER on IntegriCloud