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