1 ; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s
2 ; RUN: opt -verify-memoryssa -passes='loop-mssa(unswitch),verify<loops>' -S < %s | FileCheck %s
4 declare void @some_func() noreturn
5 declare void @sink(i32)
8 declare i32 @cond.i32()
10 ; This test contains two trivial unswitch condition in one loop.
11 ; LoopUnswitch pass should be able to unswitch the second one
12 ; after unswitching the first one.
13 define i32 @test1(i32* %var, i1 %cond1, i1 %cond2) {
14 ; CHECK-LABEL: @test1(
18 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit.split
21 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split.split, label %loop_exit
23 ; CHECK: entry.split.split:
24 ; CHECK-NEXT: br label %loop_begin
27 br i1 %cond1, label %continue, label %loop_exit ; first trivial condition
29 ; CHECK-NEXT: br label %continue
32 %var_val = load i32, i32* %var
33 br i1 %cond2, label %do_something, label %loop_exit ; second trivial condition
36 ; CHECK-NEXT: br label %do_something
39 call void @some_func() noreturn nounwind
41 ; CHECK: do_something:
43 ; CHECK-NEXT: br label %loop_begin
48 ; CHECK-NEXT: br label %loop_exit.split
50 ; CHECK: loop_exit.split:
54 ; Test for two trivially unswitchable switches.
55 define i32 @test3(i32* %var, i32 %cond1, i32 %cond2) {
56 ; CHECK-LABEL: @test3(
60 ; CHECK-NEXT: switch i32 %cond1, label %entry.split [
61 ; CHECK-NEXT: i32 0, label %loop_exit1
65 ; CHECK-NEXT: switch i32 %cond2, label %loop_exit2 [
66 ; CHECK-NEXT: i32 42, label %loop_exit2
67 ; CHECK-NEXT: i32 0, label %entry.split.split
70 ; CHECK: entry.split.split:
71 ; CHECK-NEXT: br label %loop_begin
74 switch i32 %cond1, label %continue [
75 i32 0, label %loop_exit1
78 ; CHECK-NEXT: br label %continue
81 %var_val = load i32, i32* %var
82 switch i32 %cond2, label %loop_exit2 [
83 i32 0, label %do_something
84 i32 42, label %loop_exit2
88 ; CHECK-NEXT: br label %do_something
91 call void @some_func() noreturn nounwind
93 ; CHECK: do_something:
95 ; CHECK-NEXT: br label %loop_begin
107 ; We shouldn't have any unreachable blocks here because the unswitched switches
108 ; turn into branches instead.
109 ; CHECK-NOT: unreachable
112 ; Test for a trivially unswitchable switch with multiple exiting cases and
113 ; multiple looping cases.
114 define i32 @test4(i32* %var, i32 %cond1, i32 %cond2) {
115 ; CHECK-LABEL: @test4(
119 ; CHECK-NEXT: switch i32 %cond2, label %loop_exit2 [
120 ; CHECK-NEXT: i32 13, label %loop_exit1
121 ; CHECK-NEXT: i32 42, label %loop_exit3
122 ; CHECK-NEXT: i32 0, label %entry.split
123 ; CHECK-NEXT: i32 1, label %entry.split
124 ; CHECK-NEXT: i32 2, label %entry.split
127 ; CHECK: entry.split:
128 ; CHECK-NEXT: br label %loop_begin
131 %var_val = load i32, i32* %var
132 switch i32 %cond2, label %loop_exit2 [
135 i32 13, label %loop_exit1
137 i32 42, label %loop_exit3
141 ; CHECK-NEXT: switch i32 %cond2, label %loop2 [
142 ; CHECK-NEXT: i32 0, label %loop0
143 ; CHECK-NEXT: i32 1, label %loop1
147 call void @some_func() noreturn nounwind
151 ; CHECK-NEXT: br label %loop_latch
154 call void @some_func() noreturn nounwind
158 ; CHECK-NEXT: br label %loop_latch
161 call void @some_func() noreturn nounwind
165 ; CHECK-NEXT: br label %loop_latch
170 ; CHECK-NEXT: br label %loop_begin
188 ; This test contains a trivially unswitchable branch with an LCSSA phi node in
190 define i32 @test5(i1 %cond1, i32 %x, i32 %y) {
191 ; CHECK-LABEL: @test5(
195 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit
197 ; CHECK: entry.split:
198 ; CHECK-NEXT: br label %loop_begin
201 br i1 %cond1, label %latch, label %loop_exit
203 ; CHECK-NEXT: br label %latch
206 call void @some_func() noreturn nounwind
210 ; CHECK-NEXT: br label %loop_begin
213 %result1 = phi i32 [ %x, %loop_begin ]
214 %result2 = phi i32 [ %y, %loop_begin ]
215 %result = add i32 %result1, %result2
218 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %x, %entry ]
219 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %y, %entry ]
220 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1]], %[[R2]]
221 ; CHECK-NEXT: ret i32 %[[R]]
224 ; This test contains a trivially unswitchable branch with a real phi node in LCSSA
225 ; position in a shared exit block where a different path through the loop
226 ; produces a non-invariant input to the PHI node.
227 define i32 @test6(i32* %var, i1 %cond1, i1 %cond2, i32 %x, i32 %y) {
228 ; CHECK-LABEL: @test6(
232 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit.split
234 ; CHECK: entry.split:
235 ; CHECK-NEXT: br label %loop_begin
238 br i1 %cond1, label %continue, label %loop_exit
240 ; CHECK-NEXT: br label %continue
243 %var_val = load i32, i32* %var
244 br i1 %cond2, label %latch, label %loop_exit
247 ; CHECK-NEXT: br i1 %cond2, label %latch, label %loop_exit
250 call void @some_func() noreturn nounwind
254 ; CHECK-NEXT: br label %loop_begin
257 %result1 = phi i32 [ %x, %loop_begin ], [ %var_val, %continue ]
258 %result2 = phi i32 [ %var_val, %continue ], [ %y, %loop_begin ]
259 %result = add i32 %result1, %result2
262 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %var_val, %continue ]
263 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %var_val, %continue ]
264 ; CHECK-NEXT: br label %loop_exit.split
266 ; CHECK: loop_exit.split:
267 ; CHECK-NEXT: %[[R1S:.*]] = phi i32 [ %x, %entry ], [ %[[R1]], %loop_exit ]
268 ; CHECK-NEXT: %[[R2S:.*]] = phi i32 [ %y, %entry ], [ %[[R2]], %loop_exit ]
269 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1S]], %[[R2S]]
270 ; CHECK-NEXT: ret i32 %[[R]]
273 ; This test contains a trivially unswitchable switch with an LCSSA phi node in
275 define i32 @test7(i32 %cond1, i32 %x, i32 %y) {
276 ; CHECK-LABEL: @test7(
280 ; CHECK-NEXT: switch i32 %cond1, label %entry.split [
281 ; CHECK-NEXT: i32 0, label %loop_exit
282 ; CHECK-NEXT: i32 1, label %loop_exit
285 ; CHECK: entry.split:
286 ; CHECK-NEXT: br label %loop_begin
289 switch i32 %cond1, label %latch [
290 i32 0, label %loop_exit
291 i32 1, label %loop_exit
294 ; CHECK-NEXT: br label %latch
297 call void @some_func() noreturn nounwind
301 ; CHECK-NEXT: br label %loop_begin
304 %result1 = phi i32 [ %x, %loop_begin ], [ %x, %loop_begin ]
305 %result2 = phi i32 [ %y, %loop_begin ], [ %y, %loop_begin ]
306 %result = add i32 %result1, %result2
309 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %x, %entry ], [ %x, %entry ]
310 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %y, %entry ], [ %y, %entry ]
311 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1]], %[[R2]]
312 ; CHECK-NEXT: ret i32 %[[R]]
315 ; This test contains a trivially unswitchable switch with a real phi node in
316 ; LCSSA position in a shared exit block where a different path through the loop
317 ; produces a non-invariant input to the PHI node.
318 define i32 @test8(i32* %var, i32 %cond1, i32 %cond2, i32 %x, i32 %y) {
319 ; CHECK-LABEL: @test8(
323 ; CHECK-NEXT: switch i32 %cond1, label %entry.split [
324 ; CHECK-NEXT: i32 0, label %loop_exit.split
325 ; CHECK-NEXT: i32 1, label %loop_exit2
326 ; CHECK-NEXT: i32 2, label %loop_exit.split
329 ; CHECK: entry.split:
330 ; CHECK-NEXT: br label %loop_begin
333 switch i32 %cond1, label %continue [
334 i32 0, label %loop_exit
335 i32 1, label %loop_exit2
336 i32 2, label %loop_exit
339 ; CHECK-NEXT: br label %continue
342 %var_val = load i32, i32* %var
343 switch i32 %cond2, label %latch [
344 i32 0, label %loop_exit
348 ; CHECK-NEXT: switch i32 %cond2, label %latch [
349 ; CHECK-NEXT: i32 0, label %loop_exit
353 call void @some_func() noreturn nounwind
357 ; CHECK-NEXT: br label %loop_begin
360 %result1.1 = phi i32 [ %x, %loop_begin ], [ %x, %loop_begin ], [ %var_val, %continue ]
361 %result1.2 = phi i32 [ %var_val, %continue ], [ %y, %loop_begin ], [ %y, %loop_begin ]
362 %result1 = add i32 %result1.1, %result1.2
365 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %var_val, %continue ]
366 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %var_val, %continue ]
367 ; CHECK-NEXT: br label %loop_exit.split
369 ; CHECK: loop_exit.split:
370 ; CHECK-NEXT: %[[R1S:.*]] = phi i32 [ %x, %entry ], [ %x, %entry ], [ %[[R1]], %loop_exit ]
371 ; CHECK-NEXT: %[[R2S:.*]] = phi i32 [ %y, %entry ], [ %y, %entry ], [ %[[R2]], %loop_exit ]
372 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1S]], %[[R2S]]
373 ; CHECK-NEXT: ret i32 %[[R]]
376 %result2.1 = phi i32 [ %x, %loop_begin ]
377 %result2.2 = phi i32 [ %y, %loop_begin ]
378 %result2 = add i32 %result2.1, %result2.2
381 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %x, %entry ]
382 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %y, %entry ]
383 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1]], %[[R2]]
384 ; CHECK-NEXT: ret i32 %[[R]]
387 ; This test, extracted from the LLVM test suite, has an interesting dominator
388 ; tree to update as there are edges to sibling domtree nodes within child
389 ; domtree nodes of the unswitched node.
390 define void @xgets(i1 %cond1, i1* %cond2.ptr) {
391 ; CHECK-LABEL: @xgets(
393 br label %for.cond.preheader
395 ; CHECK-NEXT: br label %for.cond.preheader
399 ; CHECK: for.cond.preheader:
400 ; CHECK-NEXT: br i1 %cond1, label %for.cond.preheader.split, label %if.end17.thread.loopexit
402 ; CHECK: for.cond.preheader.split:
403 ; CHECK-NEXT: br label %for.cond
406 br i1 %cond1, label %land.lhs.true, label %if.end17.thread.loopexit
408 ; CHECK-NEXT: br label %land.lhs.true
412 ; CHECK: land.lhs.true:
413 ; CHECK-NEXT: br label %if.then20
416 %cond2 = load volatile i1, i1* %cond2.ptr
417 br i1 %cond2, label %if.then23, label %if.else
419 ; CHECK-NEXT: %[[COND2:.*]] = load volatile i1, i1* %cond2.ptr
420 ; CHECK-NEXT: br i1 %[[COND2]], label %if.then23, label %if.else
425 ; CHECK-NEXT: br label %for.cond
427 if.end17.thread.loopexit:
428 br label %if.end17.thread
429 ; CHECK: if.end17.thread.loopexit:
430 ; CHECK-NEXT: br label %if.end17.thread
434 ; CHECK: if.end17.thread:
435 ; CHECK-NEXT: br label %cleanup
440 ; CHECK-NEXT: br label %cleanup
445 ; CHECK-NEXT: ret void
448 define i32 @test_partial_condition_unswitch_and(i32* %var, i1 %cond1, i1 %cond2) {
449 ; CHECK-LABEL: @test_partial_condition_unswitch_and(
453 ; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split
455 ; CHECK: entry.split:
456 ; CHECK-NEXT: br i1 %cond2, label %entry.split.split, label %loop_exit
458 ; CHECK: entry.split.split:
459 ; CHECK-NEXT: br label %loop_begin
462 br i1 %cond1, label %continue, label %loop_exit
464 ; CHECK-NEXT: br label %continue
467 %var_val = load i32, i32* %var
468 %var_cond = trunc i32 %var_val to i1
469 %cond_and = and i1 %var_cond, %cond2
470 br i1 %cond_and, label %do_something, label %loop_exit
472 ; CHECK-NEXT: %[[VAR:.*]] = load i32
473 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
474 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true
475 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
478 call void @some_func() noreturn nounwind
480 ; CHECK: do_something:
482 ; CHECK-NEXT: br label %loop_begin
487 ; CHECK-NEXT: br label %loop_exit.split
489 ; CHECK: loop_exit.split:
493 define i32 @test_partial_condition_unswitch_or(i32* %var, i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4, i1 %cond5, i1 %cond6) {
494 ; CHECK-LABEL: @test_partial_condition_unswitch_or(
498 ; CHECK-NEXT: %[[INV_OR1:.*]] = or i1 %cond4, %cond2
499 ; CHECK-NEXT: %[[INV_OR2:.*]] = or i1 %[[INV_OR1]], %cond3
500 ; CHECK-NEXT: %[[INV_OR3:.*]] = or i1 %[[INV_OR2]], %cond1
501 ; CHECK-NEXT: br i1 %[[INV_OR3]], label %loop_exit.split, label %entry.split
503 ; CHECK: entry.split:
504 ; CHECK-NEXT: br label %loop_begin
507 %var_val = load i32, i32* %var
508 %var_cond = trunc i32 %var_val to i1
509 %cond_or1 = or i1 %var_cond, %cond1
510 %cond_or2 = or i1 %cond2, %cond3
511 %cond_or3 = or i1 %cond_or1, %cond_or2
512 %cond_xor1 = xor i1 %cond5, %var_cond
513 %cond_and1 = and i1 %cond6, %var_cond
514 %cond_or4 = or i1 %cond_xor1, %cond_and1
515 %cond_or5 = or i1 %cond_or3, %cond_or4
516 %cond_or6 = or i1 %cond_or5, %cond4
517 br i1 %cond_or6, label %loop_exit, label %do_something
519 ; CHECK-NEXT: %[[VAR:.*]] = load i32
520 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
521 ; CHECK-NEXT: %[[COND_OR1:.*]] = or i1 %[[VAR_COND]], false
522 ; CHECK-NEXT: %[[COND_OR2:.*]] = or i1 false, false
523 ; CHECK-NEXT: %[[COND_OR3:.*]] = or i1 %[[COND_OR1]], %[[COND_OR2]]
524 ; CHECK-NEXT: %[[COND_XOR:.*]] = xor i1 %cond5, %[[VAR_COND]]
525 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %cond6, %[[VAR_COND]]
526 ; CHECK-NEXT: %[[COND_OR4:.*]] = or i1 %[[COND_XOR]], %[[COND_AND]]
527 ; CHECK-NEXT: %[[COND_OR5:.*]] = or i1 %[[COND_OR3]], %[[COND_OR4]]
528 ; CHECK-NEXT: %[[COND_OR6:.*]] = or i1 %[[COND_OR5]], false
529 ; CHECK-NEXT: br i1 %[[COND_OR6]], label %loop_exit, label %do_something
532 call void @some_func() noreturn nounwind
534 ; CHECK: do_something:
536 ; CHECK-NEXT: br label %loop_begin
540 ; CHECK: loop_exit.split:
544 define i32 @test_partial_condition_unswitch_with_lcssa_phi1(i32* %var, i1 %cond, i32 %x) {
545 ; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi1(
549 ; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split
551 ; CHECK: entry.split:
552 ; CHECK-NEXT: br label %loop_begin
555 %var_val = load i32, i32* %var
556 %var_cond = trunc i32 %var_val to i1
557 %cond_and = and i1 %var_cond, %cond
558 br i1 %cond_and, label %do_something, label %loop_exit
560 ; CHECK-NEXT: %[[VAR:.*]] = load i32
561 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
562 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true
563 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
566 call void @some_func() noreturn nounwind
568 ; CHECK: do_something:
570 ; CHECK-NEXT: br label %loop_begin
573 %x.lcssa = phi i32 [ %x, %loop_begin ]
576 ; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ]
577 ; CHECK-NEXT: br label %loop_exit.split
579 ; CHECK: loop_exit.split:
580 ; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ]
581 ; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]]
584 define i32 @test_partial_condition_unswitch_with_lcssa_phi2(i32* %var, i1 %cond, i32 %x, i32 %y) {
585 ; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi2(
589 ; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split
591 ; CHECK: entry.split:
592 ; CHECK-NEXT: br label %loop_begin
595 %var_val = load i32, i32* %var
596 %var_cond = trunc i32 %var_val to i1
597 %cond_and = and i1 %var_cond, %cond
598 br i1 %cond_and, label %do_something, label %loop_exit
600 ; CHECK-NEXT: %[[VAR:.*]] = load i32
601 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
602 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true
603 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
606 call void @some_func() noreturn nounwind
607 br i1 %var_cond, label %loop_begin, label %loop_exit
608 ; CHECK: do_something:
610 ; CHECK-NEXT: br i1 %[[VAR_COND]], label %loop_begin, label %loop_exit
613 %xy.lcssa = phi i32 [ %x, %loop_begin ], [ %y, %do_something ]
616 ; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ], [ %y, %do_something ]
617 ; CHECK-NEXT: br label %loop_exit.split
619 ; CHECK: loop_exit.split:
620 ; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ]
621 ; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]]
624 ; Unswitch will not actually change the loop nest from:
626 define void @hoist_inner_loop0() {
627 ; CHECK-LABEL: define void @hoist_inner_loop0(
631 ; CHECK-NEXT: br label %a.header
636 ; CHECK-NEXT: br label %b.header
639 %v1 = call i1 @cond()
642 ; CHECK-NEXT: %v1 = call i1 @cond()
643 ; CHECK-NEXT: br i1 %v1, label %[[B_LATCH_SPLIT:.*]], label %[[B_HEADER_SPLIT:.*]]
645 ; CHECK: [[B_HEADER_SPLIT]]:
646 ; CHECK-NEXT: br label %c.header
649 br i1 %v1, label %b.latch, label %c.latch
651 ; CHECK-NEXT: br label %c.latch
654 %v2 = call i1 @cond()
655 br i1 %v2, label %c.header, label %b.latch
657 ; CHECK-NEXT: %v2 = call i1 @cond()
658 ; CHECK-NEXT: br i1 %v2, label %c.header, label %b.latch
661 %v3 = call i1 @cond()
662 br i1 %v3, label %b.header, label %a.latch
664 ; CHECK-NEXT: br label %[[B_LATCH_SPLIT]]
666 ; CHECK: [[B_LATCH_SPLIT]]:
667 ; CHECK-NEXT: %v3 = call i1 @cond()
668 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
673 ; CHECK-NEXT: br label %a.header
678 ; CHECK-NEXT: ret void
681 ; Unswitch will transform the loop nest from:
685 define void @hoist_inner_loop1(i32* %ptr) {
686 ; CHECK-LABEL: define void @hoist_inner_loop1(
690 ; CHECK-NEXT: br label %a.header
693 %x.a = load i32, i32* %ptr
696 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
697 ; CHECK-NEXT: br label %b.header
700 %x.b = load i32, i32* %ptr
701 %v1 = call i1 @cond()
704 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
705 ; CHECK-NEXT: %v1 = call i1 @cond()
706 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
708 ; CHECK: [[B_HEADER_SPLIT]]:
709 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
710 ; CHECK-NEXT: br label %c.header
713 br i1 %v1, label %b.latch, label %c.latch
715 ; CHECK-NEXT: br label %c.latch
718 ; Use values from other loops to check LCSSA form.
719 store i32 %x.a, i32* %ptr
720 store i32 %x.b, i32* %ptr
721 %v2 = call i1 @cond()
722 br i1 %v2, label %c.header, label %a.exit.c
724 ; CHECK-NEXT: store i32 %x.a, i32* %ptr
725 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
726 ; CHECK-NEXT: %v2 = call i1 @cond()
727 ; CHECK-NEXT: br i1 %v2, label %c.header, label %a.exit.c
730 %v3 = call i1 @cond()
731 br i1 %v3, label %b.header, label %a.exit.b
733 ; CHECK-NEXT: %v3 = call i1 @cond()
734 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.exit.b
739 ; CHECK-NEXT: br label %a.latch
744 ; CHECK-NEXT: br label %a.latch
749 ; CHECK-NEXT: br label %a.header
754 ; CHECK-NEXT: ret void
757 ; Unswitch will transform the loop nest from:
761 define void @hoist_inner_loop2(i32* %ptr) {
762 ; CHECK-LABEL: define void @hoist_inner_loop2(
766 ; CHECK-NEXT: br label %a.header
769 %x.a = load i32, i32* %ptr
772 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
773 ; CHECK-NEXT: br label %b.header
776 %x.b = load i32, i32* %ptr
777 %v1 = call i1 @cond()
780 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
781 ; CHECK-NEXT: %v1 = call i1 @cond()
782 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
784 ; CHECK: [[B_HEADER_SPLIT]]:
785 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
786 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
787 ; CHECK-NEXT: br label %c.header
790 br i1 %v1, label %b.latch, label %c.latch
792 ; CHECK-NEXT: br label %c.latch
795 ; Use values from other loops to check LCSSA form.
796 store i32 %x.a, i32* %ptr
797 store i32 %x.b, i32* %ptr
798 %v2 = call i1 @cond()
799 br i1 %v2, label %c.header, label %exit
801 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
802 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
803 ; CHECK-NEXT: %v2 = call i1 @cond()
804 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
807 %v3 = call i1 @cond()
808 br i1 %v3, label %b.header, label %a.latch
810 ; CHECK-NEXT: %v3 = call i1 @cond()
811 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
816 ; CHECK-NEXT: br label %a.header
821 ; CHECK-NEXT: ret void
824 ; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.
825 ; Unswitch will transform the loop nest from:
829 define void @hoist_inner_loop3(i32* %ptr) {
830 ; CHECK-LABEL: define void @hoist_inner_loop3(
834 ; CHECK-NEXT: br label %a.header
837 %x.a = load i32, i32* %ptr
840 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
841 ; CHECK-NEXT: br label %b.header
844 %x.b = load i32, i32* %ptr
845 %v1 = call i1 @cond()
848 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
849 ; CHECK-NEXT: %v1 = call i1 @cond()
850 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
852 ; CHECK: [[B_HEADER_SPLIT]]:
853 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
854 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
855 ; CHECK-NEXT: br label %c.header
858 br i1 %v1, label %b.latch, label %c.body
860 ; CHECK-NEXT: br label %c.body
863 %x.c = load i32, i32* %ptr
866 ; CHECK-NEXT: %x.c = load i32, i32* %ptr
867 ; CHECK-NEXT: br label %d.header
870 ; Use values from other loops to check LCSSA form.
871 store i32 %x.a, i32* %ptr
872 store i32 %x.b, i32* %ptr
873 store i32 %x.c, i32* %ptr
874 %v2 = call i1 @cond()
875 br i1 %v2, label %d.header, label %c.latch
877 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
878 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
879 ; CHECK-NEXT: store i32 %x.c, i32* %ptr
880 ; CHECK-NEXT: %v2 = call i1 @cond()
881 ; CHECK-NEXT: br i1 %v2, label %d.header, label %c.latch
884 %v3 = call i1 @cond()
885 br i1 %v3, label %c.header, label %exit
887 ; CHECK-NEXT: %v3 = call i1 @cond()
888 ; CHECK-NEXT: br i1 %v3, label %c.header, label %exit
891 %v4 = call i1 @cond()
892 br i1 %v4, label %b.header, label %a.latch
894 ; CHECK-NEXT: %v4 = call i1 @cond()
895 ; CHECK-NEXT: br i1 %v4, label %b.header, label %a.latch
900 ; CHECK-NEXT: br label %a.header
905 ; CHECK-NEXT: ret void
908 ; This test is designed to exercise checking multiple remaining exits from the
909 ; loop being unswitched.
910 ; Unswitch will transform the loop nest from:
914 define void @hoist_inner_loop4() {
915 ; CHECK-LABEL: define void @hoist_inner_loop4(
919 ; CHECK-NEXT: br label %a.header
924 ; CHECK-NEXT: br label %b.header
929 ; CHECK-NEXT: br label %c.header
932 %v1 = call i1 @cond()
935 ; CHECK-NEXT: %v1 = call i1 @cond()
936 ; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT:.*]], label %c.latch
938 ; CHECK: [[C_HEADER_SPLIT]]:
939 ; CHECK-NEXT: br label %d.header
942 br i1 %v1, label %d.exiting1, label %c.latch
944 ; CHECK-NEXT: br label %d.exiting1
947 %v2 = call i1 @cond()
948 br i1 %v2, label %d.exiting2, label %a.latch
950 ; CHECK-NEXT: %v2 = call i1 @cond()
951 ; CHECK-NEXT: br i1 %v2, label %d.exiting2, label %a.latch
954 %v3 = call i1 @cond()
955 br i1 %v3, label %d.exiting3, label %loopexit.d
957 ; CHECK-NEXT: %v3 = call i1 @cond()
958 ; CHECK-NEXT: br i1 %v3, label %d.exiting3, label %loopexit.d
961 %v4 = call i1 @cond()
962 br i1 %v4, label %d.latch, label %b.latch
964 ; CHECK-NEXT: %v4 = call i1 @cond()
965 ; CHECK-NEXT: br i1 %v4, label %d.latch, label %b.latch
970 ; CHECK-NEXT: br label %d.header
973 %v5 = call i1 @cond()
974 br i1 %v5, label %c.header, label %loopexit.c
976 ; CHECK-NEXT: %v5 = call i1 @cond()
977 ; CHECK-NEXT: br i1 %v5, label %c.header, label %loopexit.c
982 ; CHECK-NEXT: br label %b.header
987 ; CHECK-NEXT: br label %a.header
992 ; CHECK-NEXT: br label %exit
997 ; CHECK-NEXT: br label %exit
1002 ; CHECK-NEXT: ret void
1005 ; Unswitch will transform the loop nest from:
1009 define void @hoist_inner_loop5(i32* %ptr) {
1010 ; CHECK-LABEL: define void @hoist_inner_loop5(
1014 ; CHECK-NEXT: br label %a.header
1017 %x.a = load i32, i32* %ptr
1020 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
1021 ; CHECK-NEXT: br label %b.header
1024 %x.b = load i32, i32* %ptr
1027 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
1028 ; CHECK-NEXT: br label %c.header
1031 %x.c = load i32, i32* %ptr
1032 %v1 = call i1 @cond()
1035 ; CHECK-NEXT: %x.c = load i32, i32* %ptr
1036 ; CHECK-NEXT: %v1 = call i1 @cond()
1037 ; CHECK-NEXT: br i1 %v1, label %c.latch, label %[[C_HEADER_SPLIT:.*]]
1039 ; CHECK: [[C_HEADER_SPLIT]]:
1040 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %c.header ]
1041 ; CHECK-NEXT: %[[X_C_LCSSA:.*]] = phi i32 [ %x.c, %c.header ]
1042 ; CHECK-NEXT: br label %d.header
1045 br i1 %v1, label %c.latch, label %d.latch
1047 ; CHECK-NEXT: br label %d.latch
1050 ; Use values from other loops to check LCSSA form.
1051 store i32 %x.a, i32* %ptr
1052 store i32 %x.b, i32* %ptr
1053 store i32 %x.c, i32* %ptr
1054 %v2 = call i1 @cond()
1055 br i1 %v2, label %d.header, label %a.latch
1057 ; CHECK-NEXT: store i32 %x.a, i32* %ptr
1058 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
1059 ; CHECK-NEXT: store i32 %[[X_C_LCSSA]], i32* %ptr
1060 ; CHECK-NEXT: %v2 = call i1 @cond()
1061 ; CHECK-NEXT: br i1 %v2, label %d.header, label %a.latch
1064 %v3 = call i1 @cond()
1065 br i1 %v3, label %c.header, label %b.latch
1067 ; CHECK-NEXT: %v3 = call i1 @cond()
1068 ; CHECK-NEXT: br i1 %v3, label %c.header, label %b.latch
1073 ; CHECK-NEXT: br label %b.header
1078 ; CHECK-NEXT: br label %a.header
1083 ; CHECK-NEXT: ret void
1086 ; Same as `@hoist_inner_loop2` but using a switch.
1087 ; Unswitch will transform the loop nest from:
1091 define void @hoist_inner_loop_switch(i32* %ptr) {
1092 ; CHECK-LABEL: define void @hoist_inner_loop_switch(
1096 ; CHECK-NEXT: br label %a.header
1099 %x.a = load i32, i32* %ptr
1102 ; CHECK-NEXT: %x.a = load i32, i32* %ptr
1103 ; CHECK-NEXT: br label %b.header
1106 %x.b = load i32, i32* %ptr
1107 %v1 = call i32 @cond.i32()
1110 ; CHECK-NEXT: %x.b = load i32, i32* %ptr
1111 ; CHECK-NEXT: %v1 = call i32 @cond.i32()
1112 ; CHECK-NEXT: switch i32 %v1, label %[[B_HEADER_SPLIT:.*]] [
1113 ; CHECK-NEXT: i32 1, label %b.latch
1114 ; CHECK-NEXT: i32 2, label %b.latch
1115 ; CHECK-NEXT: i32 3, label %b.latch
1118 ; CHECK: [[B_HEADER_SPLIT]]:
1119 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
1120 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
1121 ; CHECK-NEXT: br label %c.header
1124 switch i32 %v1, label %c.latch [
1125 i32 1, label %b.latch
1126 i32 2, label %b.latch
1127 i32 3, label %b.latch
1130 ; CHECK-NEXT: br label %c.latch
1133 ; Use values from other loops to check LCSSA form.
1134 store i32 %x.a, i32* %ptr
1135 store i32 %x.b, i32* %ptr
1136 %v2 = call i1 @cond()
1137 br i1 %v2, label %c.header, label %exit
1139 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr
1140 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr
1141 ; CHECK-NEXT: %v2 = call i1 @cond()
1142 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
1145 %v3 = call i1 @cond()
1146 br i1 %v3, label %b.header, label %a.latch
1148 ; CHECK-NEXT: %v3 = call i1 @cond()
1149 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
1154 ; CHECK-NEXT: br label %a.header
1159 ; CHECK-NEXT: ret void
1162 define void @test_unswitch_to_common_succ_with_phis(i32* %var, i32 %cond) {
1163 ; CHECK-LABEL: @test_unswitch_to_common_succ_with_phis(
1166 ; CHECK-NEXT: entry:
1167 ; CHECK-NEXT: switch i32 %cond, label %loopexit1 [
1168 ; CHECK-NEXT: i32 13, label %loopexit2
1169 ; CHECK-NEXT: i32 0, label %entry.split
1170 ; CHECK-NEXT: i32 1, label %entry.split
1173 ; CHECK: entry.split:
1174 ; CHECK-NEXT: br label %header
1177 %var_val = load i32, i32* %var
1178 switch i32 %cond, label %loopexit1 [
1181 i32 13, label %loopexit2
1185 ; CHECK-NEXT: br label %latch
1188 ; No-op PHI node to exercise weird PHI update scenarios.
1189 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ]
1190 call void @sink(i32 %phi)
1193 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ]
1194 ; CHECK-NEXT: call void @sink(i32 %[[PHI]])
1195 ; CHECK-NEXT: br label %header
1208 define void @test_unswitch_to_default_common_succ_with_phis(i32* %var, i32 %cond) {
1209 ; CHECK-LABEL: @test_unswitch_to_default_common_succ_with_phis(
1212 ; CHECK-NEXT: entry:
1213 ; CHECK-NEXT: switch i32 %cond, label %entry.split [
1214 ; CHECK-NEXT: i32 13, label %loopexit
1217 ; CHECK: entry.split:
1218 ; CHECK-NEXT: br label %header
1221 %var_val = load i32, i32* %var
1222 switch i32 %cond, label %latch [
1225 i32 13, label %loopexit
1229 ; CHECK-NEXT: br label %latch
1232 ; No-op PHI node to exercise weird PHI update scenarios.
1233 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ], [ %var_val, %header ]
1234 call void @sink(i32 %phi)
1237 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ]
1238 ; CHECK-NEXT: call void @sink(i32 %[[PHI]])
1239 ; CHECK-NEXT: br label %header