aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp21
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;
}