[llvm-commits] [llvm] r110758 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/max-trip-count.ll

Dan Gohman gohman at apple.com
Tue Aug 10 17:12:36 PDT 2010


Author: djg
Date: Tue Aug 10 19:12:36 2010
New Revision: 110758

URL: http://llvm.org/viewvc/llvm-project?rev=110758&view=rev
Log:
When analyzing loop exit conditions combined with and and or, don't
make any assumptions about when the two conditions will agree on when
to permit the loop to exit. This fixes PR7845.

Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp
    llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=110758&r1=110757&r2=110758&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Aug 10 19:12:36 2010
@@ -3854,14 +3854,13 @@
         else
           MaxBECount = getUMinFromMismatchedTypes(BTI0.Max, BTI1.Max);
       } else {
-        // Both conditions must be true for the loop to exit.
+        // Both conditions must be true at the same time for the loop to exit.
+        // For now, be conservative.
         assert(L->contains(FBB) && "Loop block has no successor in loop!");
-        if (BTI0.Exact != getCouldNotCompute() &&
-            BTI1.Exact != getCouldNotCompute())
-          BECount = getUMaxFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
-        if (BTI0.Max != getCouldNotCompute() &&
-            BTI1.Max != getCouldNotCompute())
-          MaxBECount = getUMaxFromMismatchedTypes(BTI0.Max, BTI1.Max);
+        if (BTI0.Max == BTI1.Max)
+          MaxBECount = BTI0.Max;
+        if (BTI0.Exact == BTI1.Exact)
+          BECount = BTI0.Exact;
       }
 
       return BackedgeTakenInfo(BECount, MaxBECount);
@@ -3889,14 +3888,13 @@
         else
           MaxBECount = getUMinFromMismatchedTypes(BTI0.Max, BTI1.Max);
       } else {
-        // Both conditions must be false for the loop to exit.
+        // Both conditions must be false at the same time for the loop to exit.
+        // For now, be conservative.
         assert(L->contains(TBB) && "Loop block has no successor in loop!");
-        if (BTI0.Exact != getCouldNotCompute() &&
-            BTI1.Exact != getCouldNotCompute())
-          BECount = getUMaxFromMismatchedTypes(BTI0.Exact, BTI1.Exact);
-        if (BTI0.Max != getCouldNotCompute() &&
-            BTI1.Max != getCouldNotCompute())
-          MaxBECount = getUMaxFromMismatchedTypes(BTI0.Max, BTI1.Max);
+        if (BTI0.Max == BTI1.Max)
+          MaxBECount = BTI0.Max;
+        if (BTI0.Exact == BTI1.Exact)
+          BECount = BTI0.Exact;
       }
 
       return BackedgeTakenInfo(BECount, MaxBECount);

Modified: llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll?rev=110758&r1=110757&r2=110758&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll Tue Aug 10 19:12:36 2010
@@ -1,8 +1,9 @@
-; RUN: opt < %s -analyze -scalar-evolution \
-; RUN:   | grep {\{%d,+,\[^\{\}\]\*\}<%bb>}
+; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
 
 ; ScalarEvolution should be able to understand the loop and eliminate the casts.
 
+; CHECK: {%d,+,sizeof(i32)}
+
 define void @foo(i32* nocapture %d, i32 %n) nounwind {
 entry:
 	%0 = icmp sgt i32 %n, 0		; <i1> [#uses=1]
@@ -32,3 +33,40 @@
 return:		; preds = %bb1.return_crit_edge, %entry
 	ret void
 }
+
+; ScalarEvolution should be able to find the maximum tripcount
+; of this multiple-exit loop, and if it doesn't know the exact
+; count, it should say so.
+
+; PR7845
+; CHECK: Loop %for.cond: <multiple exits> Unpredictable backedge-taken count. 
+; CHECK: Loop %for.cond: max backedge-taken count is 5
+
+ at .str = private constant [4 x i8] c"%d\0A\00"     ; <[4 x i8]*> [#uses=2]
+
+define i32 @main() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %g_4.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ] ; <i32> [#uses=5]
+  %cmp = icmp slt i32 %g_4.0, 5                   ; <i1> [#uses=1]
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %conv = trunc i32 %g_4.0 to i16                 ; <i16> [#uses=1]
+  %tobool.not = icmp eq i16 %conv, 0              ; <i1> [#uses=1]
+  %tobool3 = icmp ne i32 %g_4.0, 0                ; <i1> [#uses=1]
+  %or.cond = and i1 %tobool.not, %tobool3         ; <i1> [#uses=1]
+  br i1 %or.cond, label %for.end, label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %add = add nsw i32 %g_4.0, 1                    ; <i32> [#uses=1]
+  br label %for.cond
+
+for.end:                                          ; preds = %for.body, %for.cond
+  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %g_4.0) nounwind ; <i32> [#uses=0]
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)





More information about the llvm-commits mailing list