xref: /llvm-project/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll (revision ff9af4c43ad71eeba2cabe99609cfaa0fd54c1d0)
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
3; Test the CFG stackifier pass.
4
5; Explicitly disable fast-isel, since it gets implicitly enabled in the
6; optnone test.
7
8target triple = "wasm32-unknown-unknown"
9
10declare void @something()
11
12; Test that loops are made contiguous, even in the presence of split backedges.
13
14; CHECK-LABEL: test0:
15; CHECK: loop
16; CHECK-NEXT: block
17; CHECK:      i32.lt_s
18; CHECK-NEXT: br_if
19; CHECK-NEXT: return
20; CHECK-NEXT: .LBB{{[0-9]+}}_3:
21; CHECK-NEXT: end_block
22; CHECK-NEXT: i32.const
23; CHECK-NEXT: i32.add
24; CHECK-NEXT: call
25; CHECK-NEXT: br
26; CHECK-NEXT: .LBB{{[0-9]+}}_4:
27; CHECK-NEXT: end_loop
28define void @test0(i32 %n) {
29entry:
30  br label %header
31
32header:
33  %i = phi i32 [ 0, %entry ], [ %i.next, %back ]
34  %i.next = add i32 %i, 1
35
36  %c = icmp slt i32 %i.next, %n
37  br i1 %c, label %back, label %exit
38
39exit:
40  ret void
41
42back:
43  call void @something()
44  br label %header
45}
46
47; Same as test0, but the branch condition is reversed.
48
49; CHECK-LABEL: test1:
50; CHECK: loop
51; CHECK-NEXT: block
52; CHECK:      i32.lt_s
53; CHECK-NEXT: br_if
54; CHECK-NEXT: return
55; CHECK-NEXT: .LBB{{[0-9]+}}_3:
56; CHECK-NEXT: end_block
57; CHECK-NEXT: i32.const
58; CHECK-NEXT: i32.add
59; CHECK-NEXT: call
60; CHECK-NEXT: br
61; CHECK-NEXT: .LBB{{[0-9]+}}_4:
62; CHECK-NEXT: end_loop
63define void @test1(i32 %n) {
64entry:
65  br label %header
66
67header:
68  %i = phi i32 [ 0, %entry ], [ %i.next, %back ]
69  %i.next = add i32 %i, 1
70
71  %c = icmp sge i32 %i.next, %n
72  br i1 %c, label %exit, label %back
73
74exit:
75  ret void
76
77back:
78  call void @something()
79  br label %header
80}
81
82; Test that a simple loop is handled as expected.
83
84; CHECK-LABEL: test2:
85; CHECK-NOT: local
86; CHECK: block   {{$}}
87; CHECK: br_if 0, {{[^,]+}}{{$}}
88; CHECK: .LBB{{[0-9]+}}_{{[0-9]+}}:
89; CHECK: loop
90; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}
91; CHECK: .LBB{{[0-9]+}}_{{[0-9]+}}:
92; CHECK: end_loop
93; CHECK: end_block
94; CHECK: return{{$}}
95define void @test2(ptr nocapture %p, i32 %n) {
96entry:
97  %cmp.4 = icmp sgt i32 %n, 0
98  br i1 %cmp.4, label %for.body.preheader, label %for.end
99
100for.body.preheader:
101  br label %for.body
102
103for.body:
104  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]
105  %arrayidx = getelementptr inbounds double, ptr %p, i32 %i.05
106  %0 = load double, ptr %arrayidx, align 8
107  %mul = fmul double %0, 3.200000e+00
108  store double %mul, ptr %arrayidx, align 8
109  %inc = add nuw nsw i32 %i.05, 1
110  %exitcond = icmp eq i32 %inc, %n
111  br i1 %exitcond, label %for.end.loopexit, label %for.body
112
113for.end.loopexit:
114  br label %for.end
115
116for.end:
117  ret void
118}
119
120; CHECK-LABEL: doublediamond:
121; CHECK: block   {{$}}
122; CHECK-NEXT: block   {{$}}
123; CHECK: br_if 0, ${{[^,]+}}{{$}}
124; CHECK: br 1{{$}}
125; CHECK: .LBB{{[0-9]+}}_2:
126; CHECK-NEXT: end_block{{$}}
127; CHECK: block   {{$}}
128; CHECK: br_if 0, ${{[^,]+}}{{$}}
129; CHECK: br 1{{$}}
130; CHECK: .LBB{{[0-9]+}}_4:
131; CHECK-NEXT: end_block{{$}}
132; CHECK: .LBB{{[0-9]+}}_5:
133; CHECK-NEXT: end_block{{$}}
134; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
135; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
136define i32 @doublediamond(i32 %a, i32 %b, ptr %p) {
137entry:
138  %c = icmp eq i32 %a, 0
139  %d = icmp eq i32 %b, 0
140  store volatile i32 0, ptr %p
141  br i1 %c, label %true, label %false
142true:
143  store volatile i32 1, ptr %p
144  br label %exit
145false:
146  store volatile i32 2, ptr %p
147  br i1 %d, label %ft, label %ff
148ft:
149  store volatile i32 3, ptr %p
150  br label %exit
151ff:
152  store volatile i32 4, ptr %p
153  br label %exit
154exit:
155  store volatile i32 5, ptr %p
156  ret i32 0
157}
158
159; CHECK-LABEL: triangle:
160; CHECK: block   {{$}}
161; CHECK: br_if 0, $1{{$}}
162; CHECK: .LBB{{[0-9]+}}_2:
163; CHECK: return
164define i32 @triangle(ptr %p, i32 %a) {
165entry:
166  %c = icmp eq i32 %a, 0
167  store volatile i32 0, ptr %p
168  br i1 %c, label %true, label %exit
169true:
170  store volatile i32 1, ptr %p
171  br label %exit
172exit:
173  store volatile i32 2, ptr %p
174  ret i32 0
175}
176
177; CHECK-LABEL: diamond:
178; CHECK: block   {{$}}
179; CHECK: block   {{$}}
180; CHECK: br_if 0, $1{{$}}
181; CHECK: br 1{{$}}
182; CHECK: .LBB{{[0-9]+}}_2:
183; CHECK: .LBB{{[0-9]+}}_3:
184; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
185; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
186define i32 @diamond(ptr %p, i32 %a) {
187entry:
188  %c = icmp eq i32 %a, 0
189  store volatile i32 0, ptr %p
190  br i1 %c, label %true, label %false
191true:
192  store volatile i32 1, ptr %p
193  br label %exit
194false:
195  store volatile i32 2, ptr %p
196  br label %exit
197exit:
198  store volatile i32 3, ptr %p
199  ret i32 0
200}
201
202; CHECK-LABEL: single_block:
203; CHECK-NOT: br
204; CHECK: return $pop{{[0-9]+}}{{$}}
205define i32 @single_block(ptr %p) {
206entry:
207  store volatile i32 0, ptr %p
208  ret i32 0
209}
210
211; CHECK-LABEL: minimal_loop:
212; CHECK-NOT: br
213; CHECK: .LBB{{[0-9]+}}_1:
214; CHECK: loop i32
215; CHECK: i32.store 0($0), $pop{{[0-9]+}}{{$}}
216; CHECK: br 0{{$}}
217; CHECK: .LBB{{[0-9]+}}_2:
218define i32 @minimal_loop(ptr %p) {
219entry:
220  store volatile i32 0, ptr %p
221  br label %loop
222loop:
223  store volatile i32 1, ptr %p
224  br label %loop
225}
226
227; CHECK-LABEL: simple_loop:
228; CHECK-NOT: br
229; CHECK: .LBB{{[0-9]+}}_1:
230; CHECK: loop    {{$}}
231; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}
232; CHECK-NEXT: end_loop{{$}}
233; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
234; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
235define i32 @simple_loop(ptr %p, i32 %a) {
236entry:
237  %c = icmp eq i32 %a, 0
238  store volatile i32 0, ptr %p
239  br label %loop
240loop:
241  store volatile i32 1, ptr %p
242  br i1 %c, label %loop, label %exit
243exit:
244  store volatile i32 2, ptr %p
245  ret i32 0
246}
247
248; CHECK-LABEL: doubletriangle:
249; CHECK: block   {{$}}
250; CHECK: br_if 0, $0{{$}}
251; CHECK: block   {{$}}
252; CHECK: br_if 0, $1{{$}}
253; CHECK: .LBB{{[0-9]+}}_3:
254; CHECK: .LBB{{[0-9]+}}_4:
255; CHECK: return
256define i32 @doubletriangle(i32 %a, i32 %b, ptr %p) {
257entry:
258  %c = icmp eq i32 %a, 0
259  %d = icmp eq i32 %b, 0
260  store volatile i32 0, ptr %p
261  br i1 %c, label %true, label %exit
262true:
263  store volatile i32 2, ptr %p
264  br i1 %d, label %tt, label %tf
265tt:
266  store volatile i32 3, ptr %p
267  br label %tf
268tf:
269  store volatile i32 4, ptr %p
270  br label %exit
271exit:
272  store volatile i32 5, ptr %p
273  ret i32 0
274}
275
276; CHECK-LABEL: ifelse_earlyexits:
277; CHECK: block   {{$}}
278; CHECK: block   {{$}}
279; CHECK: br_if 0, $0{{$}}
280; CHECK: br 1{{$}}
281; CHECK: .LBB{{[0-9]+}}_2:
282; CHECK: br_if 0, $1{{$}}
283; CHECK: .LBB{{[0-9]+}}_4:
284; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
285; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
286define i32 @ifelse_earlyexits(i32 %a, i32 %b, ptr %p) {
287entry:
288  %c = icmp eq i32 %a, 0
289  %d = icmp eq i32 %b, 0
290  store volatile i32 0, ptr %p
291  br i1 %c, label %true, label %false
292true:
293  store volatile i32 1, ptr %p
294  br label %exit
295false:
296  store volatile i32 2, ptr %p
297  br i1 %d, label %ft, label %exit
298ft:
299  store volatile i32 3, ptr %p
300  br label %exit
301exit:
302  store volatile i32 4, ptr %p
303  ret i32 0
304}
305
306; CHECK-LABEL: doublediamond_in_a_loop:
307; CHECK: .LBB{{[0-9]+}}_1:
308; CHECK: loop i32{{$}}
309; CHECK: block   {{$}}
310; CHECK: br_if           0, $0{{$}}
311; CHECK: br              1{{$}}
312; CHECK: .LBB{{[0-9]+}}_3:
313; CHECK: end_block{{$}}
314; CHECK: block   {{$}}
315; CHECK: br_if           0, $1{{$}}
316; CHECK: br              1{{$}}
317; CHECK: .LBB{{[0-9]+}}_5:
318; CHECK: br              0{{$}}
319; CHECK: .LBB{{[0-9]+}}_6:
320; CHECK-NEXT: end_loop{{$}}
321define i32 @doublediamond_in_a_loop(i32 %a, i32 %b, ptr %p) {
322entry:
323  br label %header
324header:
325  %c = icmp eq i32 %a, 0
326  %d = icmp eq i32 %b, 0
327  store volatile i32 0, ptr %p
328  br i1 %c, label %true, label %false
329true:
330  store volatile i32 1, ptr %p
331  br label %exit
332false:
333  store volatile i32 2, ptr %p
334  br i1 %d, label %ft, label %ff
335ft:
336  store volatile i32 3, ptr %p
337  br label %exit
338ff:
339  store volatile i32 4, ptr %p
340  br label %exit
341exit:
342  store volatile i32 5, ptr %p
343  br label %header
344}
345
346; Test that nested loops are handled.
347
348; CHECK-LABEL: test3:
349; CHECK: loop
350; CHECK-NEXT: br_if
351; CHECK-NEXT: .LBB{{[0-9]+}}_{{[0-9]+}}:
352; CHECK-NEXT: loop
353declare void @bar()
354define void @test3(i32 %w, i32 %x)  {
355entry:
356  br i1 undef, label %outer.ph, label %exit
357
358outer.ph:
359  br label %outer
360
361outer:
362  %tobool = icmp eq i32 %x, 0
363  br i1 %tobool, label %inner, label %unreachable
364
365unreachable:
366  unreachable
367
368inner:
369  %c = icmp eq i32 %x, %w
370  br i1 %c, label %if.end, label %inner
371
372exit:
373  ret void
374
375if.end:
376  call void @bar()
377  br label %outer
378}
379
380; Test switch lowering and block placement.
381
382; CHECK-LABEL: test4:
383; CHECK-NEXT: .functype test4 (i32) -> (){{$}}
384; CHECK-NEXT: block   {{$}}
385; CHECK-NEXT: block   {{$}}
386; CHECK-NEXT: br_table   $0, 1, 1, 1, 1, 1, 0{{$}}
387; CHECK-NEXT: .LBB{{[0-9]+}}_1:
388; CHECK-NEXT: end_block{{$}}
389; CHECK-NEXT: i32.const $push[[C:[0-9]+]]=, 622{{$}}
390; CHECK-NEXT: i32.eq $drop=, $0, $pop[[C]]{{$}}
391; CHECK-NEXT: .LBB{{[0-9]+}}_2:
392; CHECK-NEXT: end_block{{$}}
393; CHECK-NEXT: return{{$}}
394define void @test4(i32 %t) {
395entry:
396  switch i32 %t, label %default [
397    i32 0, label %bb2
398    i32 2, label %bb2
399    i32 4, label %bb1
400    i32 622, label %bb0
401  ]
402
403bb0:
404  ret void
405
406bb1:
407  ret void
408
409bb2:
410  ret void
411
412default:
413  ret void
414}
415
416; Test a case where the BLOCK needs to be placed before the LOOP in the
417; same basic block.
418
419; CHECK-LABEL: test5:
420; CHECK:       .LBB{{[0-9]+}}_1:
421; CHECK-NEXT:  block   {{$}}
422; CHECK-NEXT:  loop    {{$}}
423; CHECK:       br_if 1, {{[^,]+}}{{$}}
424; CHECK:       br_if 0, {{[^,]+}}{{$}}
425; CHECK-NEXT:  end_loop{{$}}
426; CHECK:       return{{$}}
427; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
428; CHECK:       return{{$}}
429define void @test5(i1 %p, i1 %q) {
430entry:
431  br label %header
432
433header:
434  store volatile i32 0, ptr null
435  br i1 %p, label %more, label %alt
436
437more:
438  store volatile i32 1, ptr null
439  br i1 %q, label %header, label %return
440
441alt:
442  store volatile i32 2, ptr null
443  ret void
444
445return:
446  store volatile i32 3, ptr null
447  ret void
448}
449
450; Test an interesting case of a loop with multiple exits, which
451; aren't to layout successors of the loop, and one of which is to a successors
452; which has another predecessor.
453
454; CHECK-LABEL: test6:
455; CHECK:       .LBB{{[0-9]+}}_1:
456; CHECK-NEXT:  block   {{$}}
457; CHECK-NEXT:  block   {{$}}
458; CHECK-NEXT:  loop    {{$}}
459; CHECK-NOT:   block
460; CHECK:       br_if 2, {{[^,]+}}{{$}}
461; CHECK-NOT:   block
462; CHECK:       br_if 1, {{[^,]+}}{{$}}
463; CHECK-NOT:   block
464; CHECK:       br_if 0, {{[^,]+}}{{$}}
465; CHECK-NEXT:  end_loop{{$}}
466; CHECK-NOT:   block
467; CHECK:       return{{$}}
468; CHECK-NEXT:  .LBB{{[0-9]+}}_5:
469; CHECK-NEXT:  end_block{{$}}
470; CHECK-NOT:   block
471; CHECK:       .LBB{{[0-9]+}}_6:
472; CHECK-NEXT:  end_block{{$}}
473; CHECK-NOT:   block
474; CHECK:       return{{$}}
475define void @test6(i1 %p, i1 %q) {
476entry:
477  br label %header
478
479header:
480  store volatile i32 0, ptr null
481  br i1 %p, label %more, label %second
482
483more:
484  store volatile i32 1, ptr null
485  br i1 %q, label %evenmore, label %first
486
487evenmore:
488  store volatile i32 1, ptr null
489  br i1 %q, label %header, label %return
490
491return:
492  store volatile i32 2, ptr null
493  ret void
494
495first:
496  store volatile i32 3, ptr null
497  br label %second
498
499second:
500  store volatile i32 4, ptr null
501  ret void
502}
503
504; Test a case where there are multiple backedges and multiple loop exits
505; that end in unreachable.
506
507; CHECK-LABEL: test7:
508; CHECK:       .LBB{{[0-9]+}}_1:
509; CHECK-NEXT:  loop    {{$}}
510; CHECK-NOT:   block
511; CHECK:       block   {{$}}
512; CHECK:       br_if 0, {{[^,]+}}{{$}}
513; CHECK-NOT:   block
514; CHECK:       br_if 1, {{[^,]+}}{{$}}
515; CHECK-NOT:   block
516; CHECK:       unreachable
517; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
518; CHECK-NEXT:  end_block{{$}}
519; CHECK-NOT:   block
520; CHECK:       br_if 0, {{[^,]+}}{{$}}
521; CHECK-NEXT:  end_loop{{$}}
522; CHECK-NOT:   block
523; CHECK:       unreachable
524define void @test7(i1 %tobool2, i1 %tobool9) {
525entry:
526  store volatile i32 0, ptr null
527  br label %loop
528
529loop:
530  store volatile i32 1, ptr null
531  br i1 %tobool2, label %l1, label %l0
532
533l0:
534  store volatile i32 2, ptr null
535  br i1 %tobool9, label %loop, label %u0
536
537l1:
538  store volatile i32 3, ptr null
539  br i1 %tobool9, label %loop, label %u1
540
541u0:
542  store volatile i32 4, ptr null
543  unreachable
544
545u1:
546  store volatile i32 5, ptr null
547  unreachable
548}
549
550; Test an interesting case using nested loops and switches.
551
552; CHECK-LABEL: test8:
553; CHECK:       .LBB{{[0-9]+}}_1:
554; CHECK-NEXT:  loop i32{{$}}
555; CHECK-NEXT:  i32.const $push{{[^,]+}}, 0{{$}}
556; CHECK-NEXT:  br_if    0, {{[^,]+}}{{$}}
557; CHECK-NEXT:  br       0{{$}}
558; CHECK-NEXT:  .LBB{{[0-9]+}}_2:
559; CHECK-NEXT:  end_loop{{$}}
560define i32 @test8() {
561bb:
562  br label %bb1
563
564bb1:
565  br i1 undef, label %bb2, label %bb3
566
567bb2:
568  switch i8 undef, label %bb1 [
569    i8 44, label %bb2
570  ]
571
572bb3:
573  switch i8 undef, label %bb1 [
574    i8 44, label %bb2
575  ]
576}
577
578; Test an interesting case using nested loops that share a bottom block.
579
580; CHECK-LABEL: test9:
581; CHECK:       .LBB{{[0-9]+}}_1:
582; CHECK-NEXT:  block   {{$}}
583; CHECK-NEXT:  loop    {{$}}
584; CHECK-NOT:   block
585; CHECK:       br_if     1, {{[^,]+}}{{$}}
586; CHECK-NEXT:  .LBB{{[0-9]+}}_2:
587; CHECK-NEXT:  loop    {{$}}
588; CHECK-NOT:   block
589; CHECK:       block   {{$}}
590; CHECK-NOT:   block
591; CHECK:       br_if     0, {{[^,]+}}{{$}}
592; CHECK-NOT:   block
593; CHECK:       br_if     2, {{[^,]+}}{{$}}
594; CHECK-NEXT:  br        1{{$}}
595; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
596; CHECK-NEXT:  end_block{{$}}
597; CHECK-NOT:   block
598; CHECK:       br_if     1, {{[^,]+}}{{$}}
599; CHECK-NEXT:  br        0{{$}}
600; CHECK-NEXT:  .LBB{{[0-9]+}}_5:
601; CHECK-NOT:   block
602; CHECK:       end_block
603; CHECK-NOT:   block
604; CHECK:       return{{$}}
605declare i1 @a()
606define void @test9() {
607entry:
608  store volatile i32 0, ptr null
609  br label %header
610
611header:
612  store volatile i32 1, ptr null
613  %call4 = call i1 @a()
614  br i1 %call4, label %header2, label %end
615
616header2:
617  store volatile i32 2, ptr null
618  %call = call i1 @a()
619  br i1 %call, label %if.then, label %if.else
620
621if.then:
622  store volatile i32 3, ptr null
623  %call3 = call i1 @a()
624  br i1 %call3, label %header2, label %header
625
626if.else:
627  store volatile i32 4, ptr null
628  %call2 = call i1 @a()
629  br i1 %call2, label %header2, label %header
630
631end:
632  store volatile i32 5, ptr null
633  ret void
634}
635
636; Test an interesting case involving nested loops sharing a loop bottom,
637; and loop exits to a block with unreachable.
638
639; CHECK-LABEL: test10:
640; CHECK:       .LBB{{[0-9]+}}_1:
641; CHECK-NEXT:  loop    {{$}}
642; CHECK:       br_if     0, {{[^,]+}}{{$}}
643; CHECK:       .LBB{{[0-9]+}}_3:
644; CHECK-NEXT:  block   {{$}}
645; CHECK-NEXT:  loop    {{$}}
646; CHECK:       .LBB{{[0-9]+}}_4:
647; CHECK-NEXT:  loop    {{$}}
648; CHECK:       br_if     0, {{[^,]+}}{{$}}
649; CHECK-NEXT:  end_loop{{$}}
650; CHECK-NEXT:  block   {{$}}
651; CHECK-NOT:   br_if
652; CHECK:       br_table   $pop{{[^,]+}}, 0, 3, 1, 2, 3
653; CHECK-NEXT:  .LBB{{[0-9]+}}_6:
654; CHECK-NEXT:  end_block{{$}}
655; CHECK-NEXT:  end_loop{{$}}
656; CHECK-NEXT:  return{{$}}
657; CHECK-NEXT:  .LBB{{[0-9]+}}_7:
658; CHECK-NEXT:  end_block{{$}}
659; CHECK:       br        0{{$}}
660; CHECK-NEXT:  .LBB{{[0-9]+}}_8:
661; CHECK-NEXT:  end_loop{{$}}
662define void @test10() {
663bb0:
664  br label %bb1
665
666bb1:
667  %tmp = phi i32 [ 2, %bb0 ], [ 3, %bb3 ]
668  %tmp3 = phi i32 [ undef, %bb0 ], [ %tmp11, %bb3 ]
669  %tmp4 = icmp eq i32 %tmp3, 0
670  br i1 %tmp4, label %bb4, label %bb2
671
672bb2:
673  br label %bb3
674
675bb3:
676  %tmp11 = phi i32 [ 1, %bb5 ], [ 0, %bb2 ]
677  br label %bb1
678
679bb4:
680  %tmp6 = phi i32 [ %tmp9, %bb5 ], [ 4, %bb1 ]
681  %tmp7 = phi i32 [ %tmp6, %bb5 ], [ %tmp, %bb1 ]
682  br label %bb5
683
684bb5:
685  %tmp9 = phi i32 [ %tmp6, %bb5 ], [ %tmp7, %bb4 ]
686  switch i32 %tmp9, label %bb2 [
687    i32 0, label %bb5
688    i32 1, label %bb6
689    i32 3, label %bb4
690    i32 4, label %bb3
691  ]
692
693bb6:
694  ret void
695}
696
697; Test a CFG DAG with interesting merging.
698
699; CHECK-LABEL: test11:
700; CHECK:       block   {{$}}
701; CHECK-NEXT:  block   {{$}}
702; CHECK-NEXT:  block   {{$}}
703; CHECK-NEXT:  block   {{$}}
704; CHECK:       br_if        0, {{[^,]+}}{{$}}
705; CHECK-NOT:   block
706; CHECK:       block   {{$}}
707; CHECK-NEXT:  i32.const
708; CHECK-NEXT:  br_if        0, {{[^,]+}}{{$}}
709; CHECK-NOT:   block
710; CHECK:       br_if        2, {{[^,]+}}{{$}}
711; CHECK-NEXT:  .LBB{{[0-9]+}}_3:
712; CHECK-NEXT:  end_block{{$}}
713; CHECK-NOT:   block
714; CHECK:       return{{$}}
715; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
716; CHECK-NEXT:  end_block{{$}}
717; CHECK-NOT:   block
718; CHECK:       br_if        1, {{[^,]+}}{{$}}
719; CHECK-NOT:   block
720; CHECK:       br_if        2, {{[^,]+}}{{$}}
721; CHECK-NEXT:  .LBB{{[0-9]+}}_6:
722; CHECK-NEXT:  end_block{{$}}
723; CHECK-NOT:   block
724; CHECK:       return{{$}}
725; CHECK-NEXT:  .LBB{{[0-9]+}}_7:
726; CHECK-NEXT:  end_block{{$}}
727; CHECK-NOT:   block
728; CHECK:       return{{$}}
729; CHECK-NEXT:  .LBB{{[0-9]+}}_8:
730; CHECK-NEXT:  end_block{{$}}
731; CHECK-NOT:   block
732; CHECK:       return{{$}}
733define void @test11() {
734bb0:
735  store volatile i32 0, ptr null
736  br i1 undef, label %bb1, label %bb4
737bb1:
738  store volatile i32 1, ptr null
739  br i1 undef, label %bb3, label %bb2
740bb2:
741  store volatile i32 2, ptr null
742  br i1 undef, label %bb3, label %bb7
743bb3:
744  store volatile i32 3, ptr null
745  ret void
746bb4:
747  store volatile i32 4, ptr null
748  br i1 undef, label %bb8, label %bb5
749bb5:
750  store volatile i32 5, ptr null
751  br i1 undef, label %bb6, label %bb7
752bb6:
753  store volatile i32 6, ptr null
754  ret void
755bb7:
756  store volatile i32 7, ptr null
757  ret void
758bb8:
759  store volatile i32 8, ptr null
760  ret void
761}
762
763; CHECK-LABEL: test12:
764; CHECK:       .LBB{{[0-9]+}}_1:
765; CHECK-NEXT:  block   {{$}}
766; CHECK-NEXT:  loop    {{$}}
767; CHECK-NEXT:  block   {{$}}
768; CHECK-NEXT:  block   {{$}}
769; CHECK:       br_table  {{[^,]+}}, 1, 3, 3, 3, 1, 0{{$}}
770; CHECK-NEXT:  .LBB{{[0-9]+}}_2:
771; CHECK-NEXT:  end_block{{$}}
772; CHECK:       br_if     0, {{[^,]+}}{{$}}
773; CHECK:       br_if     2, {{[^,]+}}{{$}}
774; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
775; CHECK-NEXT:  end_block{{$}}
776; CHECK:       br        0{{$}}
777; CHECK-NEXT:  .LBB{{[0-9]+}}_5:
778; CHECK-NEXT:  end_loop{{$}}
779; CHECK-NEXT:  end_block{{$}}
780; CHECK-NEXT:  return{{$}}
781define void @test12(ptr %arg) {
782bb:
783  br label %bb1
784
785bb1:
786  %tmp = phi i32 [ 0, %bb ], [ %tmp5, %bb4 ]
787  %tmp2 = getelementptr i8, ptr %arg, i32 %tmp
788  %tmp3 = load i8, ptr %tmp2
789  switch i8 %tmp3, label %bb7 [
790    i8 42, label %bb4
791    i8 76, label %bb4
792    i8 108, label %bb4
793    i8 104, label %bb4
794  ]
795
796bb4:
797  %tmp5 = add i32 %tmp, 1
798  br label %bb1
799
800bb7:
801  ret void
802}
803
804; A block can be "branched to" from another even if it is also reachable via
805; fallthrough from the other. This would normally be optimized away, so use
806; optnone to disable optimizations to test this case.
807
808; CHECK-LABEL: test13:
809; CHECK:       block   {{$}}
810; CHECK-NEXT:  block   {{$}}
811; CHECK:       br_if 0, $pop0{{$}}
812; CHECK:       block   {{$}}
813; CHECK:       br_if 0, $pop3{{$}}
814; CHECK:       .LBB{{[0-9]+}}_3:
815; CHECK-NEXT:  end_block{{$}}
816; CHECK:       br_if 1, $pop{{[0-9]+}}{{$}}
817; CHECK-NEXT:  br 1{{$}}
818; CHECK-NEXT:  .LBB{{[0-9]+}}_4:
819; CHECK-NEXT:  end_block{{$}}
820; CHECK-NEXT:  return{{$}}
821; CHECK-NEXT:  .LBB{{[0-9]+}}_5:
822; CHECK-NEXT:  end_block{{$}}
823; CHECK-NEXT:  unreachable{{$}}
824define void @test13() noinline optnone {
825bb:
826  br i1 undef, label %bb5, label %bb2
827bb1:
828  unreachable
829bb2:
830  br i1 undef, label %bb3, label %bb4
831bb3:
832  br label %bb4
833bb4:
834  %tmp = phi i1 [ false, %bb2 ], [ false, %bb3 ]
835  br i1 %tmp, label %bb1, label %bb1
836bb5:
837  ret void
838}
839
840; Test a case with a single-block loop that has another loop
841; as a successor. The end_loop for the first loop should go
842; before the loop for the second.
843
844; CHECK-LABEL: test14:
845; CHECK:      .LBB{{[0-9]+}}_1:{{$}}
846; CHECK-NEXT:     loop    {{$}}
847; CHECK-NEXT:     i32.const   $push0=, 0{{$}}
848; CHECK-NEXT:     br_if       0, $pop0{{$}}
849; CHECK-NEXT:     end_loop{{$}}
850; CHECK-NEXT: .LBB{{[0-9]+}}_3:{{$}}
851; CHECK-NEXT:     loop    {{$}}
852; CHECK-NEXT:     i32.const   $push1=, 0{{$}}
853; CHECK-NEXT:     br_if       0, $pop1{{$}}
854; CHECK-NEXT:     end_loop{{$}}
855; CHECK-NEXT:     return{{$}}
856define void @test14() {
857bb:
858  br label %bb1
859
860bb1:
861  %tmp = bitcast i1 undef to i1
862  br i1 %tmp, label %bb3, label %bb1
863
864bb3:
865  br label %bb4
866
867bb4:
868  br i1 undef, label %bb7, label %bb48
869
870bb7:
871  br i1 undef, label %bb12, label %bb12
872
873bb12:
874  br i1 undef, label %bb17, label %bb17
875
876bb17:
877  br i1 undef, label %bb22, label %bb22
878
879bb22:
880  br i1 undef, label %bb27, label %bb27
881
882bb27:
883  br i1 undef, label %bb30, label %bb30
884
885bb30:
886  br i1 undef, label %bb35, label %bb35
887
888bb35:
889  br i1 undef, label %bb38, label %bb38
890
891bb38:
892  br i1 undef, label %bb48, label %bb48
893
894bb48:
895  %tmp49 = bitcast i1 undef to i1
896  br i1 %tmp49, label %bb3, label %bb50
897
898bb50:
899  ret void
900}
901
902; Test that a block boundary which ends one block, begins another block, and
903; also begins a loop, has the markers placed in the correct order.
904
905; CHECK-LABEL: test15:
906; CHECK:        block
907; CHECK-NEXT:   block
908; CHECK:        br_if       0, $pop{{.*}}{{$}}
909; CHECK:        .LBB{{[0-9]+}}_2:
910; CHECK-NEXT:   block   {{$}}
911; CHECK-NEXT:   block   {{$}}
912; CHECK-NEXT:   loop    {{$}}
913; CHECK:        br_if       1, $pop{{.*}}{{$}}
914; CHECK:        br_if       0, ${{.*}}{{$}}
915; CHECK-NEXT:   br          2{{$}}
916; CHECK-NEXT:   .LBB{{[0-9]+}}_4:
917; CHECK-NEXT:   end_loop{{$}}
918; CHECK:        .LBB{{[0-9]+}}_5:
919; CHECK-NEXT:   end_block{{$}}
920; CHECK:        br_if       1, $pop{{.*}}{{$}}
921; CHECK:        return{{$}}
922; CHECK:        .LBB{{[0-9]+}}_7:
923; CHECK-NEXT:   end_block{{$}}
924; CHECK:        .LBB{{[0-9]+}}_8:
925; CHECK-NEXT:   end_block{{$}}
926; CHECK-NEXT:   return{{$}}
927%0 = type { i8, i32 }
928declare void @test15_callee0()
929declare void @test15_callee1()
930define void @test15() {
931bb:
932  %tmp1 = icmp eq i8 1, 0
933  br i1 %tmp1, label %bb2, label %bb14
934
935bb2:
936  %tmp3 = phi ptr [ %tmp6, %bb5 ], [ null, %bb ]
937  %tmp4 = icmp eq i32 0, 11
938  br i1 %tmp4, label %bb5, label %bb8
939
940bb5:
941  %tmp = bitcast ptr null to ptr
942  %tmp6 = getelementptr ptr, ptr %tmp3, i32 1
943  %tmp7 = icmp eq ptr %tmp6, null
944  br i1 %tmp7, label %bb10, label %bb2
945
946bb8:
947  %tmp9 = icmp eq ptr null, undef
948  br label %bb10
949
950bb10:
951  %tmp11 = phi ptr [ null, %bb8 ], [ %tmp, %bb5 ]
952  %tmp12 = icmp eq ptr null, %tmp11
953  br i1 %tmp12, label %bb15, label %bb13
954
955bb13:
956  call void @test15_callee0()
957  ret void
958
959bb14:
960  call void @test15_callee1()
961  ret void
962
963bb15:
964  ret void
965}
966