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