[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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333811 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth
2018-06-02 01:29:01 +00:00
parent 71a5348666
commit 2aaad36203
2 changed files with 132 additions and 44 deletions
@@ -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
}