From 9281503e8f7573b09e151c0de89dbcb682b288be Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 2 Jun 2018 01:29:01 +0000 Subject: [PM/LoopUnswitch] Fix how the cloned loops are handled when updating analyses. Summary: I noticed this issue because we didn't put the primary cloned loop into the `NonChildClonedLoops` vector and so never iterated on it. Once I fixed that, it made it clear why I had to do a really complicated and unnecesasry dance when updating the loops to remain in canonical form -- I was unwittingly working around the fact that the primary cloned loop wasn't in the expected list of cloned loops. Doh! Now that we include it in this vector, we don't need to return it and we can consolidate the update logic as we correctly have a single place where it can be handled. I've just added a test for the iteration order aspect as every time I changed the update logic partially or incorrectly here, an existing test failed and caught it so that seems well covered (which is also evidenced by the extensive working around of this missing update). Reviewers: asbirlea, sanjoy Subscribers: mcrosier, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D47647 llvm-svn: 333811 --- .../SimpleLoopUnswitch/nontrivial-unswitch.ll | 101 +++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'llvm/test/Transforms') diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll index 51afdf386e5..1a14bd209d1 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch.ll @@ -2562,3 +2562,104 @@ outer.latch: exit: ret void } + +; Non-trivial loop unswitching where there are two invariant conditions, but the +; second one is only in the cloned copy of the loop after unswitching. +define i32 @test24(i1* %ptr, i1 %cond1, i1 %cond2) { +; CHECK-LABEL: @test24( +entry: + br label %loop_begin +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 %cond1, label %entry.split.us, label %entry.split + +loop_begin: + br i1 %cond1, label %loop_a, label %loop_b + +loop_a: + br i1 %cond2, label %loop_a_a, label %loop_a_c +; The second unswitched condition. +; +; CHECK: entry.split.us: +; CHECK-NEXT: br i1 %cond2, label %entry.split.us.split.us, label %entry.split.us.split + +loop_a_a: + call void @a() + br label %latch +; The 'loop_a_a' unswitched loop. +; +; CHECK: entry.split.us.split.us: +; CHECK-NEXT: br label %loop_begin.us.us +; +; CHECK: loop_begin.us.us: +; CHECK-NEXT: br label %loop_a.us.us +; +; CHECK: loop_a.us.us: +; CHECK-NEXT: br label %loop_a_a.us.us +; +; CHECK: loop_a_a.us.us: +; CHECK-NEXT: call void @a() +; CHECK-NEXT: br label %latch.us.us +; +; CHECK: latch.us.us: +; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr +; CHECK-NEXT: br i1 %[[V]], label %loop_begin.us.us, label %loop_exit.split.us.split.us +; +; CHECK: loop_exit.split.us.split.us: +; CHECK-NEXT: br label %loop_exit.split + +loop_a_c: + call void @c() + br label %latch +; The 'loop_a_c' unswitched loop. +; +; CHECK: entry.split.us.split: +; CHECK-NEXT: br label %loop_begin.us +; +; CHECK: loop_begin.us: +; CHECK-NEXT: br label %loop_a.us +; +; CHECK: loop_a.us: +; CHECK-NEXT: br label %loop_a_c.us +; +; CHECK: loop_a_c.us: +; CHECK-NEXT: call void @c() +; CHECK-NEXT: br label %latch +; +; CHECK: latch.us: +; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr +; CHECK-NEXT: br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us.split +; +; CHECK: loop_exit.split.us.split: +; CHECK-NEXT: br label %loop_exit.split + +loop_b: + call void @b() + br label %latch +; The 'loop_b' unswitched loop. +; +; CHECK: entry.split: +; CHECK-NEXT: br label %loop_begin +; +; CHECK: loop_begin: +; CHECK-NEXT: br label %loop_b +; +; CHECK: loop_b: +; CHECK-NEXT: call void @b() +; CHECK-NEXT: br label %latch +; +; CHECK: latch: +; CHECK-NEXT: %[[V:.*]] = load i1, i1* %ptr +; CHECK-NEXT: br i1 %[[V]], label %loop_begin, label %loop_exit.split +; +; CHECK: loop_exit.split: +; CHECK-NEXT: br label %loop_exit + +latch: + %v = load i1, i1* %ptr + br i1 %v, label %loop_begin, label %loop_exit + +loop_exit: + ret i32 0 +; CHECK: loop_exit: +; CHECK-NEXT: ret +} \ No newline at end of file -- cgit v1.2.3