/// 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
/// @{
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
// 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
//
// 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;
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) &&
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);
// 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;
}
APInt SplatVal;
if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) ||
- !APIntOps::isMask(SplatVal))
+ !SplatVal.isMask())
return SDValue();
if (!SupportedVectorShiftWithImm(VT0.getSimpleVT(), Subtarget, ISD::SRL))
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();
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.
}
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());
}
}
}