Skip to content

Commit cbb8438

Browse files
committed
ScalarEvolution: Fix handling of AddRecs in isKnownPredicate
ScalarEvolution::isKnownPredicate() can wrongly reduce a comparison when both the LHS and RHS are SCEVAddRecExprs. This checks that both LHS and RHS are guarded in the case when both are SCEVAddRecExprs. The test case is against indvars because I could not find a way to directly test SCEV. Patch by Sanjay Patel! llvm-svn: 209487
1 parent f713cce commit cbb8438

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6135,18 +6135,30 @@ bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
61356135

61366136
// If LHS or RHS is an addrec, check to see if the condition is true in
61376137
// every iteration of the loop.
6138-
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS))
6139-
if (isLoopEntryGuardedByCond(
6140-
AR->getLoop(), Pred, AR->getStart(), RHS) &&
6141-
isLoopBackedgeGuardedByCond(
6142-
AR->getLoop(), Pred, AR->getPostIncExpr(*this), RHS))
6143-
return true;
6144-
if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(RHS))
6145-
if (isLoopEntryGuardedByCond(
6146-
AR->getLoop(), Pred, LHS, AR->getStart()) &&
6147-
isLoopBackedgeGuardedByCond(
6148-
AR->getLoop(), Pred, LHS, AR->getPostIncExpr(*this)))
6149-
return true;
6138+
// If LHS and RHS are both addrec, both conditions must be true in
6139+
// every iteration of the loop.
6140+
const SCEVAddRecExpr *LAR = dyn_cast<SCEVAddRecExpr>(LHS);
6141+
const SCEVAddRecExpr *RAR = dyn_cast<SCEVAddRecExpr>(RHS);
6142+
bool LeftGuarded = false;
6143+
bool RightGuarded = false;
6144+
if (LAR) {
6145+
const Loop *L = LAR->getLoop();
6146+
if (isLoopEntryGuardedByCond(L, Pred, LAR->getStart(), RHS) &&
6147+
isLoopBackedgeGuardedByCond(L, Pred, LAR->getPostIncExpr(*this), RHS)) {
6148+
if (!RAR) return true;
6149+
LeftGuarded = true;
6150+
}
6151+
}
6152+
if (RAR) {
6153+
const Loop *L = RAR->getLoop();
6154+
if (isLoopEntryGuardedByCond(L, Pred, LHS, RAR->getStart()) &&
6155+
isLoopBackedgeGuardedByCond(L, Pred, LHS, RAR->getPostIncExpr(*this))) {
6156+
if (!LAR) return true;
6157+
RightGuarded = true;
6158+
}
6159+
}
6160+
if (LeftGuarded && RightGuarded)
6161+
return true;
61506162

61516163
// Otherwise see what can be done with known constant ranges.
61526164
return isKnownPredicateWithRanges(Pred, LHS, RHS);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: opt -indvars -S < %s | FileCheck %s
2+
3+
; indvars should transform the phi node pair from the for-loop
4+
; CHECK-LABEL: @main(
5+
; CHECK: ret = phi i32 [ 0, %entry ], [ 0, {{.*}} ]
6+
7+
@c = common global i32 0, align 4
8+
9+
define i32 @main() #0 {
10+
entry:
11+
%0 = load i32* @c, align 4
12+
%tobool = icmp eq i32 %0, 0
13+
br i1 %tobool, label %for.body, label %exit
14+
15+
for.body:
16+
%inc2 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
17+
%sub = add i32 %inc2, -1
18+
%cmp1 = icmp uge i32 %sub, %inc2
19+
%conv = zext i1 %cmp1 to i32
20+
br label %for.inc
21+
22+
for.inc:
23+
%inc = add nsw i32 %inc2, 1
24+
%cmp = icmp slt i32 %inc, 5
25+
br i1 %cmp, label %for.body, label %exit
26+
27+
exit:
28+
%ret = phi i32 [ 0, %entry ], [ %conv, %for.inc ]
29+
ret i32 %ret
30+
}

0 commit comments

Comments
 (0)