diff options
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 079d7da..b08399b 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -10810,6 +10810,25 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS, if (Depth >= 3) return false; + const SCEV *NewLHS, *NewRHS; + if (match(LHS, m_scev_c_Mul(m_SCEV(NewLHS), m_SCEVVScale())) && + match(RHS, m_scev_c_Mul(m_SCEV(NewRHS), m_SCEVVScale()))) { + const SCEVMulExpr *LMul = cast<SCEVMulExpr>(LHS); + const SCEVMulExpr *RMul = cast<SCEVMulExpr>(RHS); + + // (X * vscale) pred (Y * vscale) ==> X pred Y + // when both multiples are NSW. + // (X * vscale) uicmp/eq/ne (Y * vscale) ==> X uicmp/eq/ne Y + // when both multiples are NUW. + if ((LMul->hasNoSignedWrap() && RMul->hasNoSignedWrap()) || + (LMul->hasNoUnsignedWrap() && RMul->hasNoUnsignedWrap() && + !ICmpInst::isSigned(Pred))) { + LHS = NewLHS; + RHS = NewRHS; + Changed = true; + } + } + // Canonicalize a constant to the right side. if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) { // Check for both operands constant. @@ -10984,7 +11003,7 @@ bool ScalarEvolution::SimplifyICmpOperands(CmpPredicate &Pred, const SCEV *&LHS, // Recursively simplify until we either hit a recursion limit or nothing // changes. if (Changed) - return SimplifyICmpOperands(Pred, LHS, RHS, Depth + 1); + (void)SimplifyICmpOperands(Pred, LHS, RHS, Depth + 1); return Changed; } |