966 lines · plain
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 %s2 3; Test the CFG stackifier pass.4 5; Explicitly disable fast-isel, since it gets implicitly enabled in the6; 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: loop16; CHECK-NEXT: block17; CHECK: i32.lt_s18; CHECK-NEXT: br_if19; CHECK-NEXT: return20; CHECK-NEXT: .LBB{{[0-9]+}}_3:21; CHECK-NEXT: end_block22; CHECK-NEXT: i32.const23; CHECK-NEXT: i32.add24; CHECK-NEXT: call25; CHECK-NEXT: br26; CHECK-NEXT: .LBB{{[0-9]+}}_4:27; CHECK-NEXT: end_loop28define void @test0(i32 %n) {29entry:30 br label %header31 32header:33 %i = phi i32 [ 0, %entry ], [ %i.next, %back ]34 %i.next = add i32 %i, 135 36 %c = icmp slt i32 %i.next, %n37 br i1 %c, label %back, label %exit38 39exit:40 ret void41 42back:43 call void @something()44 br label %header45}46 47; Same as test0, but the branch condition is reversed.48 49; CHECK-LABEL: test1:50; CHECK: loop51; CHECK-NEXT: block52; CHECK: i32.lt_s53; CHECK-NEXT: br_if54; CHECK-NEXT: return55; CHECK-NEXT: .LBB{{[0-9]+}}_3:56; CHECK-NEXT: end_block57; CHECK-NEXT: i32.const58; CHECK-NEXT: i32.add59; CHECK-NEXT: call60; CHECK-NEXT: br61; CHECK-NEXT: .LBB{{[0-9]+}}_4:62; CHECK-NEXT: end_loop63define void @test1(i32 %n) {64entry:65 br label %header66 67header:68 %i = phi i32 [ 0, %entry ], [ %i.next, %back ]69 %i.next = add i32 %i, 170 71 %c = icmp sge i32 %i.next, %n72 br i1 %c, label %exit, label %back73 74exit:75 ret void76 77back:78 call void @something()79 br label %header80}81 82; Test that a simple loop is handled as expected.83 84; CHECK-LABEL: test2:85; CHECK-NOT: local86; CHECK: block {{$}}87; CHECK: br_if 0, {{[^,]+}}{{$}}88; CHECK: .LBB{{[0-9]+}}_{{[0-9]+}}:89; CHECK: loop90; CHECK: br_if 0, $pop{{[0-9]+}}{{$}}91; CHECK: .LBB{{[0-9]+}}_{{[0-9]+}}:92; CHECK: end_loop93; CHECK: end_block94; CHECK: return{{$}}95define void @test2(ptr nocapture %p, i32 %n) {96entry:97 %cmp.4 = icmp sgt i32 %n, 098 br i1 %cmp.4, label %for.body.preheader, label %for.end99 100for.body.preheader:101 br label %for.body102 103for.body:104 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]105 %arrayidx = getelementptr inbounds double, ptr %p, i32 %i.05106 %0 = load double, ptr %arrayidx, align 8107 %mul = fmul double %0, 3.200000e+00108 store double %mul, ptr %arrayidx, align 8109 %inc = add nuw nsw i32 %i.05, 1110 %exitcond = icmp eq i32 %inc, %n111 br i1 %exitcond, label %for.end.loopexit, label %for.body112 113for.end.loopexit:114 br label %for.end115 116for.end:117 ret void118}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, 0139 %d = icmp eq i32 %b, 0140 store volatile i32 0, ptr %p141 br i1 %c, label %true, label %false142true:143 store volatile i32 1, ptr %p144 br label %exit145false:146 store volatile i32 2, ptr %p147 br i1 %d, label %ft, label %ff148ft:149 store volatile i32 3, ptr %p150 br label %exit151ff:152 store volatile i32 4, ptr %p153 br label %exit154exit:155 store volatile i32 5, ptr %p156 ret i32 0157}158 159; CHECK-LABEL: triangle:160; CHECK: block {{$}}161; CHECK: br_if 0, $1{{$}}162; CHECK: .LBB{{[0-9]+}}_2:163; CHECK: return164define i32 @triangle(ptr %p, i32 %a) {165entry:166 %c = icmp eq i32 %a, 0167 store volatile i32 0, ptr %p168 br i1 %c, label %true, label %exit169true:170 store volatile i32 1, ptr %p171 br label %exit172exit:173 store volatile i32 2, ptr %p174 ret i32 0175}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, 0189 store volatile i32 0, ptr %p190 br i1 %c, label %true, label %false191true:192 store volatile i32 1, ptr %p193 br label %exit194false:195 store volatile i32 2, ptr %p196 br label %exit197exit:198 store volatile i32 3, ptr %p199 ret i32 0200}201 202; CHECK-LABEL: single_block:203; CHECK-NOT: br204; CHECK: return $pop{{[0-9]+}}{{$}}205define i32 @single_block(ptr %p) {206entry:207 store volatile i32 0, ptr %p208 ret i32 0209}210 211; CHECK-LABEL: minimal_loop:212; CHECK-NOT: br213; CHECK: .LBB{{[0-9]+}}_1:214; CHECK: loop i32215; 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 %p221 br label %loop222loop:223 store volatile i32 1, ptr %p224 br label %loop225}226 227; CHECK-LABEL: simple_loop:228; CHECK-NOT: br229; 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, 0238 store volatile i32 0, ptr %p239 br label %loop240loop:241 store volatile i32 1, ptr %p242 br i1 %c, label %loop, label %exit243exit:244 store volatile i32 2, ptr %p245 ret i32 0246}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: return256define i32 @doubletriangle(i32 %a, i32 %b, ptr %p) {257entry:258 %c = icmp eq i32 %a, 0259 %d = icmp eq i32 %b, 0260 store volatile i32 0, ptr %p261 br i1 %c, label %true, label %exit262true:263 store volatile i32 2, ptr %p264 br i1 %d, label %tt, label %tf265tt:266 store volatile i32 3, ptr %p267 br label %tf268tf:269 store volatile i32 4, ptr %p270 br label %exit271exit:272 store volatile i32 5, ptr %p273 ret i32 0274}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, 0289 %d = icmp eq i32 %b, 0290 store volatile i32 0, ptr %p291 br i1 %c, label %true, label %false292true:293 store volatile i32 1, ptr %p294 br label %exit295false:296 store volatile i32 2, ptr %p297 br i1 %d, label %ft, label %exit298ft:299 store volatile i32 3, ptr %p300 br label %exit301exit:302 store volatile i32 4, ptr %p303 ret i32 0304}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 %header324header:325 %c = icmp eq i32 %a, 0326 %d = icmp eq i32 %b, 0327 store volatile i32 0, ptr %p328 br i1 %c, label %true, label %false329true:330 store volatile i32 1, ptr %p331 br label %exit332false:333 store volatile i32 2, ptr %p334 br i1 %d, label %ft, label %ff335ft:336 store volatile i32 3, ptr %p337 br label %exit338ff:339 store volatile i32 4, ptr %p340 br label %exit341exit:342 store volatile i32 5, ptr %p343 br label %header344}345 346; Test that nested loops are handled.347 348; CHECK-LABEL: test3:349; CHECK: loop350; CHECK-NEXT: br_if351; CHECK-NEXT: .LBB{{[0-9]+}}_{{[0-9]+}}:352; CHECK-NEXT: loop353declare void @bar()354define void @test3(i32 %w, i32 %x) {355entry:356 br i1 undef, label %outer.ph, label %exit357 358outer.ph:359 br label %outer360 361outer:362 %tobool = icmp eq i32 %x, 0363 br i1 %tobool, label %inner, label %unreachable364 365unreachable:366 unreachable367 368inner:369 %c = icmp eq i32 %x, %w370 br i1 %c, label %if.end, label %inner371 372exit:373 ret void374 375if.end:376 call void @bar()377 br label %outer378}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 %bb2398 i32 2, label %bb2399 i32 4, label %bb1400 i32 622, label %bb0401 ]402 403bb0:404 ret void405 406bb1:407 ret void408 409bb2:410 ret void411 412default:413 ret void414}415 416; Test a case where the BLOCK needs to be placed before the LOOP in the417; 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 %header432 433header:434 store volatile i32 0, ptr null435 br i1 %p, label %more, label %alt436 437more:438 store volatile i32 1, ptr null439 br i1 %q, label %header, label %return440 441alt:442 store volatile i32 2, ptr null443 ret void444 445return:446 store volatile i32 3, ptr null447 ret void448}449 450; Test an interesting case of a loop with multiple exits, which451; aren't to layout successors of the loop, and one of which is to a successors452; 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: block460; CHECK: br_if 2, {{[^,]+}}{{$}}461; CHECK-NOT: block462; CHECK: br_if 1, {{[^,]+}}{{$}}463; CHECK-NOT: block464; CHECK: br_if 0, {{[^,]+}}{{$}}465; CHECK-NEXT: end_loop{{$}}466; CHECK-NOT: block467; CHECK: return{{$}}468; CHECK-NEXT: .LBB{{[0-9]+}}_5:469; CHECK-NEXT: end_block{{$}}470; CHECK-NOT: block471; CHECK: .LBB{{[0-9]+}}_6:472; CHECK-NEXT: end_block{{$}}473; CHECK-NOT: block474; CHECK: return{{$}}475define void @test6(i1 %p, i1 %q) {476entry:477 br label %header478 479header:480 store volatile i32 0, ptr null481 br i1 %p, label %more, label %second482 483more:484 store volatile i32 1, ptr null485 br i1 %q, label %evenmore, label %first486 487evenmore:488 store volatile i32 1, ptr null489 br i1 %q, label %header, label %return490 491return:492 store volatile i32 2, ptr null493 ret void494 495first:496 store volatile i32 3, ptr null497 br label %second498 499second:500 store volatile i32 4, ptr null501 ret void502}503 504; Test a case where there are multiple backedges and multiple loop exits505; that end in unreachable.506 507; CHECK-LABEL: test7:508; CHECK: .LBB{{[0-9]+}}_1:509; CHECK-NEXT: loop {{$}}510; CHECK-NOT: block511; CHECK: block {{$}}512; CHECK: br_if 0, {{[^,]+}}{{$}}513; CHECK-NOT: block514; CHECK: br_if 1, {{[^,]+}}{{$}}515; CHECK-NOT: block516; CHECK: unreachable517; CHECK-NEXT: .LBB{{[0-9]+}}_4:518; CHECK-NEXT: end_block{{$}}519; CHECK-NOT: block520; CHECK: br_if 0, {{[^,]+}}{{$}}521; CHECK-NEXT: end_loop{{$}}522; CHECK-NOT: block523; CHECK: unreachable524define void @test7(i1 %tobool2, i1 %tobool9) {525entry:526 store volatile i32 0, ptr null527 br label %loop528 529loop:530 store volatile i32 1, ptr null531 br i1 %tobool2, label %l1, label %l0532 533l0:534 store volatile i32 2, ptr null535 br i1 %tobool9, label %loop, label %u0536 537l1:538 store volatile i32 3, ptr null539 br i1 %tobool9, label %loop, label %u1540 541u0:542 store volatile i32 4, ptr null543 unreachable544 545u1:546 store volatile i32 5, ptr null547 unreachable548}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 %bb1563 564bb1:565 br i1 undef, label %bb2, label %bb3566 567bb2:568 switch i8 undef, label %bb1 [569 i8 44, label %bb2570 ]571 572bb3:573 switch i8 undef, label %bb1 [574 i8 44, label %bb2575 ]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: block585; CHECK: br_if 1, {{[^,]+}}{{$}}586; CHECK-NEXT: .LBB{{[0-9]+}}_2:587; CHECK-NEXT: loop {{$}}588; CHECK-NOT: block589; CHECK: block {{$}}590; CHECK-NOT: block591; CHECK: br_if 0, {{[^,]+}}{{$}}592; CHECK-NOT: block593; CHECK: br_if 2, {{[^,]+}}{{$}}594; CHECK-NEXT: br 1{{$}}595; CHECK-NEXT: .LBB{{[0-9]+}}_4:596; CHECK-NEXT: end_block{{$}}597; CHECK-NOT: block598; CHECK: br_if 1, {{[^,]+}}{{$}}599; CHECK-NEXT: br 0{{$}}600; CHECK-NEXT: .LBB{{[0-9]+}}_5:601; CHECK-NOT: block602; CHECK: end_block603; CHECK-NOT: block604; CHECK: return{{$}}605declare i1 @a()606define void @test9() {607entry:608 store volatile i32 0, ptr null609 br label %header610 611header:612 store volatile i32 1, ptr null613 %call4 = call i1 @a()614 br i1 %call4, label %header2, label %end615 616header2:617 store volatile i32 2, ptr null618 %call = call i1 @a()619 br i1 %call, label %if.then, label %if.else620 621if.then:622 store volatile i32 3, ptr null623 %call3 = call i1 @a()624 br i1 %call3, label %header2, label %header625 626if.else:627 store volatile i32 4, ptr null628 %call2 = call i1 @a()629 br i1 %call2, label %header2, label %header630 631end:632 store volatile i32 5, ptr null633 ret void634}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_if652; CHECK: br_table $pop{{[^,]+}}, 0, 3, 1, 2, 3653; 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 %bb1665 666bb1:667 %tmp = phi i32 [ 2, %bb0 ], [ 3, %bb3 ]668 %tmp3 = phi i32 [ undef, %bb0 ], [ %tmp11, %bb3 ]669 %tmp4 = icmp eq i32 %tmp3, 0670 br i1 %tmp4, label %bb4, label %bb2671 672bb2:673 br label %bb3674 675bb3:676 %tmp11 = phi i32 [ 1, %bb5 ], [ 0, %bb2 ]677 br label %bb1678 679bb4:680 %tmp6 = phi i32 [ %tmp9, %bb5 ], [ 4, %bb1 ]681 %tmp7 = phi i32 [ %tmp6, %bb5 ], [ %tmp, %bb1 ]682 br label %bb5683 684bb5:685 %tmp9 = phi i32 [ %tmp6, %bb5 ], [ %tmp7, %bb4 ]686 switch i32 %tmp9, label %bb2 [687 i32 0, label %bb5688 i32 1, label %bb6689 i32 3, label %bb4690 i32 4, label %bb3691 ]692 693bb6:694 ret void695}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: block706; CHECK: block {{$}}707; CHECK-NEXT: i32.const708; CHECK-NEXT: br_if 0, {{[^,]+}}{{$}}709; CHECK-NOT: block710; CHECK: br_if 2, {{[^,]+}}{{$}}711; CHECK-NEXT: .LBB{{[0-9]+}}_3:712; CHECK-NEXT: end_block{{$}}713; CHECK-NOT: block714; CHECK: return{{$}}715; CHECK-NEXT: .LBB{{[0-9]+}}_4:716; CHECK-NEXT: end_block{{$}}717; CHECK-NOT: block718; CHECK: br_if 1, {{[^,]+}}{{$}}719; CHECK-NOT: block720; CHECK: br_if 2, {{[^,]+}}{{$}}721; CHECK-NEXT: .LBB{{[0-9]+}}_6:722; CHECK-NEXT: end_block{{$}}723; CHECK-NOT: block724; CHECK: return{{$}}725; CHECK-NEXT: .LBB{{[0-9]+}}_7:726; CHECK-NEXT: end_block{{$}}727; CHECK-NOT: block728; CHECK: return{{$}}729; CHECK-NEXT: .LBB{{[0-9]+}}_8:730; CHECK-NEXT: end_block{{$}}731; CHECK-NOT: block732; CHECK: return{{$}}733define void @test11() {734bb0:735 store volatile i32 0, ptr null736 br i1 undef, label %bb1, label %bb4737bb1:738 store volatile i32 1, ptr null739 br i1 undef, label %bb3, label %bb2740bb2:741 store volatile i32 2, ptr null742 br i1 undef, label %bb3, label %bb7743bb3:744 store volatile i32 3, ptr null745 ret void746bb4:747 store volatile i32 4, ptr null748 br i1 undef, label %bb8, label %bb5749bb5:750 store volatile i32 5, ptr null751 br i1 undef, label %bb6, label %bb7752bb6:753 store volatile i32 6, ptr null754 ret void755bb7:756 store volatile i32 7, ptr null757 ret void758bb8:759 store volatile i32 8, ptr null760 ret void761}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 %bb1784 785bb1:786 %tmp = phi i32 [ 0, %bb ], [ %tmp5, %bb4 ]787 %tmp2 = getelementptr i8, ptr %arg, i32 %tmp788 %tmp3 = load i8, ptr %tmp2789 switch i8 %tmp3, label %bb7 [790 i8 42, label %bb4791 i8 76, label %bb4792 i8 108, label %bb4793 i8 104, label %bb4794 ]795 796bb4:797 %tmp5 = add i32 %tmp, 1798 br label %bb1799 800bb7:801 ret void802}803 804; A block can be "branched to" from another even if it is also reachable via805; fallthrough from the other. This would normally be optimized away, so use806; 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 %bb2827bb1:828 unreachable829bb2:830 br i1 undef, label %bb3, label %bb4831bb3:832 br label %bb4833bb4:834 %tmp = phi i1 [ false, %bb2 ], [ false, %bb3 ]835 br i1 %tmp, label %bb1, label %bb1836bb5:837 ret void838}839 840; Test a case with a single-block loop that has another loop841; as a successor. The end_loop for the first loop should go842; 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 %bb1859 860bb1:861 %tmp = bitcast i1 undef to i1862 br i1 %tmp, label %bb3, label %bb1863 864bb3:865 br label %bb4866 867bb4:868 br i1 undef, label %bb7, label %bb48869 870bb7:871 br i1 undef, label %bb12, label %bb12872 873bb12:874 br i1 undef, label %bb17, label %bb17875 876bb17:877 br i1 undef, label %bb22, label %bb22878 879bb22:880 br i1 undef, label %bb27, label %bb27881 882bb27:883 br i1 undef, label %bb30, label %bb30884 885bb30:886 br i1 undef, label %bb35, label %bb35887 888bb35:889 br i1 undef, label %bb38, label %bb38890 891bb38:892 br i1 undef, label %bb48, label %bb48893 894bb48:895 %tmp49 = bitcast i1 undef to i1896 br i1 %tmp49, label %bb3, label %bb50897 898bb50:899 ret void900}901 902; Test that a block boundary which ends one block, begins another block, and903; also begins a loop, has the markers placed in the correct order.904 905; CHECK-LABEL: test15:906; CHECK: block907; CHECK-NEXT: block908; 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, 0933 br i1 %tmp1, label %bb2, label %bb14934 935bb2:936 %tmp3 = phi ptr [ %tmp6, %bb5 ], [ null, %bb ]937 %tmp4 = icmp eq i32 0, 11938 br i1 %tmp4, label %bb5, label %bb8939 940bb5:941 %tmp = bitcast ptr null to ptr942 %tmp6 = getelementptr ptr, ptr %tmp3, i32 1943 %tmp7 = icmp eq ptr %tmp6, null944 br i1 %tmp7, label %bb10, label %bb2945 946bb8:947 %tmp9 = icmp eq ptr null, undef948 br label %bb10949 950bb10:951 %tmp11 = phi ptr [ null, %bb8 ], [ %tmp, %bb5 ]952 %tmp12 = icmp eq ptr null, %tmp11953 br i1 %tmp12, label %bb15, label %bb13954 955bb13:956 call void @test15_callee0()957 ret void958 959bb14:960 call void @test15_callee1()961 ret void962 963bb15:964 ret void965}966