InstCombine: merge constants in both operands of icmp.

Transform:
    icmp X+Cst2, Cst
into:
    icmp X, Cst-Cst2
when Cst-Cst2 does not overflow, and the add has nsw.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204912 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Erik Verbruggen
2014-03-27 11:16:05 +00:00
parent 5fa6dffd30
commit 668c2aa517
3 changed files with 66 additions and 12 deletions

View File

@@ -3008,6 +3008,19 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
// icmp X, X+Cst
if (match(Op1, m_Add(m_Value(X), m_ConstantInt(Cst))) && Op0 == X)
return FoldICmpAddOpCst(I, X, Cst, I.getSwappedPredicate());
ConstantInt *Cst2;
if (match(Op1, m_ConstantInt(Cst)) &&
match(Op0, m_Add(m_Value(X), m_ConstantInt(Cst2))) &&
cast<BinaryOperator>(Op0)->hasNoSignedWrap()) {
// icmp X+Cst2, Cst --> icmp X, Cst-Cst2
// iff Cst-Cst2 does not overflow
bool Overflow;
APInt NewCst = Cst->getValue().ssub_ov(Cst2->getValue(), Overflow);
if (!Overflow)
return new ICmpInst(I.getPredicate(), X,
ConstantInt::get(Cst->getType(), NewCst));
}
}
return Changed ? &I : 0;
}