1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck %s
2 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -tail-dup-placement=0 -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck -check-prefix=OPT %s
4 ; Test the CFG stackifier pass.
6 ; Explicitly disable fast-isel, since it gets implicitly enabled in the
9 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
10 target triple = "wasm32-unknown-unknown"
12 declare void @something()
14 ; Test that loops are made contiguous, even in the presence of split backedges.
22 ; CHECK-NEXT: .LBB0_3:
23 ; CHECK-NEXT: end_block
24 ; CHECK-NEXT: i32.const
28 ; CHECK-NEXT: .LBB0_4:
29 ; CHECK-NEXT: end_loop
40 define void @test0(i32 %n) {
45 %i = phi i32 [ 0, %entry ], [ %i.next, %back ]
46 %i.next = add i32 %i, 1
48 %c = icmp slt i32 %i.next, %n
49 br i1 %c, label %back, label %exit
55 call void @something()
59 ; Same as test0, but the branch condition is reversed.
67 ; CHECK-NEXT: .LBB1_3:
68 ; CHECK-NEXT: end_block
69 ; CHECK-NEXT: i32.const
73 ; CHECK-NEXT: .LBB1_4:
74 ; CHECK-NEXT: end_loop
85 define void @test1(i32 %n) {
90 %i = phi i32 [ 0, %entry ], [ %i.next, %back ]
91 %i.next = add i32 %i, 1
93 %c = icmp sge i32 %i.next, %n
94 br i1 %c, label %exit, label %back
100 call void @something()
104 ; Test that a simple loop is handled as expected.
106 ; CHECK-LABEL: test2:
109 ; CHECK: br_if 0, {{[^,]+}}{{$}}
110 ; CHECK: .LBB2_{{[0-9]+}}:
112 ; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}
113 ; CHECK: .LBB2_{{[0-9]+}}:
120 ; OPT: br_if 0, {{[^,]+}}{{$}}
121 ; OPT: .LBB2_{{[0-9]+}}:
123 ; OPT: br_if 0, $pop{{[0-9]+}}{{$}}
124 ; OPT: .LBB2_{{[0-9]+}}:
128 define void @test2(double* nocapture %p, i32 %n) {
130 %cmp.4 = icmp sgt i32 %n, 0
131 br i1 %cmp.4, label %for.body.preheader, label %for.end
137 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]
138 %arrayidx = getelementptr inbounds double, double* %p, i32 %i.05
139 %0 = load double, double* %arrayidx, align 8
140 %mul = fmul double %0, 3.200000e+00
141 store double %mul, double* %arrayidx, align 8
142 %inc = add nuw nsw i32 %i.05, 1
143 %exitcond = icmp eq i32 %inc, %n
144 br i1 %exitcond, label %for.end.loopexit, label %for.body
153 ; CHECK-LABEL: doublediamond:
155 ; CHECK-NEXT: block {{$}}
156 ; CHECK: br_if 0, ${{[^,]+}}{{$}}
159 ; CHECK-NEXT: end_block{{$}}
161 ; CHECK: br_if 0, ${{[^,]+}}{{$}}
164 ; CHECK-NEXT: end_block{{$}}
166 ; CHECK-NEXT: end_block{{$}}
167 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
168 ; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
169 ; OPT-LABEL: doublediamond:
171 ; OPT-NEXT: block {{$}}
172 ; OPT-NEXT: block {{$}}
173 ; OPT: br_if 0, ${{[^,]+}}{{$}}
174 ; OPT: br_if 1, ${{[^,]+}}{{$}}
177 ; OPT-NEXT: end_block
181 ; OPT-NEXT: end_block
182 ; OPT: return $pop{{[0-9]+}}{{$}}
183 define i32 @doublediamond(i32 %a, i32 %b, i32* %p) {
185 %c = icmp eq i32 %a, 0
186 %d = icmp eq i32 %b, 0
187 store volatile i32 0, i32* %p
188 br i1 %c, label %true, label %false
190 store volatile i32 1, i32* %p
193 store volatile i32 2, i32* %p
194 br i1 %d, label %ft, label %ff
196 store volatile i32 3, i32* %p
199 store volatile i32 4, i32* %p
202 store volatile i32 5, i32* %p
206 ; CHECK-LABEL: triangle:
208 ; CHECK: br_if 0, $1{{$}}
211 ; OPT-LABEL: triangle:
213 ; OPT: br_if 0, $1{{$}}
216 define i32 @triangle(i32* %p, i32 %a) {
218 %c = icmp eq i32 %a, 0
219 store volatile i32 0, i32* %p
220 br i1 %c, label %true, label %exit
222 store volatile i32 1, i32* %p
225 store volatile i32 2, i32* %p
229 ; CHECK-LABEL: diamond:
232 ; CHECK: br_if 0, $1{{$}}
236 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
237 ; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
238 ; OPT-LABEL: diamond:
241 ; OPT: br_if 0, {{[^,]+}}{{$}}
245 ; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
246 ; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
247 define i32 @diamond(i32* %p, i32 %a) {
249 %c = icmp eq i32 %a, 0
250 store volatile i32 0, i32* %p
251 br i1 %c, label %true, label %false
253 store volatile i32 1, i32* %p
256 store volatile i32 2, i32* %p
259 store volatile i32 3, i32* %p
263 ; CHECK-LABEL: single_block:
265 ; CHECK: return $pop{{[0-9]+}}{{$}}
266 ; OPT-LABEL: single_block:
268 ; OPT: return $pop{{[0-9]+}}{{$}}
269 define i32 @single_block(i32* %p) {
271 store volatile i32 0, i32* %p
275 ; CHECK-LABEL: minimal_loop:
279 ; CHECK: i32.store 0($0), $pop{{[0-9]+}}{{$}}
282 ; OPT-LABEL: minimal_loop:
286 ; OPT: i32.store 0($0), $pop{{[0-9]+}}{{$}}
289 define i32 @minimal_loop(i32* %p) {
291 store volatile i32 0, i32* %p
294 store volatile i32 1, i32* %p
298 ; CHECK-LABEL: simple_loop:
302 ; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}
303 ; CHECK-NEXT: end_loop{{$}}
304 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
305 ; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
306 ; OPT-LABEL: simple_loop:
310 ; OPT: br_if 0, {{[^,]+}}{{$}}
311 ; OPT-NEXT: end_loop{{$}}
312 ; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
313 ; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
314 define i32 @simple_loop(i32* %p, i32 %a) {
316 %c = icmp eq i32 %a, 0
317 store volatile i32 0, i32* %p
320 store volatile i32 1, i32* %p
321 br i1 %c, label %loop, label %exit
323 store volatile i32 2, i32* %p
327 ; CHECK-LABEL: doubletriangle:
329 ; CHECK: br_if 0, $0{{$}}
331 ; CHECK: br_if 0, $1{{$}}
335 ; OPT-LABEL: doubletriangle:
337 ; OPT: br_if 0, $0{{$}}
339 ; OPT: br_if 0, $1{{$}}
343 define i32 @doubletriangle(i32 %a, i32 %b, i32* %p) {
345 %c = icmp eq i32 %a, 0
346 %d = icmp eq i32 %b, 0
347 store volatile i32 0, i32* %p
348 br i1 %c, label %true, label %exit
350 store volatile i32 2, i32* %p
351 br i1 %d, label %tt, label %tf
353 store volatile i32 3, i32* %p
356 store volatile i32 4, i32* %p
359 store volatile i32 5, i32* %p
363 ; CHECK-LABEL: ifelse_earlyexits:
366 ; CHECK: br_if 0, $0{{$}}
369 ; CHECK: br_if 0, $1{{$}}
371 ; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
372 ; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
373 ; OPT-LABEL: ifelse_earlyexits:
376 ; OPT: br_if 0, {{[^,]+}}{{$}}
377 ; OPT: br_if 1, $1{{$}}
381 ; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
382 ; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
383 define i32 @ifelse_earlyexits(i32 %a, i32 %b, i32* %p) {
385 %c = icmp eq i32 %a, 0
386 %d = icmp eq i32 %b, 0
387 store volatile i32 0, i32* %p
388 br i1 %c, label %true, label %false
390 store volatile i32 1, i32* %p
393 store volatile i32 2, i32* %p
394 br i1 %d, label %ft, label %exit
396 store volatile i32 3, i32* %p
399 store volatile i32 4, i32* %p
403 ; CHECK-LABEL: doublediamond_in_a_loop:
405 ; CHECK: loop i32{{$}}
407 ; CHECK: br_if 0, $0{{$}}
410 ; CHECK: end_block{{$}}
412 ; CHECK: br_if 0, $1{{$}}
417 ; CHECK-NEXT: end_loop{{$}}
418 ; OPT-LABEL: doublediamond_in_a_loop:
422 ; OPT: br_if 0, {{[^,]+}}{{$}}
424 ; OPT: br_if 0, {{[^,]+}}{{$}}
426 ; OPT-NEXT: .LBB11_4:
427 ; OPT-NEXT: end_block{{$}}
430 ; OPT-NEXT: end_block{{$}}
433 ; OPT-NEXT: end_loop{{$}}
434 define i32 @doublediamond_in_a_loop(i32 %a, i32 %b, i32* %p) {
438 %c = icmp eq i32 %a, 0
439 %d = icmp eq i32 %b, 0
440 store volatile i32 0, i32* %p
441 br i1 %c, label %true, label %false
443 store volatile i32 1, i32* %p
446 store volatile i32 2, i32* %p
447 br i1 %d, label %ft, label %ff
449 store volatile i32 3, i32* %p
452 store volatile i32 4, i32* %p
455 store volatile i32 5, i32* %p
459 ; Test that nested loops are handled.
461 ; CHECK-LABEL: test3:
464 ; CHECK-NEXT: .LBB{{[0-9]+}}_{{[0-9]+}}:
469 ; OPT: .LBB{{[0-9]+}}_{{[0-9]+}}:
474 ; OPT-NEXT: .LBB{{[0-9]+}}_{{[0-9]+}}:
478 ; OPT-NEXT: .LBB{{[0-9]+}}_{{[0-9]+}}:
480 ; OPT-NEXT: end_block
481 ; OPT-NEXT: unreachable
482 ; OPT-NEXT: .LBB{{[0-9]+}}_{{[0-9]+}}:
483 ; OPT-NEXT: end_block
485 ; OPT-NEXT: .LBB{{[0-9]+}}_{{[0-9]+}}:
488 define void @test3(i32 %w) {
490 br i1 undef, label %outer.ph, label %exit
496 %tobool = icmp eq i32 undef, 0
497 br i1 %tobool, label %inner, label %unreachable
503 %c = icmp eq i32 undef, %w
504 br i1 %c, label %if.end, label %inner
514 ; Test switch lowering and block placement.
516 ; CHECK-LABEL: test4:
517 ; CHECK-NEXT: .functype test4 (i32) -> (){{$}}
519 ; CHECK-NEXT: block {{$}}
520 ; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}
521 ; CHECK: br_if 1, $pop{{[0-9]+}}{{$}}
523 ; CHECK-NEXT: .LBB13_3:
524 ; CHECK-NEXT: end_block{{$}}
525 ; CHECK-NEXT: block {{$}}
526 ; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}
527 ; CHECK: br_if 1, $pop{{[0-9]+}}{{$}}
528 ; CHECK-NEXT: .LBB13_5:
529 ; CHECK-NEXT: end_block{{$}}
530 ; CHECK-NEXT: return{{$}}
531 ; CHECK-NEXT: .LBB13_6:
532 ; CHECK-NEXT: end_block{{$}}
533 ; CHECK-NEXT: return{{$}}
535 ; OPT-NEXT: .functype test4 (i32) -> (){{$}}
537 ; OPT-NEXT: block {{$}}
538 ; OPT: br_if 0, $pop{{[0-9]+}}{{$}}
539 ; OPT: br_if 1, $pop{{[0-9]+}}{{$}}
541 ; OPT-NEXT: .LBB13_3:
542 ; OPT-NEXT: end_block{{$}}
543 ; OPT-NEXT: block {{$}}
544 ; OPT: br_if 0, $pop{{[0-9]+}}{{$}}
545 ; OPT: br_if 1, $pop{{[0-9]+}}{{$}}
546 ; OPT-NEXT: .LBB13_5:
547 ; OPT-NEXT: end_block{{$}}
548 ; OPT-NEXT: return{{$}}
549 ; OPT-NEXT: .LBB13_6:
550 ; OPT-NEXT: end_block{{$}}
551 ; OPT-NEXT: return{{$}}
552 define void @test4(i32 %t) {
554 switch i32 %t, label %default [
574 ; Test a case where the BLOCK needs to be placed before the LOOP in the
577 ; CHECK-LABEL: test5:
579 ; CHECK-NEXT: block {{$}}
580 ; CHECK-NEXT: loop {{$}}
581 ; CHECK: br_if 1, {{[^,]+}}{{$}}
582 ; CHECK: br_if 0, {{[^,]+}}{{$}}
583 ; CHECK-NEXT: end_loop{{$}}
585 ; CHECK-NEXT: .LBB14_4:
589 ; OPT-NEXT: block {{$}}
590 ; OPT-NEXT: loop {{$}}
591 ; OPT: br_if 1, {{[^,]+}}{{$}}
592 ; OPT: br_if 0, {{[^,]+}}{{$}}
593 ; OPT-NEXT: end_loop{{$}}
595 ; OPT-NEXT: .LBB14_4:
597 define void @test5(i1 %p, i1 %q) {
602 store volatile i32 0, i32* null
603 br i1 %p, label %more, label %alt
606 store volatile i32 1, i32* null
607 br i1 %q, label %header, label %return
610 store volatile i32 2, i32* null
614 store volatile i32 3, i32* null
618 ; Test an interesting case of a loop with multiple exits, which
619 ; aren't to layout successors of the loop, and one of which is to a successors
620 ; which has another predecessor.
622 ; CHECK-LABEL: test6:
624 ; CHECK-NEXT: block {{$}}
625 ; CHECK-NEXT: block {{$}}
626 ; CHECK-NEXT: loop {{$}}
628 ; CHECK: br_if 2, {{[^,]+}}{{$}}
630 ; CHECK: br_if 1, {{[^,]+}}{{$}}
632 ; CHECK: br_if 0, {{[^,]+}}{{$}}
633 ; CHECK-NEXT: end_loop{{$}}
636 ; CHECK-NEXT: .LBB15_5:
637 ; CHECK-NEXT: end_block{{$}}
640 ; CHECK-NEXT: end_block{{$}}
645 ; OPT-NEXT: block {{$}}
646 ; OPT-NEXT: block {{$}}
647 ; OPT-NEXT: loop {{$}}
649 ; OPT: br_if 2, {{[^,]+}}{{$}}
651 ; OPT: br_if 1, {{[^,]+}}{{$}}
653 ; OPT: br_if 0, {{[^,]+}}{{$}}
654 ; OPT-NEXT: end_loop{{$}}
657 ; OPT-NEXT: .LBB15_5:
658 ; OPT-NEXT: end_block{{$}}
661 ; OPT-NEXT: end_block{{$}}
664 define void @test6(i1 %p, i1 %q) {
669 store volatile i32 0, i32* null
670 br i1 %p, label %more, label %second
673 store volatile i32 1, i32* null
674 br i1 %q, label %evenmore, label %first
677 store volatile i32 1, i32* null
678 br i1 %q, label %header, label %return
681 store volatile i32 2, i32* null
685 store volatile i32 3, i32* null
689 store volatile i32 4, i32* null
693 ; Test a case where there are multiple backedges and multiple loop exits
694 ; that end in unreachable.
696 ; CHECK-LABEL: test7:
698 ; CHECK-NEXT: loop {{$}}
701 ; CHECK: br_if 0, {{[^,]+}}{{$}}
703 ; CHECK: br_if 1, {{[^,]+}}{{$}}
706 ; CHECK-NEXT: .LBB16_4:
707 ; CHECK-NEXT: end_block{{$}}
709 ; CHECK: br_if 0, {{[^,]+}}{{$}}
710 ; CHECK-NEXT: end_loop{{$}}
716 ; OPT-NEXT: loop {{$}}
720 ; OPT: br_if 0, {{[^,]+}}{{$}}
722 ; OPT: br_if 1, {{[^,]+}}{{$}}
724 ; OPT-NEXT: .LBB16_3:
725 ; OPT-NEXT: end_block
727 ; OPT: br_if 0, {{[^,]+}}{{$}}
731 ; OPT-NEXT: .LBB16_5:
732 ; OPT-NEXT: end_block
735 define void @test7(i1 %tobool2, i1 %tobool9) {
737 store volatile i32 0, i32* null
741 store volatile i32 1, i32* null
742 br i1 %tobool2, label %l1, label %l0
745 store volatile i32 2, i32* null
746 br i1 %tobool9, label %loop, label %u0
749 store volatile i32 3, i32* null
750 br i1 %tobool9, label %loop, label %u1
753 store volatile i32 4, i32* null
757 store volatile i32 5, i32* null
761 ; Test an interesting case using nested loops and switches.
763 ; CHECK-LABEL: test8:
765 ; CHECK-NEXT: loop i32{{$}}
766 ; CHECK-NEXT: i32.const $push{{[^,]+}}, 0{{$}}
767 ; CHECK-NEXT: br_if 0, {{[^,]+}}{{$}}
768 ; CHECK-NEXT: br 0{{$}}
769 ; CHECK-NEXT: .LBB17_2:
770 ; CHECK-NEXT: end_loop{{$}}
773 ; OPT-NEXT: loop i32{{$}}
774 ; OPT-NEXT: i32.const $push{{[^,]+}}, 0{{$}}
775 ; OPT-NEXT: br_if 0, {{[^,]+}}{{$}}
776 ; OPT-NEXT: br 0{{$}}
777 ; OPT-NEXT: .LBB17_2:
778 ; OPT-NEXT: end_loop{{$}}
779 define i32 @test8() {
784 br i1 undef, label %bb2, label %bb3
787 switch i8 undef, label %bb1 [
792 switch i8 undef, label %bb1 [
797 ; Test an interesting case using nested loops that share a bottom block.
799 ; CHECK-LABEL: test9:
801 ; CHECK-NEXT: block {{$}}
802 ; CHECK-NEXT: loop {{$}}
804 ; CHECK: br_if 1, {{[^,]+}}{{$}}
805 ; CHECK-NEXT: .LBB18_2:
806 ; CHECK-NEXT: loop {{$}}
810 ; CHECK: br_if 0, {{[^,]+}}{{$}}
812 ; CHECK: br_if 2, {{[^,]+}}{{$}}
813 ; CHECK-NEXT: br 1{{$}}
814 ; CHECK-NEXT: .LBB18_4:
815 ; CHECK-NEXT: end_block{{$}}
817 ; CHECK: br_if 1, {{[^,]+}}{{$}}
818 ; CHECK-NEXT: br 0{{$}}
819 ; CHECK-NEXT: .LBB18_5:
826 ; OPT-NEXT: block {{$}}
827 ; OPT-NEXT: loop {{$}}
829 ; OPT: br_if 1, {{[^,]+}}{{$}}
830 ; OPT-NEXT: .LBB18_2:
831 ; OPT-NEXT: loop {{$}}
835 ; OPT: br_if 0, {{[^,]+}}{{$}}
837 ; OPT: br_if 1, {{[^,]+}}{{$}}
838 ; OPT-NEXT: br 2{{$}}
839 ; OPT-NEXT: .LBB18_4:
840 ; OPT-NEXT: end_block{{$}}
842 ; OPT: br_if 0, {{[^,]+}}{{$}}
843 ; OPT-NEXT: br 1{{$}}
844 ; OPT-NEXT: .LBB18_5:
850 define void @test9() {
852 store volatile i32 0, i32* null
856 store volatile i32 1, i32* null
857 %call4 = call i1 @a()
858 br i1 %call4, label %header2, label %end
861 store volatile i32 2, i32* null
863 br i1 %call, label %if.then, label %if.else
866 store volatile i32 3, i32* null
867 %call3 = call i1 @a()
868 br i1 %call3, label %header2, label %header
871 store volatile i32 4, i32* null
872 %call2 = call i1 @a()
873 br i1 %call2, label %header2, label %header
876 store volatile i32 5, i32* null
880 ; Test an interesting case involving nested loops sharing a loop bottom,
881 ; and loop exits to a block with unreachable.
883 ; CHECK-LABEL: test10:
885 ; CHECK-NEXT: loop {{$}}
887 ; CHECK: br_if 0, {{[^,]+}}{{$}}
889 ; CHECK-NEXT: block {{$}}
890 ; CHECK-NEXT: loop {{$}}
893 ; CHECK-NEXT: loop {{$}}
895 ; CHECK: br_if 0, {{[^,]+}}{{$}}
896 ; CHECK-NEXT: end_loop{{$}}
897 ; CHECK: br_if 1, {{[^,]+}}{{$}}
899 ; CHECK: br_if 0, {{[^,]+}}{{$}}
900 ; CHECK-NEXT: end_loop{{$}}
902 ; CHECK: br_if 1, {{[^,]+}}{{$}}
903 ; CHECK-NEXT: return{{$}}
904 ; CHECK-NEXT: .LBB19_9:
905 ; CHECK-NEXT: end_block{{$}}
908 ; CHECK-NEXT: .LBB19_10:
911 ; OPT-NEXT: loop {{$}}
913 ; OPT: br_if 0, {{[^,]+}}{{$}}
915 ; OPT-NEXT: block {{$}}
916 ; OPT-NEXT: loop {{$}}
919 ; OPT-NEXT: loop {{$}}
921 ; OPT: br_if 0, {{[^,]+}}{{$}}
922 ; OPT-NEXT: end_loop{{$}}
923 ; OPT: br_if 1, {{[^,]+}}{{$}}
925 ; OPT: br_if 0, {{[^,]+}}{{$}}
926 ; OPT-NEXT: end_loop{{$}}
928 ; OPT: br_if 1, {{[^,]+}}{{$}}
929 ; OPT-NEXT: return{{$}}
930 ; OPT-NEXT: .LBB19_9:
931 ; OPT-NEXT: end_block{{$}}
934 ; OPT-NEXT: .LBB19_10:
935 define void @test10() {
940 %tmp = phi i32 [ 2, %bb0 ], [ 3, %bb3 ]
941 %tmp3 = phi i32 [ undef, %bb0 ], [ %tmp11, %bb3 ]
942 %tmp4 = icmp eq i32 %tmp3, 0
943 br i1 %tmp4, label %bb4, label %bb2
949 %tmp11 = phi i32 [ 1, %bb5 ], [ 0, %bb2 ]
953 %tmp6 = phi i32 [ %tmp9, %bb5 ], [ 4, %bb1 ]
954 %tmp7 = phi i32 [ %tmp6, %bb5 ], [ %tmp, %bb1 ]
958 %tmp9 = phi i32 [ %tmp6, %bb5 ], [ %tmp7, %bb4 ]
959 switch i32 %tmp9, label %bb2 [
970 ; Test a CFG DAG with interesting merging.
972 ; CHECK-LABEL: test11:
974 ; CHECK-NEXT: block {{$}}
975 ; CHECK-NEXT: block {{$}}
976 ; CHECK-NEXT: block {{$}}
977 ; CHECK: br_if 0, {{[^,]+}}{{$}}
980 ; CHECK-NEXT: i32.const
981 ; CHECK-NEXT: br_if 0, {{[^,]+}}{{$}}
983 ; CHECK: br_if 2, {{[^,]+}}{{$}}
984 ; CHECK-NEXT: .LBB20_3:
985 ; CHECK-NEXT: end_block{{$}}
988 ; CHECK-NEXT: .LBB20_4:
989 ; CHECK-NEXT: end_block{{$}}
991 ; CHECK: br_if 1, {{[^,]+}}{{$}}
993 ; CHECK: br_if 2, {{[^,]+}}{{$}}
994 ; CHECK-NEXT: .LBB20_6:
995 ; CHECK-NEXT: end_block{{$}}
998 ; CHECK-NEXT: .LBB20_7:
999 ; CHECK-NEXT: end_block{{$}}
1001 ; CHECK: return{{$}}
1002 ; CHECK-NEXT: .LBB20_8:
1003 ; CHECK-NEXT: end_block{{$}}
1005 ; CHECK: return{{$}}
1006 ; OPT-LABEL: test11:
1008 ; OPT-NEXT: block {{$}}
1009 ; OPT: br_if 0, $pop{{[0-9]+}}{{$}}
1012 ; OPT-NEXT: i32.const
1013 ; OPT-NEXT: br_if 0, {{[^,]+}}{{$}}
1015 ; OPT: br_if 2, {{[^,]+}}{{$}}
1016 ; OPT-NEXT: .LBB20_3:
1017 ; OPT-NEXT: end_block{{$}}
1020 ; OPT-NEXT: .LBB20_4:
1021 ; OPT-NEXT: end_block{{$}}
1025 ; OPT: br_if 0, $pop{{[0-9]+}}{{$}}
1028 ; OPT-NEXT: .LBB20_6:
1029 ; OPT-NEXT: end_block{{$}}
1031 ; OPT: br_if 0, $pop{{[0-9]+}}{{$}}
1034 ; OPT-NEXT: .LBB20_8:
1035 ; OPT-NEXT: end_block{{$}}
1038 define void @test11() {
1040 store volatile i32 0, i32* null
1041 br i1 undef, label %bb1, label %bb4
1043 store volatile i32 1, i32* null
1044 br i1 undef, label %bb3, label %bb2
1046 store volatile i32 2, i32* null
1047 br i1 undef, label %bb3, label %bb7
1049 store volatile i32 3, i32* null
1052 store volatile i32 4, i32* null
1053 br i1 undef, label %bb8, label %bb5
1055 store volatile i32 5, i32* null
1056 br i1 undef, label %bb6, label %bb7
1058 store volatile i32 6, i32* null
1061 store volatile i32 7, i32* null
1064 store volatile i32 8, i32* null
1068 ; CHECK-LABEL: test12:
1070 ; CHECK-NEXT: block {{$}}
1071 ; CHECK-NEXT: loop {{$}}
1073 ; CHECK: block {{$}}
1074 ; CHECK-NEXT: block {{$}}
1075 ; CHECK: br_if 0, {{[^,]+}}{{$}}
1077 ; CHECK: br_if 1, {{[^,]+}}{{$}}
1079 ; CHECK: br_if 1, {{[^,]+}}{{$}}
1080 ; CHECK-NEXT: br 3{{$}}
1081 ; CHECK-NEXT: .LBB21_4:
1082 ; CHECK-NEXT: end_block{{$}}
1084 ; CHECK: br_if 0, {{[^,]+}}{{$}}
1086 ; CHECK: br_if 2, {{[^,]+}}{{$}}
1087 ; CHECK-NEXT: .LBB21_6:
1088 ; CHECK-NEXT: end_block{{$}}
1091 ; CHECK-NEXT: .LBB21_7:
1092 ; CHECK-NEXT: end_loop{{$}}
1093 ; CHECK-NEXT: end_block{{$}}
1094 ; CHECK-NEXT: return{{$}}
1095 ; OPT-LABEL: test12:
1097 ; OPT-NEXT: block {{$}}
1098 ; OPT-NEXT: loop {{$}}
1101 ; OPT-NEXT: block {{$}}
1102 ; OPT: br_if 0, {{[^,]+}}{{$}}
1104 ; OPT: br_if 1, {{[^,]+}}{{$}}
1106 ; OPT: br_if 1, {{[^,]+}}{{$}}
1107 ; OPT-NEXT: br 3{{$}}
1108 ; OPT-NEXT: .LBB21_4:
1109 ; OPT-NEXT: end_block{{$}}
1111 ; OPT: br_if 0, {{[^,]+}}{{$}}
1113 ; OPT: br_if 2, {{[^,]+}}{{$}}
1114 ; OPT-NEXT: .LBB21_6:
1115 ; OPT-NEXT: end_block{{$}}
1117 ; OPT-NEXT: .LBB21_7:
1118 ; OPT-NEXT: end_loop{{$}}
1119 ; OPT-NEXT: end_block{{$}}
1120 ; OPT-NEXT: return{{$}}
1121 define void @test12(i8* %arg) {
1126 %tmp = phi i32 [ 0, %bb ], [ %tmp5, %bb4 ]
1127 %tmp2 = getelementptr i8, i8* %arg, i32 %tmp
1128 %tmp3 = load i8, i8* %tmp2
1129 switch i8 %tmp3, label %bb7 [
1137 %tmp5 = add i32 %tmp, 1
1144 ; A block can be "branched to" from another even if it is also reachable via
1145 ; fallthrough from the other. This would normally be optimized away, so use
1146 ; optnone to disable optimizations to test this case.
1148 ; CHECK-LABEL: test13:
1149 ; CHECK: block {{$}}
1150 ; CHECK-NEXT: block {{$}}
1151 ; CHECK: br_if 0, $pop0{{$}}
1152 ; CHECK: block {{$}}
1153 ; CHECK: br_if 0, $pop3{{$}}
1155 ; CHECK-NEXT: end_block{{$}}
1156 ; CHECK: br_if 1, $pop{{[0-9]+}}{{$}}
1157 ; CHECK-NEXT: br 1{{$}}
1158 ; CHECK-NEXT: .LBB22_4:
1159 ; CHECK-NEXT: end_block{{$}}
1160 ; CHECK-NEXT: return{{$}}
1161 ; CHECK-NEXT: .LBB22_5:
1162 ; CHECK-NEXT: end_block{{$}}
1163 ; CHECK-NEXT: unreachable{{$}}
1164 ; OPT-LABEL: test13:
1166 ; OPT-NEXT: block {{$}}
1167 ; OPT: br_if 0, $pop0{{$}}
1169 ; OPT: br_if 0, $pop3{{$}}
1171 ; OPT-NEXT: end_block{{$}}
1172 ; OPT: br_if 1, $pop{{[0-9]+}}{{$}}
1173 ; OPT-NEXT: br 1{{$}}
1174 ; OPT-NEXT: .LBB22_4:
1175 ; OPT-NEXT: end_block
1177 ; OPT-NEXT: .LBB22_5:
1178 ; OPT-NEXT: end_block{{$}}
1179 ; OPT-NEXT: unreachable{{$}}
1180 define void @test13() noinline optnone {
1182 br i1 undef, label %bb5, label %bb2
1186 br i1 undef, label %bb3, label %bb4
1190 %tmp = phi i1 [ false, %bb2 ], [ false, %bb3 ]
1191 br i1 %tmp, label %bb1, label %bb1
1196 ; Test a case with a single-block loop that has another loop
1197 ; as a successor. The end_loop for the first loop should go
1198 ; before the loop for the second.
1200 ; CHECK-LABEL: test14:
1201 ; CHECK: .LBB23_1:{{$}}
1202 ; CHECK-NEXT: loop {{$}}
1203 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
1204 ; CHECK-NEXT: br_if 0, $pop0{{$}}
1205 ; CHECK-NEXT: end_loop{{$}}
1206 ; CHECK-NEXT: .LBB23_3:{{$}}
1207 ; CHECK-NEXT: loop {{$}}
1208 ; CHECK-NEXT: i32.const $push1=, 0{{$}}
1209 ; CHECK-NEXT: br_if 0, $pop1{{$}}
1210 ; CHECK-NEXT: end_loop{{$}}
1211 ; CHECK-NEXT: return{{$}}
1212 define void @test14() {
1217 %tmp = bitcast i1 undef to i1
1218 br i1 %tmp, label %bb3, label %bb1
1224 br i1 undef, label %bb7, label %bb48
1227 br i1 undef, label %bb12, label %bb12
1230 br i1 undef, label %bb17, label %bb17
1233 br i1 undef, label %bb22, label %bb22
1236 br i1 undef, label %bb27, label %bb27
1239 br i1 undef, label %bb30, label %bb30
1242 br i1 undef, label %bb35, label %bb35
1245 br i1 undef, label %bb38, label %bb38
1248 br i1 undef, label %bb48, label %bb48
1251 %tmp49 = bitcast i1 undef to i1
1252 br i1 %tmp49, label %bb3, label %bb50
1258 ; Test that a block boundary which ends one block, begins another block, and
1259 ; also begins a loop, has the markers placed in the correct order.
1261 ; CHECK-LABEL: test15:
1264 ; CHECK: br_if 0, $pop{{.*}}{{$}}
1266 ; CHECK-NEXT: block {{$}}
1267 ; CHECK-NEXT: block {{$}}
1268 ; CHECK-NEXT: loop {{$}}
1269 ; CHECK: br_if 1, $pop{{.*}}{{$}}
1270 ; CHECK: br_if 0, ${{.*}}{{$}}
1271 ; CHECK-NEXT: br 2{{$}}
1272 ; CHECK-NEXT: .LBB24_4:
1273 ; CHECK-NEXT: end_loop{{$}}
1275 ; CHECK-NEXT: end_block{{$}}
1276 ; CHECK: br_if 1, $pop{{.*}}{{$}}
1277 ; CHECK: return{{$}}
1279 ; CHECK-NEXT: end_block{{$}}
1281 ; CHECK-NEXT: end_block{{$}}
1282 ; CHECK-NEXT: return{{$}}
1283 ; OPT-LABEL: test15:
1286 ; OPT-NEXT: i32.const $push
1287 ; OPT-NEXT: i32.eqz $push{{.*}}=, $pop{{.*}}{{$}}
1288 ; OPT-NEXT: br_if 0, $pop{{.*}}{{$}}
1289 ; OPT-NEXT: call test15_callee1@FUNCTION{{$}}
1290 ; OPT-NEXT: br 1{{$}}
1291 ; OPT-NEXT: .LBB24_2:
1292 ; OPT-NEXT: end_block
1293 ; OPT-NEXT: i32.const
1294 ; OPT-NEXT: .LBB24_3:
1298 %0 = type { i8, i32 }
1299 declare void @test15_callee0()
1300 declare void @test15_callee1()
1301 define void @test15() {
1303 %tmp1 = icmp eq i8 1, 0
1304 br i1 %tmp1, label %bb2, label %bb14
1307 %tmp3 = phi %0** [ %tmp6, %bb5 ], [ null, %bb ]
1308 %tmp4 = icmp eq i32 0, 11
1309 br i1 %tmp4, label %bb5, label %bb8
1312 %tmp = bitcast i8* null to %0**
1313 %tmp6 = getelementptr %0*, %0** %tmp3, i32 1
1314 %tmp7 = icmp eq %0** %tmp6, null
1315 br i1 %tmp7, label %bb10, label %bb2
1318 %tmp9 = icmp eq %0** null, undef
1322 %tmp11 = phi %0** [ null, %bb8 ], [ %tmp, %bb5 ]
1323 %tmp12 = icmp eq %0** null, %tmp11
1324 br i1 %tmp12, label %bb15, label %bb13
1327 call void @test15_callee0()
1331 call void @test15_callee1()