OSDN Git Service

Make LoopDeletion check the maximum backedge taken count, rather than the
authorDan Gohman <gohman@apple.com>
Fri, 23 Oct 2009 17:10:01 +0000 (17:10 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 23 Oct 2009 17:10:01 +0000 (17:10 +0000)
exact backedge taken count, when checking for infinite loops. This allows
it to delete loops with multiple exit conditions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84952 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/LoopDeletion.cpp
test/Transforms/LoopDeletion/multiple-exit-conditions.ll [new file with mode: 0644]

index 5f93756..8133a06 100644 (file)
@@ -167,7 +167,7 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) {
   // Don't remove loops for which we can't solve the trip count.
   // They could be infinite, in which case we'd be changing program behavior.
   ScalarEvolution& SE = getAnalysis<ScalarEvolution>();
-  const SCEV *S = SE.getBackedgeTakenCount(L);
+  const SCEV *S = SE.getMaxBackedgeTakenCount(L);
   if (isa<SCEVCouldNotCompute>(S))
     return Changed;
   
diff --git a/test/Transforms/LoopDeletion/multiple-exit-conditions.ll b/test/Transforms/LoopDeletion/multiple-exit-conditions.ll
new file mode 100644 (file)
index 0000000..87f8f46
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: opt < %s -loop-deletion -S | FileCheck %s
+
+; ScalarEvolution can prove the loop iteration is finite, even though
+; it can't represent the exact trip count as an expression. That's
+; good enough to let the loop be deleted.
+
+; CHECK:      entry:
+; CHECK-NEXT:   br label %return
+
+; CHECK:      return:
+; CHECK-NEXT:   ret void
+
+define void @foo(i64 %n, i64 %m) nounwind {
+entry:
+  br label %bb
+
+bb:
+  %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb ]
+  %t0 = add i64 %x.0, 1
+  %t1 = icmp slt i64 %x.0, %n
+  %t3 = icmp sgt i64 %x.0, %m
+  %t4 = and i1 %t1, %t3
+  br i1 %t4, label %bb, label %return
+
+return:
+  ret void
+}