summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/LoopDeletion
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2017-06-22 20:20:56 +0000
committerAnna Thomas <anna@azul.com>2017-06-22 20:20:56 +0000
commit72c90c87f81b40b2ec6c25a817577add1d816546 (patch)
treecb2f3cb851fd32f409e5e435da3fb6c3b228121c /llvm/test/Transforms/LoopDeletion
parent792fc92be26e9870ea939caedf574a120bc8e67f (diff)
downloadbcm5719-llvm-72c90c87f81b40b2ec6c25a817577add1d816546.tar.gz
bcm5719-llvm-72c90c87f81b40b2ec6c25a817577add1d816546.zip
[LoopDeletion] Update exits correctly when multiple duplicate edges from an exiting block
Summary: Currently, we incorrectly update exit blocks of loops when there are multiple edges from a single exiting block to the exit block. This can happen when we have switches as the terminator of the exiting blocks. The fix here is to correctly update the phi nodes in the exit block, and remove all incoming values *except* for one which is from the preheader. Note: Currently, this error can manifest only while deleting non-executed loops. However, it is possible to trigger this error in invariant loops, once we enhance the logic around the exit conditions for the loop check. Reviewers: chandlerc, dberlin, sanjoy, efriedma Reviewed by: efriedma Subscribers: mzolotukhin, llvm-commits Differential Revision: https://reviews.llvm.org/D34516 llvm-svn: 306048
Diffstat (limited to 'llvm/test/Transforms/LoopDeletion')
-rw-r--r--llvm/test/Transforms/LoopDeletion/unreachable-loops.ll76
1 files changed, 76 insertions, 0 deletions
diff --git a/llvm/test/Transforms/LoopDeletion/unreachable-loops.ll b/llvm/test/Transforms/LoopDeletion/unreachable-loops.ll
index 147a8567012..5bdaeb11232 100644
--- a/llvm/test/Transforms/LoopDeletion/unreachable-loops.ll
+++ b/llvm/test/Transforms/LoopDeletion/unreachable-loops.ll
@@ -334,3 +334,79 @@ exit:
ret void
}
+
+; 2 edges from a single exiting block to the exit block.
+define i64 @test12(i64 %n){
+;CHECK-LABEL: @test12
+; CHECK-NOT: L1:
+; CHECK-NOT: L1Latch:
+; CHECK-LABEL: L1.preheader:
+; CHECK-NEXT: br label %exit
+; CHECK-LABEL: exit:
+; CHECK-NEXT: %y.phi = phi i64 [ undef, %L1.preheader ]
+; CHECK-NEXT: ret i64 %y.phi
+
+entry:
+ br i1 true, label %exit1, label %L1
+
+exit1:
+ ret i64 42
+
+L1: ; preds = %L1Latch, %entry
+ %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
+ br i1 true, label %L1Latch, label %exit
+
+L1Latch: ; preds = %L1
+ %y = phi i64 [ %y.next, %L1 ]
+ %y.add = add i64 %y, %n
+ %cond2 = icmp eq i64 %y.add, 42
+ switch i64 %n, label %L1 [
+ i64 10, label %exit
+ i64 20, label %exit
+ ]
+
+exit: ; preds = %L1Latch, %L1Latch
+ %y.phi = phi i64 [ 10, %L1Latch ], [ 10, %L1Latch ], [ %y.next, %L1]
+ ret i64 %y.phi
+}
+
+; multiple edges to exit block from the same exiting blocks
+define i64 @test13(i64 %n) {
+; CHECK-LABEL: @test13
+; CHECK-NOT: L1:
+; CHECK-NOT: L1Latch:
+; CHECK-LABEL: L1.preheader:
+; CHECK-NEXT: br label %exit
+; CHECK-LABEL: exit:
+; CHECK-NEXT: %y.phi = phi i64 [ undef, %L1.preheader ]
+; CHECK-NEXT: ret i64 %y.phi
+
+entry:
+ br i1 true, label %exit1, label %L1
+
+exit1:
+ ret i64 42
+
+L1: ; preds = %L1Latch, %entry
+ %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
+ br i1 true, label %L1Block, label %exit
+
+L1Block: ; preds = %L1
+ %y = phi i64 [ %y.next, %L1 ]
+ %y.add = add i64 %y, %n
+ %cond2 = icmp eq i64 %y.add, 42
+ switch i64 %n, label %L1Latch [
+ i64 10, label %exit
+ i64 20, label %exit
+ ]
+
+L1Latch:
+ switch i64 %n, label %L1 [
+ i64 30, label %exit
+ i64 40, label %exit
+ ]
+
+exit: ; preds = %L1Block, %L1, %L1Latch
+ %y.phi = phi i64 [ 10, %L1Block ], [ 10, %L1Block ], [ %y.next, %L1 ], [ 30, %L1Latch ], [ 30, %L1Latch ]
+ ret i64 %y.phi
+}
OpenPOWER on IntegriCloud