1 ; RUN: opt -passes='loop(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s
2 ; RUN: opt -verify-memoryssa -passes='loop-mssa(simple-loop-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(ptr %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, ptr %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(ptr %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, ptr %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(ptr %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, ptr %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(ptr %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, ptr %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(ptr %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, ptr %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, ptr %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, ptr %cond2.ptr
417 br i1 %cond2, label %if.then23, label %if.else
419 ; CHECK-NEXT: %[[COND2:.*]] = load volatile i1, ptr %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(ptr %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: [[FROZEN:%.+]] = freeze i1 %cond2
457 ; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split.split, label %loop_exit
459 ; CHECK: entry.split.split:
460 ; CHECK-NEXT: br label %loop_begin
463 br i1 %cond1, label %continue, label %loop_exit
465 ; CHECK-NEXT: br label %continue
468 %var_val = load i32, ptr %var
469 %var_cond = trunc i32 %var_val to i1
470 %cond_and = and i1 %var_cond, %cond2
471 br i1 %cond_and, label %do_something, label %loop_exit
473 ; CHECK-NEXT: %[[VAR:.*]] = load i32
474 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
475 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true
476 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
479 call void @some_func() noreturn nounwind
481 ; CHECK: do_something:
483 ; CHECK-NEXT: br label %loop_begin
488 ; CHECK-NEXT: br label %loop_exit.split
490 ; CHECK: loop_exit.split:
494 define i32 @test_partial_condition_unswitch_and_select(ptr %var, i1 %cond1, i1 %cond2) {
495 ; CHECK-LABEL: @test_partial_condition_unswitch_and_select(
499 ; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split
501 ; CHECK: entry.split:
502 ; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2
503 ; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split.split, label %loop_exit
505 ; CHECK: entry.split.split:
506 ; CHECK-NEXT: br label %loop_begin
509 br i1 %cond1, label %continue, label %loop_exit
511 ; CHECK-NEXT: br label %continue
514 %var_val = load i32, ptr %var
515 %var_cond = trunc i32 %var_val to i1
516 %cond_and = select i1 %var_cond, i1 %cond2, i1 false
517 br i1 %cond_and, label %do_something, label %loop_exit
519 ; CHECK-NEXT: %[[VAR:.*]] = load i32
520 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
521 ; CHECK-NEXT: %[[COND_AND:.*]] = select i1 %[[VAR_COND]], i1 true, i1 false
522 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
525 call void @some_func() noreturn nounwind
527 ; CHECK: do_something:
529 ; CHECK-NEXT: br label %loop_begin
534 ; CHECK-NEXT: br label %loop_exit.split
536 ; CHECK: loop_exit.split:
540 define i32 @test_partial_condition_unswitch_or_simple_select(ptr %var, i1 %cond1, i1 %cond2) {
541 ; CHECK-LABEL: @test_partial_condition_unswitch_or_simple_select(
545 ; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split
547 ; CHECK: entry.split:
548 ; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2
549 ; CHECK-NEXT: br i1 [[FROZEN]], label %loop_exit.split1, label %entry.split.split
551 ; CHECK: entry.split.split:
552 ; CHECK-NEXT: br label %loop_begin
555 br i1 %cond1, label %continue, label %loop_exit
557 ; CHECK-NEXT: br label %continue
560 %var_val = load i32, ptr %var
561 %var_cond = trunc i32 %var_val to i1
562 %cond_or = select i1 %var_cond, i1 true, i1 %cond2
563 br i1 %cond_or, label %loop_exit, label %do_something
565 ; CHECK-NEXT: %[[VAR:.*]] = load i32
566 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
567 ; CHECK-NEXT: %[[COND_OR:.*]] = select i1 %[[VAR_COND]], i1 true, i1 false
568 ; CHECK-NEXT: br i1 %[[COND_OR]], label %loop_exit, label %do_something
571 call void @some_func() noreturn nounwind
573 ; CHECK: do_something:
575 ; CHECK-NEXT: br label %loop_begin
580 ; CHECK-NEXT: br label %loop_exit.split1
582 ; CHECK: loop_exit.split1:
583 ; CHECK-NEXT: br label %loop_exit.split
585 ; CHECK: loop_exit.split:
589 define i32 @test_partial_condition_unswitch_or(ptr %var, i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4, i1 %cond5, i1 %cond6) {
590 ; CHECK-LABEL: @test_partial_condition_unswitch_or(
594 ; CHECK-NEXT: %[[C4_FR:.+]] = freeze i1 %cond4
595 ; CHECK-NEXT: %[[C2_FR:.+]] = freeze i1 %cond2
596 ; CHECK-NEXT: %[[C3_FR:.+]] = freeze i1 %cond3
597 ; CHECK-NEXT: %[[C1_FR:.+]] = freeze i1 %cond1
598 ; CHECK-NEXT: %[[INV_OR1:.*]] = or i1 %[[C4_FR]], %[[C2_FR]]
599 ; CHECK-NEXT: %[[INV_OR2:.*]] = or i1 %[[INV_OR1]], %[[C3_FR]]
600 ; CHECK-NEXT: %[[INV_OR3:.*]] = or i1 %[[INV_OR2]], %[[C1_FR]]
601 ; CHECK-NEXT: br i1 %[[INV_OR3]], label %loop_exit.split, label %entry.split
603 ; CHECK: entry.split:
604 ; CHECK-NEXT: br label %loop_begin
607 %var_val = load i32, ptr %var
608 %var_cond = trunc i32 %var_val to i1
609 %cond_or1 = or i1 %var_cond, %cond1
610 %cond_or2 = or i1 %cond2, %cond3
611 %cond_or3 = or i1 %cond_or1, %cond_or2
612 %cond_xor1 = xor i1 %cond5, %var_cond
613 %cond_and1 = and i1 %cond6, %var_cond
614 %cond_or4 = or i1 %cond_xor1, %cond_and1
615 %cond_or5 = or i1 %cond_or3, %cond_or4
616 %cond_or6 = or i1 %cond_or5, %cond4
617 br i1 %cond_or6, label %loop_exit, label %do_something
619 ; CHECK-NEXT: %[[VAR:.*]] = load i32
620 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
621 ; CHECK-NEXT: %[[COND_OR1:.*]] = or i1 %[[VAR_COND]], false
622 ; CHECK-NEXT: %[[COND_OR2:.*]] = or i1 false, false
623 ; CHECK-NEXT: %[[COND_OR3:.*]] = or i1 %[[COND_OR1]], %[[COND_OR2]]
624 ; CHECK-NEXT: %[[COND_XOR:.*]] = xor i1 %cond5, %[[VAR_COND]]
625 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %cond6, %[[VAR_COND]]
626 ; CHECK-NEXT: %[[COND_OR4:.*]] = or i1 %[[COND_XOR]], %[[COND_AND]]
627 ; CHECK-NEXT: %[[COND_OR5:.*]] = or i1 %[[COND_OR3]], %[[COND_OR4]]
628 ; CHECK-NEXT: %[[COND_OR6:.*]] = or i1 %[[COND_OR5]], false
629 ; CHECK-NEXT: br i1 %[[COND_OR6]], label %loop_exit, label %do_something
632 call void @some_func() noreturn nounwind
634 ; CHECK: do_something:
636 ; CHECK-NEXT: br label %loop_begin
640 ; CHECK: loop_exit.split:
644 define i32 @test_partial_condition_unswitch_with_lcssa_phi1(ptr %var, i1 %cond, i32 %x) {
645 ; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi1(
649 ; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond
650 ; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split, label %loop_exit.split
652 ; CHECK: entry.split:
653 ; CHECK-NEXT: br label %loop_begin
656 %var_val = load i32, ptr %var
657 %var_cond = trunc i32 %var_val to i1
658 %cond_and = and i1 %var_cond, %cond
659 br i1 %cond_and, label %do_something, label %loop_exit
661 ; CHECK-NEXT: %[[VAR:.*]] = load i32
662 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
663 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true
664 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
667 call void @some_func() noreturn nounwind
669 ; CHECK: do_something:
671 ; CHECK-NEXT: br label %loop_begin
674 %x.lcssa = phi i32 [ %x, %loop_begin ]
677 ; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ]
678 ; CHECK-NEXT: br label %loop_exit.split
680 ; CHECK: loop_exit.split:
681 ; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ]
682 ; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]]
685 define i32 @test_partial_condition_unswitch_with_lcssa_phi2(ptr %var, i1 %cond, i32 %x, i32 %y) {
686 ; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi2(
690 ; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond
691 ; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split, label %loop_exit.split
693 ; CHECK: entry.split:
694 ; CHECK-NEXT: br label %loop_begin
697 %var_val = load i32, ptr %var
698 %var_cond = trunc i32 %var_val to i1
699 %cond_and = and i1 %var_cond, %cond
700 br i1 %cond_and, label %do_something, label %loop_exit
702 ; CHECK-NEXT: %[[VAR:.*]] = load i32
703 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1
704 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true
705 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit
708 call void @some_func() noreturn nounwind
709 br i1 %var_cond, label %loop_begin, label %loop_exit
710 ; CHECK: do_something:
712 ; CHECK-NEXT: br i1 %[[VAR_COND]], label %loop_begin, label %loop_exit
715 %xy.lcssa = phi i32 [ %x, %loop_begin ], [ %y, %do_something ]
718 ; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ], [ %y, %do_something ]
719 ; CHECK-NEXT: br label %loop_exit.split
721 ; CHECK: loop_exit.split:
722 ; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ]
723 ; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]]
726 ; Unswitch will not actually change the loop nest from:
728 define void @hoist_inner_loop0() {
729 ; CHECK-LABEL: define void @hoist_inner_loop0(
733 ; CHECK-NEXT: br label %a.header
738 ; CHECK-NEXT: br label %b.header
741 %v1 = call i1 @cond()
744 ; CHECK-NEXT: %v1 = call i1 @cond()
745 ; CHECK-NEXT: br i1 %v1, label %[[B_LATCH_SPLIT:.*]], label %[[B_HEADER_SPLIT:.*]]
747 ; CHECK: [[B_HEADER_SPLIT]]:
748 ; CHECK-NEXT: br label %c.header
751 br i1 %v1, label %b.latch, label %c.latch
753 ; CHECK-NEXT: br label %c.latch
756 %v2 = call i1 @cond()
757 br i1 %v2, label %c.header, label %b.latch
759 ; CHECK-NEXT: %v2 = call i1 @cond()
760 ; CHECK-NEXT: br i1 %v2, label %c.header, label %b.latch
763 %v3 = call i1 @cond()
764 br i1 %v3, label %b.header, label %a.latch
766 ; CHECK-NEXT: br label %[[B_LATCH_SPLIT]]
768 ; CHECK: [[B_LATCH_SPLIT]]:
769 ; CHECK-NEXT: %v3 = call i1 @cond()
770 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
775 ; CHECK-NEXT: br label %a.header
780 ; CHECK-NEXT: ret void
783 ; Unswitch will transform the loop nest from:
787 define void @hoist_inner_loop1(ptr %ptr) {
788 ; CHECK-LABEL: define void @hoist_inner_loop1(
792 ; CHECK-NEXT: br label %a.header
795 %x.a = load i32, ptr %ptr
798 ; CHECK-NEXT: %x.a = load i32, ptr %ptr
799 ; CHECK-NEXT: br label %b.header
802 %x.b = load i32, ptr %ptr
803 %v1 = call i1 @cond()
806 ; CHECK-NEXT: %x.b = load i32, ptr %ptr
807 ; CHECK-NEXT: %v1 = call i1 @cond()
808 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
810 ; CHECK: [[B_HEADER_SPLIT]]:
811 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
812 ; CHECK-NEXT: br label %c.header
815 br i1 %v1, label %b.latch, label %c.latch
817 ; CHECK-NEXT: br label %c.latch
820 ; Use values from other loops to check LCSSA form.
821 store i32 %x.a, ptr %ptr
822 store i32 %x.b, ptr %ptr
823 %v2 = call i1 @cond()
824 br i1 %v2, label %c.header, label %a.exit.c
826 ; CHECK-NEXT: store i32 %x.a, ptr %ptr
827 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr
828 ; CHECK-NEXT: %v2 = call i1 @cond()
829 ; CHECK-NEXT: br i1 %v2, label %c.header, label %a.exit.c
832 %v3 = call i1 @cond()
833 br i1 %v3, label %b.header, label %a.exit.b
835 ; CHECK-NEXT: %v3 = call i1 @cond()
836 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.exit.b
841 ; CHECK-NEXT: br label %a.latch
846 ; CHECK-NEXT: br label %a.latch
851 ; CHECK-NEXT: br label %a.header
856 ; CHECK-NEXT: ret void
859 ; Unswitch will transform the loop nest from:
863 define void @hoist_inner_loop2(ptr %ptr) {
864 ; CHECK-LABEL: define void @hoist_inner_loop2(
868 ; CHECK-NEXT: br label %a.header
871 %x.a = load i32, ptr %ptr
874 ; CHECK-NEXT: %x.a = load i32, ptr %ptr
875 ; CHECK-NEXT: br label %b.header
878 %x.b = load i32, ptr %ptr
879 %v1 = call i1 @cond()
882 ; CHECK-NEXT: %x.b = load i32, ptr %ptr
883 ; CHECK-NEXT: %v1 = call i1 @cond()
884 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
886 ; CHECK: [[B_HEADER_SPLIT]]:
887 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
888 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
889 ; CHECK-NEXT: br label %c.header
892 br i1 %v1, label %b.latch, label %c.latch
894 ; CHECK-NEXT: br label %c.latch
897 ; Use values from other loops to check LCSSA form.
898 store i32 %x.a, ptr %ptr
899 store i32 %x.b, ptr %ptr
900 %v2 = call i1 @cond()
901 br i1 %v2, label %c.header, label %exit
903 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], ptr %ptr
904 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr
905 ; CHECK-NEXT: %v2 = call i1 @cond()
906 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
909 %v3 = call i1 @cond()
910 br i1 %v3, label %b.header, label %a.latch
912 ; CHECK-NEXT: %v3 = call i1 @cond()
913 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
918 ; CHECK-NEXT: br label %a.header
923 ; CHECK-NEXT: ret void
926 ; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.
927 ; Unswitch will transform the loop nest from:
931 define void @hoist_inner_loop3(ptr %ptr) {
932 ; CHECK-LABEL: define void @hoist_inner_loop3(
936 ; CHECK-NEXT: br label %a.header
939 %x.a = load i32, ptr %ptr
942 ; CHECK-NEXT: %x.a = load i32, ptr %ptr
943 ; CHECK-NEXT: br label %b.header
946 %x.b = load i32, ptr %ptr
947 %v1 = call i1 @cond()
950 ; CHECK-NEXT: %x.b = load i32, ptr %ptr
951 ; CHECK-NEXT: %v1 = call i1 @cond()
952 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]
954 ; CHECK: [[B_HEADER_SPLIT]]:
955 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
956 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
957 ; CHECK-NEXT: br label %c.header
960 br i1 %v1, label %b.latch, label %c.body
962 ; CHECK-NEXT: br label %c.body
965 %x.c = load i32, ptr %ptr
968 ; CHECK-NEXT: %x.c = load i32, ptr %ptr
969 ; CHECK-NEXT: br label %d.header
972 ; Use values from other loops to check LCSSA form.
973 store i32 %x.a, ptr %ptr
974 store i32 %x.b, ptr %ptr
975 store i32 %x.c, ptr %ptr
976 %v2 = call i1 @cond()
977 br i1 %v2, label %d.header, label %c.latch
979 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], ptr %ptr
980 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr
981 ; CHECK-NEXT: store i32 %x.c, ptr %ptr
982 ; CHECK-NEXT: %v2 = call i1 @cond()
983 ; CHECK-NEXT: br i1 %v2, label %d.header, label %c.latch
986 %v3 = call i1 @cond()
987 br i1 %v3, label %c.header, label %exit
989 ; CHECK-NEXT: %v3 = call i1 @cond()
990 ; CHECK-NEXT: br i1 %v3, label %c.header, label %exit
993 %v4 = call i1 @cond()
994 br i1 %v4, label %b.header, label %a.latch
996 ; CHECK-NEXT: %v4 = call i1 @cond()
997 ; CHECK-NEXT: br i1 %v4, label %b.header, label %a.latch
1002 ; CHECK-NEXT: br label %a.header
1007 ; CHECK-NEXT: ret void
1010 ; This test is designed to exercise checking multiple remaining exits from the
1011 ; loop being unswitched.
1012 ; Unswitch will transform the loop nest from:
1016 define void @hoist_inner_loop4() {
1017 ; CHECK-LABEL: define void @hoist_inner_loop4(
1021 ; CHECK-NEXT: br label %a.header
1026 ; CHECK-NEXT: br label %b.header
1031 ; CHECK-NEXT: br label %c.header
1034 %v1 = call i1 @cond()
1037 ; CHECK-NEXT: %v1 = call i1 @cond()
1038 ; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT:.*]], label %c.latch
1040 ; CHECK: [[C_HEADER_SPLIT]]:
1041 ; CHECK-NEXT: br label %d.header
1044 br i1 %v1, label %d.exiting1, label %c.latch
1046 ; CHECK-NEXT: br label %d.exiting1
1049 %v2 = call i1 @cond()
1050 br i1 %v2, label %d.exiting2, label %a.latch
1051 ; CHECK: d.exiting1:
1052 ; CHECK-NEXT: %v2 = call i1 @cond()
1053 ; CHECK-NEXT: br i1 %v2, label %d.exiting2, label %a.latch
1056 %v3 = call i1 @cond()
1057 br i1 %v3, label %d.exiting3, label %loopexit.d
1058 ; CHECK: d.exiting2:
1059 ; CHECK-NEXT: %v3 = call i1 @cond()
1060 ; CHECK-NEXT: br i1 %v3, label %d.exiting3, label %loopexit.d
1063 %v4 = call i1 @cond()
1064 br i1 %v4, label %d.latch, label %b.latch
1065 ; CHECK: d.exiting3:
1066 ; CHECK-NEXT: %v4 = call i1 @cond()
1067 ; CHECK-NEXT: br i1 %v4, label %d.latch, label %b.latch
1072 ; CHECK-NEXT: br label %d.header
1075 %v5 = call i1 @cond()
1076 br i1 %v5, label %c.header, label %loopexit.c
1078 ; CHECK-NEXT: %v5 = call i1 @cond()
1079 ; CHECK-NEXT: br i1 %v5, label %c.header, label %loopexit.c
1084 ; CHECK-NEXT: br label %b.header
1089 ; CHECK-NEXT: br label %a.header
1093 ; CHECK: loopexit.d:
1094 ; CHECK-NEXT: br label %exit
1098 ; CHECK: loopexit.c:
1099 ; CHECK-NEXT: br label %exit
1104 ; CHECK-NEXT: ret void
1107 ; Unswitch will transform the loop nest from:
1111 define void @hoist_inner_loop5(ptr %ptr) {
1112 ; CHECK-LABEL: define void @hoist_inner_loop5(
1116 ; CHECK-NEXT: br label %a.header
1119 %x.a = load i32, ptr %ptr
1122 ; CHECK-NEXT: %x.a = load i32, ptr %ptr
1123 ; CHECK-NEXT: br label %b.header
1126 %x.b = load i32, ptr %ptr
1129 ; CHECK-NEXT: %x.b = load i32, ptr %ptr
1130 ; CHECK-NEXT: br label %c.header
1133 %x.c = load i32, ptr %ptr
1134 %v1 = call i1 @cond()
1137 ; CHECK-NEXT: %x.c = load i32, ptr %ptr
1138 ; CHECK-NEXT: %v1 = call i1 @cond()
1139 ; CHECK-NEXT: br i1 %v1, label %c.latch, label %[[C_HEADER_SPLIT:.*]]
1141 ; CHECK: [[C_HEADER_SPLIT]]:
1142 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %c.header ]
1143 ; CHECK-NEXT: %[[X_C_LCSSA:.*]] = phi i32 [ %x.c, %c.header ]
1144 ; CHECK-NEXT: br label %d.header
1147 br i1 %v1, label %c.latch, label %d.latch
1149 ; CHECK-NEXT: br label %d.latch
1152 ; Use values from other loops to check LCSSA form.
1153 store i32 %x.a, ptr %ptr
1154 store i32 %x.b, ptr %ptr
1155 store i32 %x.c, ptr %ptr
1156 %v2 = call i1 @cond()
1157 br i1 %v2, label %d.header, label %a.latch
1159 ; CHECK-NEXT: store i32 %x.a, ptr %ptr
1160 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr
1161 ; CHECK-NEXT: store i32 %[[X_C_LCSSA]], ptr %ptr
1162 ; CHECK-NEXT: %v2 = call i1 @cond()
1163 ; CHECK-NEXT: br i1 %v2, label %d.header, label %a.latch
1166 %v3 = call i1 @cond()
1167 br i1 %v3, label %c.header, label %b.latch
1169 ; CHECK-NEXT: %v3 = call i1 @cond()
1170 ; CHECK-NEXT: br i1 %v3, label %c.header, label %b.latch
1175 ; CHECK-NEXT: br label %b.header
1180 ; CHECK-NEXT: br label %a.header
1185 ; CHECK-NEXT: ret void
1188 ; Same as `@hoist_inner_loop2` but using a switch.
1189 ; Unswitch will transform the loop nest from:
1193 define void @hoist_inner_loop_switch(ptr %ptr) {
1194 ; CHECK-LABEL: define void @hoist_inner_loop_switch(
1198 ; CHECK-NEXT: br label %a.header
1201 %x.a = load i32, ptr %ptr
1204 ; CHECK-NEXT: %x.a = load i32, ptr %ptr
1205 ; CHECK-NEXT: br label %b.header
1208 %x.b = load i32, ptr %ptr
1209 %v1 = call i32 @cond.i32()
1212 ; CHECK-NEXT: %x.b = load i32, ptr %ptr
1213 ; CHECK-NEXT: %v1 = call i32 @cond.i32()
1214 ; CHECK-NEXT: switch i32 %v1, label %[[B_HEADER_SPLIT:.*]] [
1215 ; CHECK-NEXT: i32 1, label %b.latch
1216 ; CHECK-NEXT: i32 2, label %b.latch
1217 ; CHECK-NEXT: i32 3, label %b.latch
1220 ; CHECK: [[B_HEADER_SPLIT]]:
1221 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]
1222 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]
1223 ; CHECK-NEXT: br label %c.header
1226 switch i32 %v1, label %c.latch [
1227 i32 1, label %b.latch
1228 i32 2, label %b.latch
1229 i32 3, label %b.latch
1232 ; CHECK-NEXT: br label %c.latch
1235 ; Use values from other loops to check LCSSA form.
1236 store i32 %x.a, ptr %ptr
1237 store i32 %x.b, ptr %ptr
1238 %v2 = call i1 @cond()
1239 br i1 %v2, label %c.header, label %exit
1241 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], ptr %ptr
1242 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr
1243 ; CHECK-NEXT: %v2 = call i1 @cond()
1244 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit
1247 %v3 = call i1 @cond()
1248 br i1 %v3, label %b.header, label %a.latch
1250 ; CHECK-NEXT: %v3 = call i1 @cond()
1251 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch
1256 ; CHECK-NEXT: br label %a.header
1261 ; CHECK-NEXT: ret void
1264 define void @test_unswitch_to_common_succ_with_phis(ptr %var, i32 %cond) {
1265 ; CHECK-LABEL: @test_unswitch_to_common_succ_with_phis(
1268 ; CHECK-NEXT: entry:
1269 ; CHECK-NEXT: switch i32 %cond, label %loopexit1 [
1270 ; CHECK-NEXT: i32 13, label %loopexit2
1271 ; CHECK-NEXT: i32 0, label %entry.split
1272 ; CHECK-NEXT: i32 1, label %entry.split
1275 ; CHECK: entry.split:
1276 ; CHECK-NEXT: br label %header
1279 %var_val = load i32, ptr %var
1280 switch i32 %cond, label %loopexit1 [
1283 i32 13, label %loopexit2
1287 ; CHECK-NEXT: br label %latch
1290 ; No-op PHI node to exercise weird PHI update scenarios.
1291 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ]
1292 call void @sink(i32 %phi)
1295 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ]
1296 ; CHECK-NEXT: call void @sink(i32 %[[PHI]])
1297 ; CHECK-NEXT: br label %header
1310 define void @test_unswitch_to_default_common_succ_with_phis(ptr %var, i32 %cond) {
1311 ; CHECK-LABEL: @test_unswitch_to_default_common_succ_with_phis(
1314 ; CHECK-NEXT: entry:
1315 ; CHECK-NEXT: switch i32 %cond, label %entry.split [
1316 ; CHECK-NEXT: i32 13, label %loopexit
1319 ; CHECK: entry.split:
1320 ; CHECK-NEXT: br label %header
1323 %var_val = load i32, ptr %var
1324 switch i32 %cond, label %latch [
1327 i32 13, label %loopexit
1331 ; CHECK-NEXT: br label %latch
1334 ; No-op PHI node to exercise weird PHI update scenarios.
1335 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ], [ %var_val, %header ]
1336 call void @sink(i32 %phi)
1339 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ]
1340 ; CHECK-NEXT: call void @sink(i32 %[[PHI]])
1341 ; CHECK-NEXT: br label %header
1351 define void @test_unswitch_switch_with_nonempty_unreachable() {
1352 ; CHECK-LABEL: @test_unswitch_switch_with_nonempty_unreachable()
1357 %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
1361 switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [
1362 i32 0, label %for.cond
1363 i32 1, label %NonEmptyUnreachableBlock
1364 i32 2, label %loop.loopexit
1370 NonEmptyUnreachableBlock:
1376 ; CHECK-NEXT: %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
1377 ; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [
1378 ; CHECK-NEXT: i32 1, label %NonEmptyUnreachableBlock
1379 ; CHECK-NEXT: i32 0, label %loop.split
1380 ; CHECK-NEXT: i32 2, label %loop.split
1384 ; CHECK-NEXT: br label %for.cond
1387 ; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %loop.loopexit [
1388 ; CHECK-NEXT: i32 0, label %for.cond
1391 ; CHECK:loop.loopexit:
1392 ; CHECK-NEXT: unreachable
1394 ; CHECK:NonEmptyUnreachableBlock:
1395 ; CHECK-NEXT: call void @f()
1396 ; CHECK-NEXT: call void @g()
1397 ; CHECK-NEXT: unreachable
1400 define void @test_unswitch_switch_with_nonempty_unreachable2() {
1401 ; CHECK-LABEL: @test_unswitch_switch_with_nonempty_unreachable2()
1406 %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
1410 switch i32 %cleanup.dest.slot.0, label %for.cond [
1411 i32 0, label %for.cond
1412 i32 1, label %NonEmptyUnreachableBlock
1413 i32 2, label %loop.loopexit
1419 NonEmptyUnreachableBlock:
1425 ; CHECK-NEXT: %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
1426 ; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %loop.split [
1427 ; CHECK-NEXT: i32 1, label %NonEmptyUnreachableBlock
1431 ; CHECK-NEXT: br label %for.cond
1434 ; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %for.cond.backedge [
1435 ; CHECK-NEXT: i32 0, label %for.cond.backedge
1436 ; CHECK-NEXT: i32 2, label %loop.loopexit
1439 ; CHECK:for.cond.backedge:
1440 ; CHECK-NEXT: br label %for.cond
1442 ; CHECK:loop.loopexit:
1443 ; CHECK-NEXT: unreachable
1445 ; CHECK:NonEmptyUnreachableBlock:
1446 ; CHECK-NEXT: call void @f()
1447 ; CHECK-NEXT: call void @g()
1448 ; CHECK-NEXT: unreachable
1452 define void @test_unswitch_switch_with_duplicate_edge() {
1453 ; CHECK-LABEL: @test_unswitch_switch_with_duplicate_edge()
1457 lbl1: ; preds = %entry
1458 %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
1461 for.cond1: ; preds = %for.cond1, %lbl1
1462 switch i32 %cleanup.dest.slot.0, label %UnifiedUnreachableBlock [
1463 i32 0, label %for.cond1
1464 i32 5, label %UnifiedUnreachableBlock
1465 i32 2, label %lbl1.loopexit
1468 UnifiedUnreachableBlock: ; preds = %for.cond1, %for.cond1
1471 lbl1.loopexit: ; preds = %for.cond1
1475 ; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %UnifiedUnreachableBlock [
1476 ; CHECK-NEXT: i32 0, label %for.cond1
1477 ; CHECK-NEXT: i32 5, label %UnifiedUnreachableBlock
1478 ; CHECK-NEXT: i32 2, label %lbl1.loopexit