[InstCombine] add helper functions for foldICmpWithConstant; NFCI

Besides breaking up a 700 line function to improve readability,
this sinks the 'FIXME: ConstantInt' check into each helper. So 
now we can independently break that restriction within any of the
helper functions.

As much as possible, the code was only {cut/paste/clang-format}'ed 
to minimize risk (no functional changes intended), so several more
readability improvements are still possible. 

llvm-svn: 278828
This commit is contained in:
Sanjay Patel 2016-08-16 17:54:36 +00:00
parent 5cd57177a5
commit a3f4f0828b
2 changed files with 790 additions and 653 deletions

View File

@ -1179,7 +1179,8 @@ Instruction *InstCombiner::foldICmpAddOpConst(Instruction &ICI,
/// Fold "icmp pred, ([su]div X, DivRHS), CmpRHS" where DivRHS and CmpRHS are
/// both known to be integer constants.
Instruction *InstCombiner::foldICmpDivConst(ICmpInst &ICI, BinaryOperator *DivI,
Instruction *InstCombiner::foldICmpDivConstConst(ICmpInst &ICI,
BinaryOperator *DivI,
ConstantInt *DivRHS) {
ConstantInt *CmpRHS = cast<ConstantInt>(ICI.getOperand(1));
const APInt &CmpRHSV = CmpRHS->getValue();
@ -1335,7 +1336,8 @@ Instruction *InstCombiner::foldICmpDivConst(ICmpInst &ICI, BinaryOperator *DivI,
}
/// Handle "icmp(([al]shr X, cst1), cst2)".
Instruction *InstCombiner::foldICmpShrConst(ICmpInst &ICI, BinaryOperator *Shr,
Instruction *InstCombiner::foldICmpShrConstConst(ICmpInst &ICI,
BinaryOperator *Shr,
ConstantInt *ShAmt) {
const APInt &CmpRHSV = cast<ConstantInt>(ICI.getOperand(1))->getValue();
@ -1382,7 +1384,8 @@ Instruction *InstCombiner::foldICmpShrConst(ICmpInst &ICI, BinaryOperator *Shr,
assert(TheDiv->getOpcode() == Instruction::SDiv ||
TheDiv->getOpcode() == Instruction::UDiv);
Instruction *Res = foldICmpDivConst(ICI, TheDiv, cast<ConstantInt>(DivCst));
Instruction *Res =
foldICmpDivConstConst(ICI, TheDiv, cast<ConstantInt>(DivCst));
assert(Res && "This div/cst should have folded!");
return Res;
}
@ -1530,21 +1533,14 @@ Instruction *InstCombiner::foldICmpCstShlConst(ICmpInst &I, Value *Op, Value *A,
return getConstant(false);
}
/// Try to fold integer comparisons with a constant operand: icmp Pred X, C.
Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
Instruction *LHSI;
const APInt *RHSV;
if (!match(ICI.getOperand(0), m_Instruction(LHSI)) ||
!match(ICI.getOperand(1), m_APInt(RHSV)))
return nullptr;
Instruction *InstCombiner::foldICmpTruncConstant(ICmpInst &ICI,
Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
switch (LHSI->getOpcode()) {
case Instruction::Trunc:
if (RHS->isOne() && RHSV->getBitWidth() > 1) {
// icmp slt trunc(signum(V)) 1 --> icmp slt V, 1
Value *V = nullptr;
@ -1570,9 +1566,16 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
Builder->getInt(NewRHS));
}
}
break;
return nullptr;
}
Instruction *InstCombiner::foldICmpXorConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
case Instruction::Xor: // (icmp pred (xor X, XorCst), CI)
if (ConstantInt *XorCst = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
// If this is a comparison that tests the signbit (X < 0) or (x > -1),
// fold the xor.
@ -1595,19 +1598,16 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
isTrueIfPositive ^= true;
if (isTrueIfPositive)
return new ICmpInst(ICmpInst::ICMP_SGT, CompareVal,
SubOne(RHS));
return new ICmpInst(ICmpInst::ICMP_SGT, CompareVal, SubOne(RHS));
else
return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal,
AddOne(RHS));
return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS));
}
if (LHSI->hasOneUse()) {
// (icmp u/s (xor A SignBit), C) -> (icmp s/u A, (xor C SignBit))
if (!ICI.isEquality() && XorCst->getValue().isSignBit()) {
const APInt &SignBit = XorCst->getValue();
ICmpInst::Predicate Pred = ICI.isSigned()
? ICI.getUnsignedPredicate()
ICmpInst::Predicate Pred = ICI.isSigned() ? ICI.getUnsignedPredicate()
: ICI.getSignedPredicate();
return new ICmpInst(Pred, LHSI->getOperand(0),
Builder->getInt(*RHSV ^ SignBit));
@ -1616,8 +1616,7 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// (icmp u/s (xor A ~SignBit), C) -> (icmp s/u (xor C ~SignBit), A)
if (!ICI.isEquality() && XorCst->isMaxValue(true)) {
const APInt &NotSignBit = XorCst->getValue();
ICmpInst::Predicate Pred = ICI.isSigned()
? ICI.getUnsignedPredicate()
ICmpInst::Predicate Pred = ICI.isSigned() ? ICI.getUnsignedPredicate()
: ICI.getSignedPredicate();
Pred = ICI.getSwappedPredicate(Pred);
return new ICmpInst(Pred, LHSI->getOperand(0),
@ -1637,8 +1636,16 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
XorCst->getValue() == -(*RHSV) && RHSV->isPowerOf2())
return new ICmpInst(ICmpInst::ICMP_UGE, LHSI->getOperand(0), XorCst);
}
break;
case Instruction::And: // (icmp pred (and X, AndCst), RHS)
return nullptr;
}
Instruction *InstCombiner::foldICmpAndConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
if (LHSI->hasOneUse() && isa<ConstantInt>(LHSI->getOperand(1)) &&
LHSI->getOperand(0)->hasOneUse()) {
ConstantInt *AndCst = cast<ConstantInt>(LHSI->getOperand(1));
@ -1669,8 +1676,7 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// Make sure we don't compare the upper bits, SimplifyDemandedBits
// should fold the icmp to true/false in that case.
if (ICI.isEquality() && RHSV->getActiveBits() <= Ty->getBitWidth()) {
Value *NewAnd =
Builder->CreateAnd(Cast->getOperand(0),
Value *NewAnd = Builder->CreateAnd(Cast->getOperand(0),
ConstantExpr::getTrunc(AndCst, Ty));
NewAnd->takeName(LHSI);
return new ICmpInst(ICI.getPredicate(), NewAnd,
@ -1761,9 +1767,8 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// Turn ((X >> Y) & C) == 0 into (X & (C << Y)) == 0. The later is
// preferable because it allows the C<<Y expression to be hoisted out
// of a loop if Y is invariant and X is not.
if (Shift && Shift->hasOneUse() && *RHSV == 0 &&
ICI.isEquality() && !Shift->isArithmeticShift() &&
!isa<Constant>(Shift->getOperand(0))) {
if (Shift && Shift->hasOneUse() && *RHSV == 0 && ICI.isEquality() &&
!Shift->isArithmeticShift() && !isa<Constant>(Shift->getOperand(0))) {
// Compute C << Y.
Value *NS;
if (Shift->getOpcode() == Instruction::LShr) {
@ -1836,8 +1841,7 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// Try to optimize things like "A[i]&42 == 0" to index computations.
if (LoadInst *LI = dyn_cast<LoadInst>(LHSI->getOperand(0))) {
if (GetElementPtrInst *GEP =
dyn_cast<GetElementPtrInst>(LI->getOperand(0)))
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0)))
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
if (GV->isConstant() && GV->hasDefinitiveInitializer() &&
!LI->isVolatile() && isa<ConstantInt>(LHSI->getOperand(1))) {
@ -1851,8 +1855,8 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// X & -C != -C -> X <= u ~C
// iff C is a power of 2
if (ICI.isEquality() && RHS == LHSI->getOperand(1) && (-(*RHSV)).isPowerOf2())
return new ICmpInst(
ICI.getPredicate() == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_UGT
return new ICmpInst(ICI.getPredicate() == ICmpInst::ICMP_EQ
? ICmpInst::ICMP_UGT
: ICmpInst::ICMP_ULE,
LHSI->getOperand(0), SubOne(RHS));
@ -1872,9 +1876,16 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
}
}
}
break;
return nullptr;
}
Instruction *InstCombiner::foldICmpOrConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
case Instruction::Or: {
if (RHS->isOne()) {
// icmp slt signum(V) 1 --> icmp slt V, 1
Value *V = nullptr;
@ -1885,7 +1896,8 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
}
if (!ICI.isEquality() || !RHS->isNullValue() || !LHSI->hasOneUse())
break;
return nullptr;
Value *P, *Q;
if (match(LHSI, m_Or(m_PtrToInt(m_Value(P)), m_PtrToInt(m_Value(Q))))) {
// Simplify icmp eq (or (ptrtoint P), (ptrtoint Q)), 0
@ -1901,12 +1913,19 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
Op = BinaryOperator::CreateOr(ICIP, ICIQ);
return Op;
}
break;
return nullptr;
}
case Instruction::Mul: { // (icmp pred (mul X, Val), CI)
Instruction *InstCombiner::foldICmpMulConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
ConstantInt *Val = dyn_cast<ConstantInt>(LHSI->getOperand(1));
if (!Val) break;
if (!Val)
return nullptr;
// If this is a signed comparison to 0 and the mul is sign preserving,
// use the mul LHS operand instead.
@ -1918,10 +1937,16 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
LHSI->getOperand(0),
Constant::getNullValue(RHS->getType()));
break;
return nullptr;
}
case Instruction::Shl: { // (icmp pred (shl X, ShAmt), CI)
Instruction *InstCombiner::foldICmpShlConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
uint32_t TypeBits = RHSV->getBitWidth();
ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1));
if (!ShAmt) {
@ -1952,8 +1977,7 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
Pred = ICmpInst::ICMP_NE;
}
return new ICmpInst(Pred, X,
ConstantInt::get(RHS->getType(), RHSLog2));
return new ICmpInst(Pred, X, ConstantInt::get(RHS->getType(), RHSLog2));
} else if (ICI.isSigned()) {
if (RHSV->isAllOnesValue()) {
// (1 << X) <= -1 -> X == 31
@ -1984,21 +2008,20 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
Pred, X, ConstantInt::get(RHS->getType(), RHSV->logBase2()));
}
}
break;
return nullptr;
}
// Check that the shift amount is in range. If not, don't perform
// undefined shifts. When the shift is visited it will be
// simplified.
if (ShAmt->uge(TypeBits))
break;
return nullptr;
if (ICI.isEquality()) {
// If we are comparing against bits always shifted out, the
// comparison cannot succeed.
Constant *Comp =
ConstantExpr::getShl(ConstantExpr::getLShr(RHS, ShAmt),
ShAmt);
ConstantExpr::getShl(ConstantExpr::getLShr(RHS, ShAmt), ShAmt);
if (Comp != RHS) { // Comparing against a bit that we know is zero.
bool IsICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE;
Constant *Cst = Builder->getInt1(IsICMP_NE);
@ -2020,11 +2043,11 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
if (LHSI->hasOneUse()) {
// Otherwise strength reduce the shift into an and.
uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits);
Constant *Mask = Builder->getInt(APInt::getLowBitsSet(TypeBits,
TypeBits - ShAmtVal));
Constant *Mask =
Builder->getInt(APInt::getLowBitsSet(TypeBits, TypeBits - ShAmtVal));
Value *And =
Builder->CreateAnd(LHSI->getOperand(0),Mask, LHSI->getName()+".mask");
Value *And = Builder->CreateAnd(LHSI->getOperand(0), Mask,
LHSI->getName() + ".mask");
return new ICmpInst(ICI.getPredicate(), And,
ConstantExpr::getLShr(RHS, ShAmt));
}
@ -2033,10 +2056,8 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// If this is a signed comparison to 0 and the shift is sign preserving,
// use the shift LHS operand instead.
ICmpInst::Predicate pred = ICI.getPredicate();
if (isSignTest(pred, RHS) &&
cast<BinaryOperator>(LHSI)->hasNoSignedWrap())
return new ICmpInst(pred,
LHSI->getOperand(0),
if (isSignTest(pred, RHS) && cast<BinaryOperator>(LHSI)->hasNoSignedWrap())
return new ICmpInst(pred, LHSI->getOperand(0),
Constant::getNullValue(RHS->getType()));
// Otherwise, if this is a comparison of the sign bit, simplify to and/test.
@ -2044,11 +2065,11 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
if (LHSI->hasOneUse() &&
isSignBitCheck(ICI.getPredicate(), RHS, TrueIfSigned)) {
// (X << 31) <s 0 --> (X&1) != 0
Constant *Mask = ConstantInt::get(LHSI->getOperand(0)->getType(),
APInt::getOneBitSet(TypeBits,
TypeBits-ShAmt->getZExtValue()-1));
Value *And =
Builder->CreateAnd(LHSI->getOperand(0), Mask, LHSI->getName()+".mask");
Constant *Mask = ConstantInt::get(
LHSI->getOperand(0)->getType(),
APInt::getOneBitSet(TypeBits, TypeBits - ShAmt->getZExtValue() - 1));
Value *And = Builder->CreateAnd(LHSI->getOperand(0), Mask,
LHSI->getName() + ".mask");
return new ICmpInst(TrueIfSigned ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ,
And, Constant::getNullValue(And->getType()));
}
@ -2060,27 +2081,28 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// free on the target. It has the additional benefit of comparing to a
// smaller constant, which will be target friendly.
unsigned Amt = ShAmt->getLimitedValue(TypeBits - 1);
if (LHSI->hasOneUse() &&
Amt != 0 && RHSV->countTrailingZeros() >= Amt) {
if (LHSI->hasOneUse() && Amt != 0 && RHSV->countTrailingZeros() >= Amt) {
Type *NTy = IntegerType::get(ICI.getContext(), TypeBits - Amt);
Constant *NCI = ConstantExpr::getTrunc(
ConstantExpr::getAShr(RHS,
ConstantInt::get(RHS->getType(), Amt)),
NTy);
ConstantExpr::getAShr(RHS, ConstantInt::get(RHS->getType(), Amt)), NTy);
return new ICmpInst(ICI.getPredicate(),
Builder->CreateTrunc(LHSI->getOperand(0), NTy),
NCI);
Builder->CreateTrunc(LHSI->getOperand(0), NTy), NCI);
}
break;
return nullptr;
}
case Instruction::LShr: // (icmp pred (shr X, ShAmt), CI)
case Instruction::AShr: {
Instruction *InstCombiner::foldICmpShrConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
// Handle equality comparisons of shift-by-constant.
BinaryOperator *BO = cast<BinaryOperator>(LHSI);
if (ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
if (Instruction *Res = foldICmpShrConst(ICI, BO, ShAmt))
if (Instruction *Res = foldICmpShrConstConst(ICI, BO, ShAmt))
return Res;
}
@ -2089,10 +2111,18 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
if (RHSV->isMinValue())
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), RHS);
}
break;
return nullptr;
}
case Instruction::UDiv:
Instruction *InstCombiner::foldICmpUDivConstant(ICmpInst &ICI,
Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
if (ConstantInt *DivLHS = dyn_cast<ConstantInt>(LHSI->getOperand(0))) {
Value *X = LHSI->getOperand(1);
const APInt &C1 = RHS->getValue();
@ -2112,8 +2142,17 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
ConstantInt::get(X->getType(), C2.udiv(C1)));
}
}
// fall-through
case Instruction::SDiv:
return nullptr;
}
Instruction *InstCombiner::foldICmpDivConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
// Fold: icmp pred ([us]div X, C1), C2 -> range test
// Fold this div into the comparison, producing a range check.
// Determine, based on the divide type, what the range is being
@ -2121,14 +2160,24 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
// it, otherwise compute the range [low, hi) bounding the new value.
// See: InsertRangeTest above for the kinds of replacements possible.
if (ConstantInt *DivRHS = dyn_cast<ConstantInt>(LHSI->getOperand(1)))
if (Instruction *R = foldICmpDivConst(ICI, cast<BinaryOperator>(LHSI),
DivRHS))
if (Instruction *R =
foldICmpDivConstConst(ICI, cast<BinaryOperator>(LHSI), DivRHS))
return R;
break;
case Instruction::Sub: {
return nullptr;
}
Instruction *InstCombiner::foldICmpSubConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
ConstantInt *LHSC = dyn_cast<ConstantInt>(LHSI->getOperand(0));
if (!LHSC) break;
if (!LHSC)
return nullptr;
const APInt &LHSV = LHSC->getValue();
// C1-X <u C2 -> (X|(C2-1)) == C1
@ -2147,18 +2196,26 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
(*RHSV + 1).isPowerOf2() && (LHSV & *RHSV) == *RHSV)
return new ICmpInst(ICmpInst::ICMP_NE,
Builder->CreateOr(LHSI->getOperand(1), *RHSV), LHSC);
break;
return nullptr;
}
case Instruction::Add:
Instruction *InstCombiner::foldICmpAddConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(ICI.getOperand(1));
if (!RHS)
return nullptr;
// Fold: icmp pred (add X, C1), C2
if (!ICI.isEquality()) {
ConstantInt *LHSC = dyn_cast<ConstantInt>(LHSI->getOperand(1));
if (!LHSC) break;
const APInt &LHSV = LHSC->getValue();
if (!LHSC)
return nullptr;
ConstantRange CR = ICI.makeConstantRange(ICI.getPredicate(), *RHSV)
.subtract(LHSV);
const APInt &LHSV = LHSC->getValue();
ConstantRange CR =
ICI.makeConstantRange(ICI.getPredicate(), *RHSV).subtract(LHSV);
if (ICI.isSigned()) {
if (CR.getLower().isSignBit()) {
@ -2196,6 +2253,62 @@ Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
Builder->CreateAnd(LHSI->getOperand(0), ~(*RHSV)),
ConstantExpr::getNeg(LHSC));
}
return nullptr;
}
/// Try to fold integer comparisons with a constant operand: icmp Pred X, C.
Instruction *InstCombiner::foldICmpWithConstant(ICmpInst &ICI) {
Instruction *LHSI;
const APInt *RHSV;
if (!match(ICI.getOperand(0), m_Instruction(LHSI)) ||
!match(ICI.getOperand(1), m_APInt(RHSV)))
return nullptr;
switch (LHSI->getOpcode()) {
case Instruction::Trunc:
if (Instruction *I = foldICmpTruncConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::Xor:
if (Instruction *I = foldICmpXorConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::And:
if (Instruction *I = foldICmpAndConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::Or:
if (Instruction *I = foldICmpOrConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::Mul:
if (Instruction *I = foldICmpMulConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::Shl:
if (Instruction *I = foldICmpShlConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::LShr:
case Instruction::AShr:
if (Instruction *I = foldICmpShrConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::UDiv:
if (Instruction *I = foldICmpUDivConstant(ICI, LHSI, RHSV))
return I;
// fall-through
case Instruction::SDiv:
if (Instruction *I = foldICmpDivConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::Sub:
if (Instruction *I = foldICmpSubConstant(ICI, LHSI, RHSV))
return I;
break;
case Instruction::Add:
if (Instruction *I = foldICmpAddConstant(ICI, LHSI, RHSV))
return I;
break;
}

View File

@ -548,9 +548,9 @@ private:
ConstantInt *AndCst = nullptr);
Instruction *foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI,
Constant *RHSC);
Instruction *foldICmpDivConst(ICmpInst &ICI, BinaryOperator *DivI,
Instruction *foldICmpDivConstConst(ICmpInst &ICI, BinaryOperator *DivI,
ConstantInt *DivRHS);
Instruction *foldICmpShrConst(ICmpInst &ICI, BinaryOperator *DivI,
Instruction *foldICmpShrConstConst(ICmpInst &ICI, BinaryOperator *DivI,
ConstantInt *DivRHS);
Instruction *foldICmpCstShrConst(ICmpInst &I, Value *Op, Value *A,
ConstantInt *CI1, ConstantInt *CI2);
@ -560,6 +560,30 @@ private:
ICmpInst::Predicate Pred);
Instruction *foldICmpWithCastAndCast(ICmpInst &ICI);
Instruction *foldICmpWithConstant(ICmpInst &ICI);
Instruction *foldICmpTruncConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpAndConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpXorConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpOrConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpMulConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpShlConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpShrConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpUDivConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpDivConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpSubConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpAddConstant(ICmpInst &ICI, Instruction *LHSI,
const APInt *RHSV);
Instruction *foldICmpEqualityWithConstant(ICmpInst &ICI);
Instruction *foldICmpIntrinsicWithConstant(ICmpInst &ICI);