Skip to content

Commit

Permalink
[InstCombine][InstSimplify] Use APInt::isNullValue/isOneValue to redu…
Browse files Browse the repository at this point in the history
…ce compiled code for comparing APInts with 0 and 1. NFC

These methods are specifically optimized to only counting leading zeros without an additional uint64_t compare.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304876 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
topperc committed Jun 7, 2017
1 parent e57d4f5 commit eb370b4
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 64 deletions.
2 changes: 1 addition & 1 deletion include/llvm/IR/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
};

struct is_one {
bool isValue(const APInt &C) { return C == 1; }
bool isValue(const APInt &C) { return C.isOneValue(); }
};

/// \brief Match an integer 1 or a vector with all elements equal to 1.
Expand Down
12 changes: 6 additions & 6 deletions lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2391,7 +2391,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
const APInt *C;
switch (BO.getOpcode()) {
case Instruction::Add:
if (match(BO.getOperand(1), m_APInt(C)) && *C != 0) {
if (match(BO.getOperand(1), m_APInt(C)) && !C->isNullValue()) {
// FIXME: If we have both nuw and nsw, we should reduce the range further.
if (BO.hasNoUnsignedWrap()) {
// 'add nuw x, C' produces [C, UINT_MAX].
Expand Down Expand Up @@ -2429,7 +2429,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
Upper = APInt::getSignedMaxValue(Width).ashr(*C) + 1;
} else if (match(BO.getOperand(0), m_APInt(C))) {
unsigned ShiftAmount = Width - 1;
if (*C != 0 && BO.isExact())
if (!C->isNullValue() && BO.isExact())
ShiftAmount = C->countTrailingZeros();
if (C->isNegative()) {
// 'ashr C, x' produces [C, C >> (Width-1)]
Expand All @@ -2450,7 +2450,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
} else if (match(BO.getOperand(0), m_APInt(C))) {
// 'lshr C, x' produces [C >> (Width-1), C].
unsigned ShiftAmount = Width - 1;
if (*C != 0 && BO.isExact())
if (!C->isNullValue() && BO.isExact())
ShiftAmount = C->countTrailingZeros();
Lower = C->lshr(ShiftAmount);
Upper = *C + 1;
Expand Down Expand Up @@ -2512,7 +2512,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
break;

case Instruction::UDiv:
if (match(BO.getOperand(1), m_APInt(C)) && *C != 0) {
if (match(BO.getOperand(1), m_APInt(C)) && !C->isNullValue()) {
// 'udiv x, C' produces [0, UINT_MAX / C].
Upper = APInt::getMaxValue(Width).udiv(*C) + 1;
} else if (match(BO.getOperand(0), m_APInt(C))) {
Expand Down Expand Up @@ -2827,14 +2827,14 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
// - CI2 is one
// - CI isn't zero
if (LBO->hasNoSignedWrap() || LBO->hasNoUnsignedWrap() ||
*CI2Val == 1 || !CI->isZero()) {
CI2Val->isOneValue() || !CI->isZero()) {
if (Pred == ICmpInst::ICMP_EQ)
return ConstantInt::getFalse(RHS->getContext());
if (Pred == ICmpInst::ICMP_NE)
return ConstantInt::getTrue(RHS->getContext());
}
}
if (CIVal->isSignMask() && *CI2Val == 1) {
if (CIVal->isSignMask() && CI2Val->isOneValue()) {
if (Pred == ICmpInst::ICMP_UGT)
return ConstantInt::getFalse(RHS->getContext());
if (Pred == ICmpInst::ICMP_ULE)
Expand Down
7 changes: 4 additions & 3 deletions lib/Transforms/InstCombine/InstCombineAddSub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -991,8 +991,9 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add,
// Shifts and add used to flip and mask off the low bit:
// add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1
const APInt *C3;
if (*C == 1 && match(Op0, m_OneUse(m_AShr(m_Shl(m_Value(X), m_APInt(C2)),
m_APInt(C3)))) &&
if (C->isOneValue() &&
match(Op0,
m_OneUse(m_AShr(m_Shl(m_Value(X), m_APInt(C2)), m_APInt(C3)))) &&
C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) {
Value *NotX = Builder.CreateNot(X);
return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1));
Expand Down Expand Up @@ -1554,7 +1555,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {

// -(X >>u 31) -> (X >>s 31)
// -(X >>s 31) -> (X >>u 31)
if (*Op0C == 0) {
if (Op0C->isNullValue()) {
Value *X;
const APInt *ShAmt;
if (match(Op1, m_LShr(m_Value(X), m_APInt(ShAmt))) &&
Expand Down
21 changes: 11 additions & 10 deletions lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,12 @@ Instruction *InstCombiner::OptAndOp(BinaryOperator *Op,
const APInt& AddRHS = OpRHS->getValue();

// Check to see if any bits below the one bit set in AndRHSV are set.
if ((AddRHS & (AndRHSV-1)) == 0) {
if ((AddRHS & (AndRHSV - 1)).isNullValue()) {
// If not, the only thing that can effect the output of the AND is
// the bit specified by AndRHSV. If that bit is set, the effect of
// the XOR is to toggle the bit. If it is clear, then the ADD has
// no effect.
if ((AddRHS & AndRHSV) == 0) { // Bit is not set, noop
if ((AddRHS & AndRHSV).isNullValue()) { // Bit is not set, noop
TheAnd.setOperand(0, X);
return &TheAnd;
} else {
Expand Down Expand Up @@ -641,7 +641,7 @@ static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
// If there is a conflict, we should actually return a false for the
// whole construct.
if (((BCst->getValue() & DCst->getValue()) &
(CCst->getValue() ^ ECst->getValue())) != 0)
(CCst->getValue() ^ ECst->getValue())).getBoolValue())
return ConstantInt::get(LHS->getType(), !IsAnd);

Value *NewOr1 = Builder->CreateOr(B, D);
Expand Down Expand Up @@ -748,7 +748,7 @@ foldAndOrOfEqualityCmpsWithConstants(ICmpInst *LHS, ICmpInst *RHS,

// Special case: get the ordering right when the values wrap around zero.
// Ie, we assumed the constants were unsigned when swapping earlier.
if (*C1 == 0 && C2->isAllOnesValue())
if (C1->isNullValue() && C2->isAllOnesValue())
std::swap(C1, C2);

if (*C1 == *C2 - 1) {
Expand Down Expand Up @@ -840,7 +840,8 @@ Value *InstCombiner::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS) {

// Check that the low bits are zero.
APInt Low = APInt::getLowBitsSet(BigBitSize, SmallBitSize);
if ((Low & AndC->getValue()) == 0 && (Low & BigC->getValue()) == 0) {
if ((Low & AndC->getValue()).isNullValue() &&
(Low & BigC->getValue()).isNullValue()) {
Value *NewAnd = Builder->CreateAnd(V, Low | AndC->getValue());
APInt N = SmallC->getValue().zext(BigBitSize) | BigC->getValue();
Value *NewVal = ConstantInt::get(AndC->getType()->getContext(), N);
Expand Down Expand Up @@ -1286,7 +1287,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
}
case Instruction::Sub:
// -x & 1 -> x & 1
if (AndRHSMask == 1 && match(Op0LHS, m_Zero()))
if (AndRHSMask.isOneValue() && match(Op0LHS, m_Zero()))
return BinaryOperator::CreateAnd(Op0RHS, AndRHS);

break;
Expand All @@ -1295,7 +1296,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
case Instruction::LShr:
// (1 << x) & 1 --> zext(x == 0)
// (1 >> x) & 1 --> zext(x == 0)
if (AndRHSMask == 1 && Op0LHS == AndRHS) {
if (AndRHSMask.isOneValue() && Op0LHS == AndRHS) {
Value *NewICmp =
Builder->CreateICmpEQ(Op0RHS, Constant::getNullValue(I.getType()));
return new ZExtInst(NewICmp, I.getType());
Expand Down Expand Up @@ -2033,7 +2034,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
ConstantInt *C1 = dyn_cast<ConstantInt>(C);
ConstantInt *C2 = dyn_cast<ConstantInt>(D);
if (C1 && C2) { // (A & C1)|(B & C2)
if ((C1->getValue() & C2->getValue()) == 0) {
if ((C1->getValue() & C2->getValue()).isNullValue()) {
// ((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)
// iff (C1&C2) == 0 and (N&~C1) == 0
if (match(A, m_Or(m_Value(V1), m_Value(V2))) &&
Expand All @@ -2056,9 +2057,9 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
// iff (C1&C2) == 0 and (C3&~C1) == 0 and (C4&~C2) == 0.
ConstantInt *C3 = nullptr, *C4 = nullptr;
if (match(A, m_Or(m_Value(V1), m_ConstantInt(C3))) &&
(C3->getValue() & ~C1->getValue()) == 0 &&
(C3->getValue() & ~C1->getValue()).isNullValue() &&
match(B, m_Or(m_Specific(V1), m_ConstantInt(C4))) &&
(C4->getValue() & ~C2->getValue()) == 0) {
(C4->getValue() & ~C2->getValue()).isNullValue()) {
V2 = Builder->CreateOr(V1, ConstantExpr::getOr(C3, C4), "bitfield");
return BinaryOperator::CreateAnd(V2,
Builder->getInt(C1->getValue()|C2->getValue()));
Expand Down
4 changes: 2 additions & 2 deletions lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ static Value *simplifyX86immShift(const IntrinsicInst &II,
unsigned BitWidth = SVT->getPrimitiveSizeInBits();

// If shift-by-zero then just return the original value.
if (Count == 0)
if (Count.isNullValue())
return Vec;

// Handle cases when Shift >= BitWidth.
Expand Down Expand Up @@ -1395,7 +1395,7 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) {
// If the input to cttz/ctlz is known to be non-zero,
// then change the 'ZeroIsUndef' parameter to 'true'
// because we know the zero behavior can't affect the result.
if (Known.One != 0 ||
if (!Known.One.isNullValue() ||
isKnownNonZero(Op0, IC.getDataLayout(), 0, &IC.getAssumptionCache(), &II,
&IC.getDominatorTree())) {
if (!match(II.getArgOperand(1), m_One())) {
Expand Down
8 changes: 4 additions & 4 deletions lib/Transforms/InstCombine/InstCombineCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, ZExtInst &CI,

// zext (x <s 0) to i32 --> x>>u31 true if signbit set.
// zext (x >s -1) to i32 --> (x>>u31)^1 true if signbit clear.
if ((ICI->getPredicate() == ICmpInst::ICMP_SLT && Op1CV == 0) ||
if ((ICI->getPredicate() == ICmpInst::ICMP_SLT && Op1CV.isNullValue()) ||
(ICI->getPredicate() == ICmpInst::ICMP_SGT && Op1CV.isAllOnesValue())) {
if (!DoTransform) return ICI;

Expand All @@ -688,7 +688,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, ZExtInst &CI,
// zext (X != 0) to i32 --> X>>1 iff X has only the 2nd bit set.
// zext (X != 1) to i32 --> X^1 iff X has only the low bit set.
// zext (X != 2) to i32 --> (X>>1)^1 iff X has only the 2nd bit set.
if ((Op1CV == 0 || Op1CV.isPowerOf2()) &&
if ((Op1CV.isNullValue() || Op1CV.isPowerOf2()) &&
// This only works for EQ and NE
ICI->isEquality()) {
// If Op1C some other power of two, convert:
Expand All @@ -699,7 +699,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, ZExtInst &CI,
if (!DoTransform) return ICI;

bool isNE = ICI->getPredicate() == ICmpInst::ICMP_NE;
if (Op1CV != 0 && (Op1CV != KnownZeroMask)) {
if (!Op1CV.isNullValue() && (Op1CV != KnownZeroMask)) {
// (X&4) == 2 --> false
// (X&4) != 2 --> true
Constant *Res = ConstantInt::get(Type::getInt1Ty(CI.getContext()),
Expand All @@ -717,7 +717,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, ZExtInst &CI,
In->getName() + ".lobit");
}

if ((Op1CV != 0) == isNE) { // Toggle the low bit.
if (!Op1CV.isNullValue() == isNE) { // Toggle the low bit.
Constant *One = ConstantInt::get(In->getType(), 1);
In = Builder->CreateXor(In, One);
}
Expand Down
Loading

0 comments on commit eb370b4

Please sign in to comment.