aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-06-09 01:13:59 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-06-09 01:13:59 +0000
commitc7f69b921ff8b2e06762055e159cce55cd5f406b (patch)
tree6cb5b577bd19ec1fe8cbd2476039bfa7fa3ef328
parent97cd7d5d44b60df7fc4a8dffb0a7d7d8d128aee2 (diff)
downloadllvm-c7f69b921ff8b2e06762055e159cce55cd5f406b.zip
llvm-c7f69b921ff8b2e06762055e159cce55cd5f406b.tar.gz
llvm-c7f69b921ff8b2e06762055e159cce55cd5f406b.tar.bz2
Be wary of abnormal exits from loop when exploiting UB
We can safely rely on a NoWrap add recurrence causing UB down the road only if we know the loop does not have a exit expressed in a way that is opaque to ScalarEvolution (e.g. by a function call that conditionally calls exit(0)). I believe with this change PR28012 is fixed. Note: I had to change some llvm-lit tests in LoopReroll, since it looks like they were depending on this incorrect behavior. llvm-svn: 272237
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp3
-rw-r--r--llvm/test/Analysis/ScalarEvolution/trip-count.ll22
-rw-r--r--llvm/test/Transforms/LoopReroll/basic.ll8
3 files changed, 28 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 9278aa0..867b051 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -7199,7 +7199,8 @@ ScalarEvolution::howFarToZero(const SCEV *V, const Loop *L, bool ControlsExit,
// compute the backedge count. In this case, the step may not divide the
// distance, but we don't care because if the condition is "missed" the loop
// will have undefined behavior due to wrapping.
- if (ControlsExit && AddRec->hasNoSelfWrap()) {
+ if (ControlsExit && AddRec->hasNoSelfWrap() &&
+ loopHasNoAbnormalExits(AddRec->getLoop())) {
const SCEV *Exact =
getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
return ExitLimit(Exact, Exact, P);
diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count.ll b/llvm/test/Analysis/ScalarEvolution/trip-count.ll
index 8975081..d21ace9 100644
--- a/llvm/test/Analysis/ScalarEvolution/trip-count.ll
+++ b/llvm/test/Analysis/ScalarEvolution/trip-count.ll
@@ -89,3 +89,25 @@ for.inc.1: ; preds = %for.body.1, %for.in
; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #0
+
+declare void @may_exit() nounwind
+
+define void @pr28012(i32 %n) {
+; CHECK-LABEL: Classifying expressions for: @pr28012
+; CHECK: Loop %loop: backedge-taken count is -1431655751
+; CHECK: Loop %loop: max backedge-taken count is -1431655751
+; CHECK: Loop %loop: Predicated backedge-taken count is -1431655751
+
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+ %iv.inc = add nsw i32 %iv, 3
+ call void @may_exit()
+ %becond = icmp ne i32 %iv.inc, 46
+ br i1 %becond, label %loop, label %leave
+
+leave:
+ ret void
+}
diff --git a/llvm/test/Transforms/LoopReroll/basic.ll b/llvm/test/Transforms/LoopReroll/basic.ll
index 16a6dc8..ce2ab2f 100644
--- a/llvm/test/Transforms/LoopReroll/basic.ll
+++ b/llvm/test/Transforms/LoopReroll/basic.ll
@@ -24,7 +24,7 @@ for.body: ; preds = %for.body, %entry
%add2 = add nsw i32 %i.08, 2
%call3 = tail call i32 @foo(i32 %add2) #1
%add3 = add nsw i32 %i.08, 3
- %exitcond = icmp eq i32 %add3, 500
+ %exitcond = icmp sge i32 %add3, 500
br i1 %exitcond, label %for.end, label %for.body
; CHECK-LABEL: @bar
@@ -33,7 +33,7 @@ for.body: ; preds = %for.body, %entry
; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
; CHECK: %call = tail call i32 @foo(i32 %indvar) #1
; CHECK: %indvar.next = add i32 %indvar, 1
-; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
+; CHECK: %exitcond1 = icmp eq i32 %indvar, 500
; CHECK: br i1 %exitcond1, label %for.end, label %for.body
; CHECK: ret
@@ -524,7 +524,7 @@ for.body: ; preds = %for.body, %entry
%add3 = add nsw i32 %i.08, 3
- %exitcond = icmp eq i32 %add3, 500
+ %exitcond = icmp sge i32 %add3, 500
br i1 %exitcond, label %for.end, label %for.body
; CHECK-LABEL: @bar2
@@ -536,7 +536,7 @@ for.body: ; preds = %for.body, %entry
; CHECK: %tmp3 = add i32 %tmp2, %tmp1
; CHECK: %call = tail call i32 @foo(i32 %tmp3) #1
; CHECK: %indvar.next = add i32 %indvar, 1
-; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
+; CHECK: %exitcond1 = icmp eq i32 %indvar, 500
; CHECK: br i1 %exitcond1, label %for.end, label %for.body
; CHECK: ret