diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index dad8e07dadb..d27afb09cf3 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -6135,18 +6135,30 @@ bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred, // If LHS or RHS is an addrec, check to see if the condition is true in // every iteration of the loop. - if (const SCEVAddRecExpr *AR = dyn_cast(LHS)) - if (isLoopEntryGuardedByCond( - AR->getLoop(), Pred, AR->getStart(), RHS) && - isLoopBackedgeGuardedByCond( - AR->getLoop(), Pred, AR->getPostIncExpr(*this), RHS)) - return true; - if (const SCEVAddRecExpr *AR = dyn_cast(RHS)) - if (isLoopEntryGuardedByCond( - AR->getLoop(), Pred, LHS, AR->getStart()) && - isLoopBackedgeGuardedByCond( - AR->getLoop(), Pred, LHS, AR->getPostIncExpr(*this))) - return true; + // If LHS and RHS are both addrec, both conditions must be true in + // every iteration of the loop. + const SCEVAddRecExpr *LAR = dyn_cast(LHS); + const SCEVAddRecExpr *RAR = dyn_cast(RHS); + bool LeftGuarded = false; + bool RightGuarded = false; + if (LAR) { + const Loop *L = LAR->getLoop(); + if (isLoopEntryGuardedByCond(L, Pred, LAR->getStart(), RHS) && + isLoopBackedgeGuardedByCond(L, Pred, LAR->getPostIncExpr(*this), RHS)) { + if (!RAR) return true; + LeftGuarded = true; + } + } + if (RAR) { + const Loop *L = RAR->getLoop(); + if (isLoopEntryGuardedByCond(L, Pred, LHS, RAR->getStart()) && + isLoopBackedgeGuardedByCond(L, Pred, LHS, RAR->getPostIncExpr(*this))) { + if (!LAR) return true; + RightGuarded = true; + } + } + if (LeftGuarded && RightGuarded) + return true; // Otherwise see what can be done with known constant ranges. return isKnownPredicateWithRanges(Pred, LHS, RHS); diff --git a/test/Transforms/IndVarSimplify/pr18223.ll b/test/Transforms/IndVarSimplify/pr18223.ll new file mode 100644 index 00000000000..738f75c0fe0 --- /dev/null +++ b/test/Transforms/IndVarSimplify/pr18223.ll @@ -0,0 +1,30 @@ +; RUN: opt -indvars -S < %s | FileCheck %s + +; indvars should transform the phi node pair from the for-loop +; CHECK-LABEL: @main( +; CHECK: ret = phi i32 [ 0, %entry ], [ 0, {{.*}} ] + +@c = common global i32 0, align 4 + +define i32 @main() #0 { +entry: + %0 = load i32* @c, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %for.body, label %exit + +for.body: + %inc2 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] + %sub = add i32 %inc2, -1 + %cmp1 = icmp uge i32 %sub, %inc2 + %conv = zext i1 %cmp1 to i32 + br label %for.inc + +for.inc: + %inc = add nsw i32 %inc2, 1 + %cmp = icmp slt i32 %inc, 5 + br i1 %cmp, label %for.body, label %exit + +exit: + %ret = phi i32 [ 0, %entry ], [ %conv, %for.inc ] + ret i32 %ret +}