summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp2
-rw-r--r--test/Transforms/IndVarSimplify/udiv-invariant-but-traps.ll32
2 files changed, 33 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index 8e76c78f5a..df11e92c9e 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -532,7 +532,7 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
// and varies predictably *inside* the loop. Evaluate the value it
// contains when the loop exits, if possible.
const SCEV *ExitValue = SE->getSCEVAtScope(Inst, L->getParentLoop());
- if (!SE->isLoopInvariant(ExitValue, L))
+ if (!SE->isLoopInvariant(ExitValue, L) || !isSafeToExpand(ExitValue))
continue;
// Computing the value outside of the loop brings no benefit if :
diff --git a/test/Transforms/IndVarSimplify/udiv-invariant-but-traps.ll b/test/Transforms/IndVarSimplify/udiv-invariant-but-traps.ll
new file mode 100644
index 0000000000..b2d2629eb3
--- /dev/null
+++ b/test/Transforms/IndVarSimplify/udiv-invariant-but-traps.ll
@@ -0,0 +1,32 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+@b = common global i32 0, align 4
+
+define i32 @foo(i32 %x, i1 %y) {
+bb0:
+ br label %bb1
+
+bb1:
+ br i1 %y, label %bb14, label %bb8
+
+bb8:
+ %i = phi i64 [ %i.next, %bb8 ], [ 0, %bb1 ]
+ %i.next = add i64 %i, 1
+ %div = udiv i32 1, %x
+ %c = icmp eq i64 %i.next, 6
+ br i1 %c, label %bb11, label %bb8
+
+bb11:
+ br i1 %y, label %bb1, label %bb13
+
+bb13:
+ store i32 %div, i32* @b, align 4
+ br label %bb14
+
+bb14:
+ ret i32 0
+}
+
+; CHECK: @foo
+; CHECK: bb8:
+; CHECK: udiv