[InstCombine][InstSimplify] Use APInt::isNullValue/isOneValue to reduce 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
This commit is contained in:
Craig Topper 2017-06-07 07:40:37 +00:00
parent e57d4f53f8
commit eb370b4757
10 changed files with 70 additions and 64 deletions

View File

@ -262,7 +262,7 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
}; };
struct is_one { 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. /// \brief Match an integer 1 or a vector with all elements equal to 1.

View File

@ -2391,7 +2391,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
const APInt *C; const APInt *C;
switch (BO.getOpcode()) { switch (BO.getOpcode()) {
case Instruction::Add: 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. // FIXME: If we have both nuw and nsw, we should reduce the range further.
if (BO.hasNoUnsignedWrap()) { if (BO.hasNoUnsignedWrap()) {
// 'add nuw x, C' produces [C, UINT_MAX]. // 'add nuw x, C' produces [C, UINT_MAX].
@ -2429,7 +2429,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
Upper = APInt::getSignedMaxValue(Width).ashr(*C) + 1; Upper = APInt::getSignedMaxValue(Width).ashr(*C) + 1;
} else if (match(BO.getOperand(0), m_APInt(C))) { } else if (match(BO.getOperand(0), m_APInt(C))) {
unsigned ShiftAmount = Width - 1; unsigned ShiftAmount = Width - 1;
if (*C != 0 && BO.isExact()) if (!C->isNullValue() && BO.isExact())
ShiftAmount = C->countTrailingZeros(); ShiftAmount = C->countTrailingZeros();
if (C->isNegative()) { if (C->isNegative()) {
// 'ashr C, x' produces [C, C >> (Width-1)] // 'ashr C, x' produces [C, C >> (Width-1)]
@ -2450,7 +2450,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
} else if (match(BO.getOperand(0), m_APInt(C))) { } else if (match(BO.getOperand(0), m_APInt(C))) {
// 'lshr C, x' produces [C >> (Width-1), C]. // 'lshr C, x' produces [C >> (Width-1), C].
unsigned ShiftAmount = Width - 1; unsigned ShiftAmount = Width - 1;
if (*C != 0 && BO.isExact()) if (!C->isNullValue() && BO.isExact())
ShiftAmount = C->countTrailingZeros(); ShiftAmount = C->countTrailingZeros();
Lower = C->lshr(ShiftAmount); Lower = C->lshr(ShiftAmount);
Upper = *C + 1; Upper = *C + 1;
@ -2512,7 +2512,7 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
break; break;
case Instruction::UDiv: 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]. // 'udiv x, C' produces [0, UINT_MAX / C].
Upper = APInt::getMaxValue(Width).udiv(*C) + 1; Upper = APInt::getMaxValue(Width).udiv(*C) + 1;
} else if (match(BO.getOperand(0), m_APInt(C))) { } else if (match(BO.getOperand(0), m_APInt(C))) {
@ -2827,14 +2827,14 @@ static Value *simplifyICmpWithBinOp(CmpInst::Predicate Pred, Value *LHS,
// - CI2 is one // - CI2 is one
// - CI isn't zero // - CI isn't zero
if (LBO->hasNoSignedWrap() || LBO->hasNoUnsignedWrap() || if (LBO->hasNoSignedWrap() || LBO->hasNoUnsignedWrap() ||
*CI2Val == 1 || !CI->isZero()) { CI2Val->isOneValue() || !CI->isZero()) {
if (Pred == ICmpInst::ICMP_EQ) if (Pred == ICmpInst::ICMP_EQ)
return ConstantInt::getFalse(RHS->getContext()); return ConstantInt::getFalse(RHS->getContext());
if (Pred == ICmpInst::ICMP_NE) if (Pred == ICmpInst::ICMP_NE)
return ConstantInt::getTrue(RHS->getContext()); return ConstantInt::getTrue(RHS->getContext());
} }
} }
if (CIVal->isSignMask() && *CI2Val == 1) { if (CIVal->isSignMask() && CI2Val->isOneValue()) {
if (Pred == ICmpInst::ICMP_UGT) if (Pred == ICmpInst::ICMP_UGT)
return ConstantInt::getFalse(RHS->getContext()); return ConstantInt::getFalse(RHS->getContext());
if (Pred == ICmpInst::ICMP_ULE) if (Pred == ICmpInst::ICMP_ULE)

View File

@ -991,8 +991,9 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add,
// Shifts and add used to flip and mask off the low bit: // Shifts and add used to flip and mask off the low bit:
// add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1 // add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1
const APInt *C3; const APInt *C3;
if (*C == 1 && match(Op0, m_OneUse(m_AShr(m_Shl(m_Value(X), m_APInt(C2)), if (C->isOneValue() &&
m_APInt(C3)))) && match(Op0,
m_OneUse(m_AShr(m_Shl(m_Value(X), m_APInt(C2)), m_APInt(C3)))) &&
C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) { C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) {
Value *NotX = Builder.CreateNot(X); Value *NotX = Builder.CreateNot(X);
return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1)); return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1));
@ -1554,7 +1555,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
// -(X >>u 31) -> (X >>s 31) // -(X >>u 31) -> (X >>s 31)
// -(X >>s 31) -> (X >>u 31) // -(X >>s 31) -> (X >>u 31)
if (*Op0C == 0) { if (Op0C->isNullValue()) {
Value *X; Value *X;
const APInt *ShAmt; const APInt *ShAmt;
if (match(Op1, m_LShr(m_Value(X), m_APInt(ShAmt))) && if (match(Op1, m_LShr(m_Value(X), m_APInt(ShAmt))) &&

View File

@ -172,12 +172,12 @@ Instruction *InstCombiner::OptAndOp(BinaryOperator *Op,
const APInt& AddRHS = OpRHS->getValue(); const APInt& AddRHS = OpRHS->getValue();
// Check to see if any bits below the one bit set in AndRHSV are set. // 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 // 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 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 // the XOR is to toggle the bit. If it is clear, then the ADD has
// no effect. // no effect.
if ((AddRHS & AndRHSV) == 0) { // Bit is not set, noop if ((AddRHS & AndRHSV).isNullValue()) { // Bit is not set, noop
TheAnd.setOperand(0, X); TheAnd.setOperand(0, X);
return &TheAnd; return &TheAnd;
} else { } else {
@ -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 // If there is a conflict, we should actually return a false for the
// whole construct. // whole construct.
if (((BCst->getValue() & DCst->getValue()) & if (((BCst->getValue() & DCst->getValue()) &
(CCst->getValue() ^ ECst->getValue())) != 0) (CCst->getValue() ^ ECst->getValue())).getBoolValue())
return ConstantInt::get(LHS->getType(), !IsAnd); return ConstantInt::get(LHS->getType(), !IsAnd);
Value *NewOr1 = Builder->CreateOr(B, D); Value *NewOr1 = Builder->CreateOr(B, D);
@ -748,7 +748,7 @@ foldAndOrOfEqualityCmpsWithConstants(ICmpInst *LHS, ICmpInst *RHS,
// Special case: get the ordering right when the values wrap around zero. // Special case: get the ordering right when the values wrap around zero.
// Ie, we assumed the constants were unsigned when swapping earlier. // Ie, we assumed the constants were unsigned when swapping earlier.
if (*C1 == 0 && C2->isAllOnesValue()) if (C1->isNullValue() && C2->isAllOnesValue())
std::swap(C1, C2); std::swap(C1, C2);
if (*C1 == *C2 - 1) { if (*C1 == *C2 - 1) {
@ -840,7 +840,8 @@ Value *InstCombiner::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
// Check that the low bits are zero. // Check that the low bits are zero.
APInt Low = APInt::getLowBitsSet(BigBitSize, SmallBitSize); 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()); Value *NewAnd = Builder->CreateAnd(V, Low | AndC->getValue());
APInt N = SmallC->getValue().zext(BigBitSize) | BigC->getValue(); APInt N = SmallC->getValue().zext(BigBitSize) | BigC->getValue();
Value *NewVal = ConstantInt::get(AndC->getType()->getContext(), N); Value *NewVal = ConstantInt::get(AndC->getType()->getContext(), N);
@ -1286,7 +1287,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
} }
case Instruction::Sub: case Instruction::Sub:
// -x & 1 -> x & 1 // -x & 1 -> x & 1
if (AndRHSMask == 1 && match(Op0LHS, m_Zero())) if (AndRHSMask.isOneValue() && match(Op0LHS, m_Zero()))
return BinaryOperator::CreateAnd(Op0RHS, AndRHS); return BinaryOperator::CreateAnd(Op0RHS, AndRHS);
break; break;
@ -1295,7 +1296,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
case Instruction::LShr: case Instruction::LShr:
// (1 << x) & 1 --> zext(x == 0) // (1 << x) & 1 --> zext(x == 0)
// (1 >> x) & 1 --> zext(x == 0) // (1 >> x) & 1 --> zext(x == 0)
if (AndRHSMask == 1 && Op0LHS == AndRHS) { if (AndRHSMask.isOneValue() && Op0LHS == AndRHS) {
Value *NewICmp = Value *NewICmp =
Builder->CreateICmpEQ(Op0RHS, Constant::getNullValue(I.getType())); Builder->CreateICmpEQ(Op0RHS, Constant::getNullValue(I.getType()));
return new ZExtInst(NewICmp, I.getType()); return new ZExtInst(NewICmp, I.getType());
@ -2033,7 +2034,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
ConstantInt *C1 = dyn_cast<ConstantInt>(C); ConstantInt *C1 = dyn_cast<ConstantInt>(C);
ConstantInt *C2 = dyn_cast<ConstantInt>(D); ConstantInt *C2 = dyn_cast<ConstantInt>(D);
if (C1 && C2) { // (A & C1)|(B & C2) 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) // ((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)
// iff (C1&C2) == 0 and (N&~C1) == 0 // iff (C1&C2) == 0 and (N&~C1) == 0
if (match(A, m_Or(m_Value(V1), m_Value(V2))) && if (match(A, m_Or(m_Value(V1), m_Value(V2))) &&
@ -2056,9 +2057,9 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
// iff (C1&C2) == 0 and (C3&~C1) == 0 and (C4&~C2) == 0. // iff (C1&C2) == 0 and (C3&~C1) == 0 and (C4&~C2) == 0.
ConstantInt *C3 = nullptr, *C4 = nullptr; ConstantInt *C3 = nullptr, *C4 = nullptr;
if (match(A, m_Or(m_Value(V1), m_ConstantInt(C3))) && 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))) && 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"); V2 = Builder->CreateOr(V1, ConstantExpr::getOr(C3, C4), "bitfield");
return BinaryOperator::CreateAnd(V2, return BinaryOperator::CreateAnd(V2,
Builder->getInt(C1->getValue()|C2->getValue())); Builder->getInt(C1->getValue()|C2->getValue()));

View File

@ -393,7 +393,7 @@ static Value *simplifyX86immShift(const IntrinsicInst &II,
unsigned BitWidth = SVT->getPrimitiveSizeInBits(); unsigned BitWidth = SVT->getPrimitiveSizeInBits();
// If shift-by-zero then just return the original value. // If shift-by-zero then just return the original value.
if (Count == 0) if (Count.isNullValue())
return Vec; return Vec;
// Handle cases when Shift >= BitWidth. // Handle cases when Shift >= BitWidth.
@ -1395,7 +1395,7 @@ static Instruction *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) {
// If the input to cttz/ctlz is known to be non-zero, // If the input to cttz/ctlz is known to be non-zero,
// then change the 'ZeroIsUndef' parameter to 'true' // then change the 'ZeroIsUndef' parameter to 'true'
// because we know the zero behavior can't affect the result. // 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, isKnownNonZero(Op0, IC.getDataLayout(), 0, &IC.getAssumptionCache(), &II,
&IC.getDominatorTree())) { &IC.getDominatorTree())) {
if (!match(II.getArgOperand(1), m_One())) { if (!match(II.getArgOperand(1), m_One())) {

View File

@ -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 0) to i32 --> x>>u31 true if signbit set.
// zext (x >s -1) to i32 --> (x>>u31)^1 true if signbit clear. // 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())) { (ICI->getPredicate() == ICmpInst::ICMP_SGT && Op1CV.isAllOnesValue())) {
if (!DoTransform) return ICI; if (!DoTransform) return ICI;
@ -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 != 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 != 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. // 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 // This only works for EQ and NE
ICI->isEquality()) { ICI->isEquality()) {
// If Op1C some other power of two, convert: // If Op1C some other power of two, convert:
@ -699,7 +699,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, ZExtInst &CI,
if (!DoTransform) return ICI; if (!DoTransform) return ICI;
bool isNE = ICI->getPredicate() == ICmpInst::ICMP_NE; bool isNE = ICI->getPredicate() == ICmpInst::ICMP_NE;
if (Op1CV != 0 && (Op1CV != KnownZeroMask)) { if (!Op1CV.isNullValue() && (Op1CV != KnownZeroMask)) {
// (X&4) == 2 --> false // (X&4) == 2 --> false
// (X&4) != 2 --> true // (X&4) != 2 --> true
Constant *Res = ConstantInt::get(Type::getInt1Ty(CI.getContext()), Constant *Res = ConstantInt::get(Type::getInt1Ty(CI.getContext()),
@ -717,7 +717,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, ZExtInst &CI,
In->getName() + ".lobit"); 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); Constant *One = ConstantInt::get(In->getType(), 1);
In = Builder->CreateXor(In, One); In = Builder->CreateXor(In, One);
} }

View File

@ -127,7 +127,7 @@ static bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS,
switch (Pred) { switch (Pred) {
case ICmpInst::ICMP_SLT: // True if LHS s< 0 case ICmpInst::ICMP_SLT: // True if LHS s< 0
TrueIfSigned = true; TrueIfSigned = true;
return RHS == 0; return RHS.isNullValue();
case ICmpInst::ICMP_SLE: // True if LHS s<= RHS and RHS == -1 case ICmpInst::ICMP_SLE: // True if LHS s<= RHS and RHS == -1
TrueIfSigned = true; TrueIfSigned = true;
return RHS.isAllOnesValue(); return RHS.isAllOnesValue();
@ -155,10 +155,10 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C) {
if (!ICmpInst::isSigned(Pred)) if (!ICmpInst::isSigned(Pred))
return false; return false;
if (C == 0) if (C.isNullValue())
return ICmpInst::isRelational(Pred); return ICmpInst::isRelational(Pred);
if (C == 1) { if (C.isOneValue()) {
if (Pred == ICmpInst::ICMP_SLT) { if (Pred == ICmpInst::ICMP_SLT) {
Pred = ICmpInst::ICMP_SLE; Pred = ICmpInst::ICMP_SLE;
return true; return true;
@ -1193,7 +1193,7 @@ Instruction *InstCombiner::foldICmpShrConstConst(ICmpInst &I, Value *A,
}; };
// Don't bother doing any work for cases which InstSimplify handles. // Don't bother doing any work for cases which InstSimplify handles.
if (AP2 == 0) if (AP2.isNullValue())
return nullptr; return nullptr;
bool IsAShr = isa<AShrOperator>(I.getOperand(0)); bool IsAShr = isa<AShrOperator>(I.getOperand(0));
@ -1252,7 +1252,7 @@ Instruction *InstCombiner::foldICmpShlConstConst(ICmpInst &I, Value *A,
}; };
// Don't bother doing any work for cases which InstSimplify handles. // Don't bother doing any work for cases which InstSimplify handles.
if (AP2 == 0) if (AP2.isNullValue())
return nullptr; return nullptr;
unsigned AP2TrailingZeros = AP2.countTrailingZeros(); unsigned AP2TrailingZeros = AP2.countTrailingZeros();
@ -1399,7 +1399,7 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &Cmp) {
} }
// (icmp sgt smin(PosA, B) 0) -> (icmp sgt B 0) // (icmp sgt smin(PosA, B) 0) -> (icmp sgt B 0)
if (*C == 0 && Pred == ICmpInst::ICMP_SGT) { if (C->isNullValue() && Pred == ICmpInst::ICMP_SGT) {
SelectPatternResult SPR = matchSelectPattern(X, A, B); SelectPatternResult SPR = matchSelectPattern(X, A, B);
if (SPR.Flavor == SPF_SMIN) { if (SPR.Flavor == SPF_SMIN) {
if (isKnownPositive(A, DL, 0, &AC, &Cmp, &DT)) if (isKnownPositive(A, DL, 0, &AC, &Cmp, &DT))
@ -1465,7 +1465,7 @@ Instruction *InstCombiner::foldICmpTruncConstant(ICmpInst &Cmp,
const APInt *C) { const APInt *C) {
ICmpInst::Predicate Pred = Cmp.getPredicate(); ICmpInst::Predicate Pred = Cmp.getPredicate();
Value *X = Trunc->getOperand(0); Value *X = Trunc->getOperand(0);
if (*C == 1 && C->getBitWidth() > 1) { if (C->isOneValue() && C->getBitWidth() > 1) {
// icmp slt trunc(signum(V)) 1 --> icmp slt V, 1 // icmp slt trunc(signum(V)) 1 --> icmp slt V, 1
Value *V = nullptr; Value *V = nullptr;
if (Pred == ICmpInst::ICMP_SLT && match(X, m_Signum(m_Value(V)))) if (Pred == ICmpInst::ICMP_SLT && match(X, m_Signum(m_Value(V))))
@ -1505,7 +1505,7 @@ Instruction *InstCombiner::foldICmpXorConstant(ICmpInst &Cmp,
// If this is a comparison that tests the signbit (X < 0) or (x > -1), // If this is a comparison that tests the signbit (X < 0) or (x > -1),
// fold the xor. // fold the xor.
ICmpInst::Predicate Pred = Cmp.getPredicate(); ICmpInst::Predicate Pred = Cmp.getPredicate();
if ((Pred == ICmpInst::ICMP_SLT && *C == 0) || if ((Pred == ICmpInst::ICMP_SLT && C->isNullValue()) ||
(Pred == ICmpInst::ICMP_SGT && C->isAllOnesValue())) { (Pred == ICmpInst::ICMP_SGT && C->isAllOnesValue())) {
// If the sign bit of the XorCst is not set, there is no change to // If the sign bit of the XorCst is not set, there is no change to
@ -1623,7 +1623,7 @@ Instruction *InstCombiner::foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And,
// Turn ((X >> Y) & C2) == 0 into (X & (C2 << Y)) == 0. The latter is // Turn ((X >> Y) & C2) == 0 into (X & (C2 << Y)) == 0. The latter is
// preferable because it allows the C2 << Y expression to be hoisted out of a // preferable because it allows the C2 << Y expression to be hoisted out of a
// loop if Y is invariant and X is not. // loop if Y is invariant and X is not.
if (Shift->hasOneUse() && *C1 == 0 && Cmp.isEquality() && if (Shift->hasOneUse() && C1->isNullValue() && Cmp.isEquality() &&
!Shift->isArithmeticShift() && !isa<Constant>(Shift->getOperand(0))) { !Shift->isArithmeticShift() && !isa<Constant>(Shift->getOperand(0))) {
// Compute C2 << Y. // Compute C2 << Y.
Value *NewShift = Value *NewShift =
@ -1681,7 +1681,8 @@ Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
// (icmp pred (and A, (or (shl 1, B), 1), 0)) // (icmp pred (and A, (or (shl 1, B), 1), 0))
// //
// iff pred isn't signed // iff pred isn't signed
if (!Cmp.isSigned() && *C1 == 0 && match(And->getOperand(1), m_One())) { if (!Cmp.isSigned() && C1->isNullValue() &&
match(And->getOperand(1), m_One())) {
Constant *One = cast<Constant>(And->getOperand(1)); Constant *One = cast<Constant>(And->getOperand(1));
Value *Or = And->getOperand(0); Value *Or = And->getOperand(0);
Value *A, *B, *LShr; Value *A, *B, *LShr;
@ -1764,7 +1765,7 @@ Instruction *InstCombiner::foldICmpAndConstant(ICmpInst &Cmp,
// (X & C2) != 0 -> (trunc X) < 0 // (X & C2) != 0 -> (trunc X) < 0
// iff C2 is a power of 2 and it masks the sign bit of a legal integer type. // iff C2 is a power of 2 and it masks the sign bit of a legal integer type.
const APInt *C2; const APInt *C2;
if (And->hasOneUse() && *C == 0 && match(Y, m_APInt(C2))) { if (And->hasOneUse() && C->isNullValue() && match(Y, m_APInt(C2))) {
int32_t ExactLogBase2 = C2->exactLogBase2(); int32_t ExactLogBase2 = C2->exactLogBase2();
if (ExactLogBase2 != -1 && DL.isLegalInteger(ExactLogBase2 + 1)) { if (ExactLogBase2 != -1 && DL.isLegalInteger(ExactLogBase2 + 1)) {
Type *NTy = IntegerType::get(Cmp.getContext(), ExactLogBase2 + 1); Type *NTy = IntegerType::get(Cmp.getContext(), ExactLogBase2 + 1);
@ -1784,7 +1785,7 @@ Instruction *InstCombiner::foldICmpAndConstant(ICmpInst &Cmp,
Instruction *InstCombiner::foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or, Instruction *InstCombiner::foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or,
const APInt *C) { const APInt *C) {
ICmpInst::Predicate Pred = Cmp.getPredicate(); ICmpInst::Predicate Pred = Cmp.getPredicate();
if (*C == 1) { if (C->isOneValue()) {
// icmp slt signum(V) 1 --> icmp slt V, 1 // icmp slt signum(V) 1 --> icmp slt V, 1
Value *V = nullptr; Value *V = nullptr;
if (Pred == ICmpInst::ICMP_SLT && match(Or, m_Signum(m_Value(V)))) if (Pred == ICmpInst::ICMP_SLT && match(Or, m_Signum(m_Value(V))))
@ -1801,7 +1802,7 @@ Instruction *InstCombiner::foldICmpOrConstant(ICmpInst &Cmp, BinaryOperator *Or,
return new ICmpInst(Pred, Or->getOperand(0), Or->getOperand(1)); return new ICmpInst(Pred, Or->getOperand(0), Or->getOperand(1));
} }
if (!Cmp.isEquality() || *C != 0 || !Or->hasOneUse()) if (!Cmp.isEquality() || !C->isNullValue() || !Or->hasOneUse())
return nullptr; return nullptr;
Value *P, *Q; Value *P, *Q;
@ -2036,7 +2037,8 @@ Instruction *InstCombiner::foldICmpShrConstant(ICmpInst &Cmp,
// icmp eq/ne (shr X, Y), 0 --> icmp eq/ne X, 0 // icmp eq/ne (shr X, Y), 0 --> icmp eq/ne X, 0
Value *X = Shr->getOperand(0); Value *X = Shr->getOperand(0);
CmpInst::Predicate Pred = Cmp.getPredicate(); CmpInst::Predicate Pred = Cmp.getPredicate();
if (Cmp.isEquality() && Shr->isExact() && Shr->hasOneUse() && *C == 0) if (Cmp.isEquality() && Shr->isExact() && Shr->hasOneUse() &&
C->isNullValue())
return new ICmpInst(Pred, X, Cmp.getOperand(1)); return new ICmpInst(Pred, X, Cmp.getOperand(1));
const APInt *ShiftVal; const APInt *ShiftVal;
@ -2178,7 +2180,8 @@ Instruction *InstCombiner::foldICmpDivConstant(ICmpInst &Cmp,
// INT_MIN will also fail if the divisor is 1. Although folds of all these // INT_MIN will also fail if the divisor is 1. Although folds of all these
// division-by-constant cases should be present, we can not assert that they // division-by-constant cases should be present, we can not assert that they
// have happened before we reach this icmp instruction. // have happened before we reach this icmp instruction.
if (*C2 == 0 || *C2 == 1 || (DivIsSigned && C2->isAllOnesValue())) if (C2->isNullValue() || C2->isOneValue() ||
(DivIsSigned && C2->isAllOnesValue()))
return nullptr; return nullptr;
// TODO: We could do all of the computations below using APInt. // TODO: We could do all of the computations below using APInt.
@ -2224,7 +2227,7 @@ Instruction *InstCombiner::foldICmpDivConstant(ICmpInst &Cmp,
HiOverflow = addWithOverflow(HiBound, LoBound, RangeSize, false); HiOverflow = addWithOverflow(HiBound, LoBound, RangeSize, false);
} }
} else if (C2->isStrictlyPositive()) { // Divisor is > 0. } else if (C2->isStrictlyPositive()) { // Divisor is > 0.
if (*C == 0) { // (X / pos) op 0 if (C->isNullValue()) { // (X / pos) op 0
// Can't overflow. e.g. X/2 op 0 --> [-1, 2) // Can't overflow. e.g. X/2 op 0 --> [-1, 2)
LoBound = ConstantExpr::getNeg(SubOne(RangeSize)); LoBound = ConstantExpr::getNeg(SubOne(RangeSize));
HiBound = RangeSize; HiBound = RangeSize;
@ -2245,7 +2248,7 @@ Instruction *InstCombiner::foldICmpDivConstant(ICmpInst &Cmp,
} else if (C2->isNegative()) { // Divisor is < 0. } else if (C2->isNegative()) { // Divisor is < 0.
if (Div->isExact()) if (Div->isExact())
RangeSize = ConstantExpr::getNeg(RangeSize); RangeSize = ConstantExpr::getNeg(RangeSize);
if (*C == 0) { // (X / neg) op 0 if (C->isNullValue()) { // (X / neg) op 0
// e.g. X/-5 op 0 --> [-4, 5) // e.g. X/-5 op 0 --> [-4, 5)
LoBound = AddOne(RangeSize); LoBound = AddOne(RangeSize);
HiBound = ConstantExpr::getNeg(RangeSize); HiBound = ConstantExpr::getNeg(RangeSize);
@ -2337,15 +2340,15 @@ Instruction *InstCombiner::foldICmpSubConstant(ICmpInst &Cmp,
return new ICmpInst(ICmpInst::ICMP_SGE, X, Y); return new ICmpInst(ICmpInst::ICMP_SGE, X, Y);
// (icmp sgt (sub nsw X, Y), 0) -> (icmp sgt X, Y) // (icmp sgt (sub nsw X, Y), 0) -> (icmp sgt X, Y)
if (Pred == ICmpInst::ICMP_SGT && *C == 0) if (Pred == ICmpInst::ICMP_SGT && C->isNullValue())
return new ICmpInst(ICmpInst::ICMP_SGT, X, Y); return new ICmpInst(ICmpInst::ICMP_SGT, X, Y);
// (icmp slt (sub nsw X, Y), 0) -> (icmp slt X, Y) // (icmp slt (sub nsw X, Y), 0) -> (icmp slt X, Y)
if (Pred == ICmpInst::ICMP_SLT && *C == 0) if (Pred == ICmpInst::ICMP_SLT && C->isNullValue())
return new ICmpInst(ICmpInst::ICMP_SLT, X, Y); return new ICmpInst(ICmpInst::ICMP_SLT, X, Y);
// (icmp slt (sub nsw X, Y), 1) -> (icmp sle X, Y) // (icmp slt (sub nsw X, Y), 1) -> (icmp sle X, Y)
if (Pred == ICmpInst::ICMP_SLT && *C == 1) if (Pred == ICmpInst::ICMP_SLT && C->isOneValue())
return new ICmpInst(ICmpInst::ICMP_SLE, X, Y); return new ICmpInst(ICmpInst::ICMP_SLE, X, Y);
} }
@ -2520,7 +2523,7 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
switch (BO->getOpcode()) { switch (BO->getOpcode()) {
case Instruction::SRem: case Instruction::SRem:
// If we have a signed (X % (2^c)) == 0, turn it into an unsigned one. // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one.
if (*C == 0 && BO->hasOneUse()) { if (C->isNullValue() && BO->hasOneUse()) {
const APInt *BOC; const APInt *BOC;
if (match(BOp1, m_APInt(BOC)) && BOC->sgt(1) && BOC->isPowerOf2()) { if (match(BOp1, m_APInt(BOC)) && BOC->sgt(1) && BOC->isPowerOf2()) {
Value *NewRem = Builder->CreateURem(BOp0, BOp1, BO->getName()); Value *NewRem = Builder->CreateURem(BOp0, BOp1, BO->getName());
@ -2537,7 +2540,7 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
Constant *SubC = ConstantExpr::getSub(RHS, cast<Constant>(BOp1)); Constant *SubC = ConstantExpr::getSub(RHS, cast<Constant>(BOp1));
return new ICmpInst(Pred, BOp0, SubC); return new ICmpInst(Pred, BOp0, SubC);
} }
} else if (*C == 0) { } else if (C->isNullValue()) {
// Replace ((add A, B) != 0) with (A != -B) if A or B is // Replace ((add A, B) != 0) with (A != -B) if A or B is
// efficiently invertible, or if the add has just this one use. // efficiently invertible, or if the add has just this one use.
if (Value *NegVal = dyn_castNegVal(BOp1)) if (Value *NegVal = dyn_castNegVal(BOp1))
@ -2558,7 +2561,7 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
// For the xor case, we can xor two constants together, eliminating // For the xor case, we can xor two constants together, eliminating
// the explicit xor. // the explicit xor.
return new ICmpInst(Pred, BOp0, ConstantExpr::getXor(RHS, BOC)); return new ICmpInst(Pred, BOp0, ConstantExpr::getXor(RHS, BOC));
} else if (*C == 0) { } else if (C->isNullValue()) {
// Replace ((xor A, B) != 0) with (A != B) // Replace ((xor A, B) != 0) with (A != B)
return new ICmpInst(Pred, BOp0, BOp1); return new ICmpInst(Pred, BOp0, BOp1);
} }
@ -2571,7 +2574,7 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
// Replace ((sub BOC, B) != C) with (B != BOC-C). // Replace ((sub BOC, B) != C) with (B != BOC-C).
Constant *SubC = ConstantExpr::getSub(cast<Constant>(BOp0), RHS); Constant *SubC = ConstantExpr::getSub(cast<Constant>(BOp0), RHS);
return new ICmpInst(Pred, BOp1, SubC); return new ICmpInst(Pred, BOp1, SubC);
} else if (*C == 0) { } else if (C->isNullValue()) {
// Replace ((sub A, B) != 0) with (A != B). // Replace ((sub A, B) != 0) with (A != B).
return new ICmpInst(Pred, BOp0, BOp1); return new ICmpInst(Pred, BOp0, BOp1);
} }
@ -2609,7 +2612,7 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
} }
// ((X & ~7) == 0) --> X < 8 // ((X & ~7) == 0) --> X < 8
if (*C == 0 && (~(*BOC) + 1).isPowerOf2()) { if (C->isNullValue() && (~(*BOC) + 1).isPowerOf2()) {
Constant *NegBOC = ConstantExpr::getNeg(cast<Constant>(BOp1)); Constant *NegBOC = ConstantExpr::getNeg(cast<Constant>(BOp1));
auto NewPred = isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT; auto NewPred = isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
return new ICmpInst(NewPred, BOp0, NegBOC); return new ICmpInst(NewPred, BOp0, NegBOC);
@ -2618,9 +2621,9 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
break; break;
} }
case Instruction::Mul: case Instruction::Mul:
if (*C == 0 && BO->hasNoSignedWrap()) { if (C->isNullValue() && BO->hasNoSignedWrap()) {
const APInt *BOC; const APInt *BOC;
if (match(BOp1, m_APInt(BOC)) && *BOC != 0) { if (match(BOp1, m_APInt(BOC)) && !BOC->isNullValue()) {
// The trivial case (mul X, 0) is handled by InstSimplify. // The trivial case (mul X, 0) is handled by InstSimplify.
// General case : (mul X, C) != 0 iff X != 0 // General case : (mul X, C) != 0 iff X != 0
// (mul X, C) == 0 iff X == 0 // (mul X, C) == 0 iff X == 0
@ -2629,7 +2632,7 @@ Instruction *InstCombiner::foldICmpBinOpEqualityWithConstant(ICmpInst &Cmp,
} }
break; break;
case Instruction::UDiv: case Instruction::UDiv:
if (*C == 0) { if (C->isNullValue()) {
// (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A) // (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A)
auto NewPred = isICMP_NE ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_UGT; auto NewPred = isICMP_NE ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_UGT;
return new ICmpInst(NewPred, BOp1, BOp0); return new ICmpInst(NewPred, BOp1, BOp0);
@ -2668,7 +2671,7 @@ Instruction *InstCombiner::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
case Intrinsic::ctpop: { case Intrinsic::ctpop: {
// popcount(A) == 0 -> A == 0 and likewise for != // popcount(A) == 0 -> A == 0 and likewise for !=
// popcount(A) == bitwidth(A) -> A == -1 and likewise for != // popcount(A) == bitwidth(A) -> A == -1 and likewise for !=
bool IsZero = *C == 0; bool IsZero = C->isNullValue();
if (IsZero || *C == C->getBitWidth()) { if (IsZero || *C == C->getBitWidth()) {
Worklist.Add(II); Worklist.Add(II);
Cmp.setOperand(0, II->getArgOperand(0)); Cmp.setOperand(0, II->getArgOperand(0));
@ -3057,7 +3060,8 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) {
break; break;
const APInt *C; const APInt *C;
if (match(BO0->getOperand(1), m_APInt(C)) && *C != 0 && *C != 1) { if (match(BO0->getOperand(1), m_APInt(C)) && !C->isNullValue() &&
!C->isOneValue()) {
// icmp eq/ne (X * C), (Y * C) --> icmp (X & Mask), (Y & Mask) // icmp eq/ne (X * C), (Y * C) --> icmp (X & Mask), (Y & Mask)
// Mask = -1 >> count-trailing-zeros(C). // Mask = -1 >> count-trailing-zeros(C).
if (unsigned TZs = C->countTrailingZeros()) { if (unsigned TZs = C->countTrailingZeros()) {
@ -4093,7 +4097,7 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
// Check if the LHS is 8 >>u x and the result is a power of 2 like 1. // Check if the LHS is 8 >>u x and the result is a power of 2 like 1.
const APInt *CI; const APInt *CI;
if (Op0KnownZeroInverted == 1 && if (Op0KnownZeroInverted.isOneValue() &&
match(LHS, m_LShr(m_Power2(CI), m_Value(X)))) { match(LHS, m_LShr(m_Power2(CI), m_Value(X)))) {
// ((8 >>u X) & 1) == 0 -> X != 3 // ((8 >>u X) & 1) == 0 -> X != 3
// ((8 >>u X) & 1) != 0 -> X == 3 // ((8 >>u X) & 1) != 0 -> X == 3

View File

@ -930,7 +930,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
} }
} }
if (*C2 != 0) // avoid X udiv 0 if (!C2->isNullValue()) // avoid X udiv 0
if (Instruction *FoldedDiv = foldOpWithConstantIntoOperand(I)) if (Instruction *FoldedDiv = foldOpWithConstantIntoOperand(I))
return FoldedDiv; return FoldedDiv;
} }

View File

@ -1478,9 +1478,9 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
if (!CondVal->getType()->isVectorTy() && !AC.assumptions().empty()) { if (!CondVal->getType()->isVectorTy() && !AC.assumptions().empty()) {
KnownBits Known(1); KnownBits Known(1);
computeKnownBits(CondVal, Known, 0, &SI); computeKnownBits(CondVal, Known, 0, &SI);
if (Known.One == 1) if (Known.One.isOneValue())
return replaceInstUsesWith(SI, TrueVal); return replaceInstUsesWith(SI, TrueVal);
if (Known.Zero == 1) if (Known.Zero.isOneValue())
return replaceInstUsesWith(SI, FalseVal); return replaceInstUsesWith(SI, FalseVal);
} }

View File

@ -121,7 +121,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
} }
Known.resetAll(); Known.resetAll();
if (DemandedMask == 0) // Not demanding any bits from V. if (DemandedMask.isNullValue()) // Not demanding any bits from V.
return UndefValue::get(VTy); return UndefValue::get(VTy);
if (Depth == 6) // Limit search depth. if (Depth == 6) // Limit search depth.
@ -488,7 +488,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
// always convert this into a logical shr, even if the shift amount is // always convert this into a logical shr, even if the shift amount is
// variable. The low bit of the shift cannot be an input sign bit unless // variable. The low bit of the shift cannot be an input sign bit unless
// the shift amount is >= the size of the datatype, which is undefined. // the shift amount is >= the size of the datatype, which is undefined.
if (DemandedMask == 1) { if (DemandedMask.isOneValue()) {
// Perform the logical shift right. // Perform the logical shift right.
Instruction *NewVal = BinaryOperator::CreateLShr( Instruction *NewVal = BinaryOperator::CreateLShr(
I->getOperand(0), I->getOperand(1), I->getName()); I->getOperand(0), I->getOperand(1), I->getName());
@ -656,7 +656,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
// If we don't need any of low bits then return zero, // If we don't need any of low bits then return zero,
// we know that DemandedMask is non-zero already. // we know that DemandedMask is non-zero already.
APInt DemandedElts = DemandedMask.zextOrTrunc(ArgWidth); APInt DemandedElts = DemandedMask.zextOrTrunc(ArgWidth);
if (DemandedElts == 0) if (DemandedElts.isNullValue())
return ConstantInt::getNullValue(VTy); return ConstantInt::getNullValue(VTy);
// We know that the upper bits are set to zero. // We know that the upper bits are set to zero.
@ -908,7 +908,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,
return nullptr; return nullptr;
} }
if (DemandedElts == 0) { // If nothing is demanded, provide undef. if (DemandedElts.isNullValue()) { // If nothing is demanded, provide undef.
UndefElts = EltMask; UndefElts = EltMask;
return UndefValue::get(V->getType()); return UndefValue::get(V->getType());
} }