Switch invars away from using isTrapping when it really shouldn't be
authorEli Friedman <eli.friedman@gmail.com>
Wed, 15 Jul 2009 22:48:29 +0000 (22:48 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 15 Jul 2009 22:48:29 +0000 (22:48 +0000)
using it.

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

lib/Transforms/Scalar/IndVarSimplify.cpp
test/Transforms/IndVarSimplify/sink-trapping.ll [new file with mode: 0644]

index 1a6c6a1321175b9324abae3d5f12e291d95743ed..0ac58f1fea9ef078f0f430e6ffbd13e2eff12605 100644 (file)
@@ -544,7 +544,13 @@ void IndVarSimplify::SinkUnusedInvariants(Loop *L) {
     // New instructions were inserted at the end of the preheader.
     if (isa<PHINode>(I))
       break;
-    if (I->isTrapping())
+    // Don't move instructions which might have side effects, since the side
+    // effects need to complete before instructions inside the loop.  Also
+    // don't move instructions which might read memory, since the loop may
+    // modify memory. Note that it's okay if the instruction might have
+    // undefined behavior: LoopSimplify guarantees that the preheader
+    // dominates the exit block.
+    if (I->mayHaveSideEffects() || I->mayReadFromMemory())
       continue;
     // Determine if there is a use in or before the loop (direct or
     // otherwise).
diff --git a/test/Transforms/IndVarSimplify/sink-trapping.ll b/test/Transforms/IndVarSimplify/sink-trapping.ll
new file mode 100644 (file)
index 0000000..5382c92
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | opt -indvars | llvm-dis | FileCheck %s --check-prefix=CHECK
+
+declare i1 @b()
+
+define i32 @a(i32 %x) nounwind {
+for.body.preheader:
+    %y = sdiv i32 10, %x
+       br label %for.body
+
+for.body:
+    %cmp = call i1 @b()
+       br i1 %cmp, label %for.body, label %for.end.loopexit
+
+for.end.loopexit:
+       ret i32 %y
+}
+; CHECK: for.end.loopexit:
+; CHECK: sdiv
+; CHECK: ret