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: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_{{[0-9]+}}: 90; CHECK: loop 91; CHECK: br_if 0, $pop{{[0-9]+}}{{$}} 92; CHECK: .LBB{{[0-9]+}}_{{[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: .LBB{{[0-9]+}}_2: 127; CHECK-NEXT: end_block{{$}} 128; CHECK: block {{$}} 129; CHECK: br_if 0, ${{[^,]+}}{{$}} 130; CHECK: br 1{{$}} 131; CHECK: .LBB{{[0-9]+}}_4: 132; CHECK-NEXT: end_block{{$}} 133; CHECK: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_2: 184; CHECK: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_1: 215; CHECK: loop i32 216; CHECK: i32.store 0($0), $pop{{[0-9]+}}{{$}} 217; CHECK: br 0{{$}} 218; CHECK: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_3: 255; CHECK: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_2: 283; CHECK: br_if 0, $1{{$}} 284; CHECK: .LBB{{[0-9]+}}_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: .LBB{{[0-9]+}}_1: 309; CHECK: loop i32{{$}} 310; CHECK: block {{$}} 311; CHECK: br_if 0, $0{{$}} 312; CHECK: br 1{{$}} 313; CHECK: .LBB{{[0-9]+}}_3: 314; CHECK: end_block{{$}} 315; CHECK: block {{$}} 316; CHECK: br_if 0, $1{{$}} 317; CHECK: br 1{{$}} 318; CHECK: .LBB{{[0-9]+}}_5: 319; CHECK: br 0{{$}} 320; CHECK: .LBB{{[0-9]+}}_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, i32 %x) { 356entry: 357 br i1 undef, label %outer.ph, label %exit 358 359outer.ph: 360 br label %outer 361 362outer: 363 %tobool = icmp eq i32 %x, 0 364 br i1 %tobool, label %inner, label %unreachable 365 366unreachable: 367 unreachable 368 369inner: 370 %c = icmp eq i32 %x, %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-NEXT: block {{$}} 386; CHECK-NEXT: block {{$}} 387; CHECK-NEXT: br_table $0, 1, 1, 1, 1, 1, 0{{$}} 388; CHECK-NEXT: .LBB{{[0-9]+}}_1: 389; CHECK-NEXT: end_block{{$}} 390; CHECK-NEXT: i32.const $push[[C:[0-9]+]]=, 622{{$}} 391; CHECK-NEXT: i32.eq $drop=, $0, $pop[[C]]{{$}} 392; CHECK-NEXT: .LBB{{[0-9]+}}_2: 393; CHECK-NEXT: end_block{{$}} 394; CHECK-NEXT: return{{$}} 395define void @test4(i32 %t) { 396entry: 397 switch i32 %t, label %default [ 398 i32 0, label %bb2 399 i32 2, label %bb2 400 i32 4, label %bb1 401 i32 622, label %bb0 402 ] 403 404bb0: 405 ret void 406 407bb1: 408 ret void 409 410bb2: 411 ret void 412 413default: 414 ret void 415} 416 417; Test a case where the BLOCK needs to be placed before the LOOP in the 418; same basic block. 419 420; CHECK-LABEL: test5: 421; CHECK: .LBB{{[0-9]+}}_1: 422; CHECK-NEXT: block {{$}} 423; CHECK-NEXT: loop {{$}} 424; CHECK: br_if 1, {{[^,]+}}{{$}} 425; CHECK: br_if 0, {{[^,]+}}{{$}} 426; CHECK-NEXT: end_loop{{$}} 427; CHECK: return{{$}} 428; CHECK-NEXT: .LBB{{[0-9]+}}_4: 429; CHECK: return{{$}} 430define void @test5(i1 %p, i1 %q) { 431entry: 432 br label %header 433 434header: 435 store volatile i32 0, i32* null 436 br i1 %p, label %more, label %alt 437 438more: 439 store volatile i32 1, i32* null 440 br i1 %q, label %header, label %return 441 442alt: 443 store volatile i32 2, i32* null 444 ret void 445 446return: 447 store volatile i32 3, i32* null 448 ret void 449} 450 451; Test an interesting case of a loop with multiple exits, which 452; aren't to layout successors of the loop, and one of which is to a successors 453; which has another predecessor. 454 455; CHECK-LABEL: test6: 456; CHECK: .LBB{{[0-9]+}}_1: 457; CHECK-NEXT: block {{$}} 458; CHECK-NEXT: block {{$}} 459; CHECK-NEXT: loop {{$}} 460; CHECK-NOT: block 461; CHECK: br_if 2, {{[^,]+}}{{$}} 462; CHECK-NOT: block 463; CHECK: br_if 1, {{[^,]+}}{{$}} 464; CHECK-NOT: block 465; CHECK: br_if 0, {{[^,]+}}{{$}} 466; CHECK-NEXT: end_loop{{$}} 467; CHECK-NOT: block 468; CHECK: return{{$}} 469; CHECK-NEXT: .LBB{{[0-9]+}}_5: 470; CHECK-NEXT: end_block{{$}} 471; CHECK-NOT: block 472; CHECK: .LBB{{[0-9]+}}_6: 473; CHECK-NEXT: end_block{{$}} 474; CHECK-NOT: block 475; CHECK: return{{$}} 476define void @test6(i1 %p, i1 %q) { 477entry: 478 br label %header 479 480header: 481 store volatile i32 0, i32* null 482 br i1 %p, label %more, label %second 483 484more: 485 store volatile i32 1, i32* null 486 br i1 %q, label %evenmore, label %first 487 488evenmore: 489 store volatile i32 1, i32* null 490 br i1 %q, label %header, label %return 491 492return: 493 store volatile i32 2, i32* null 494 ret void 495 496first: 497 store volatile i32 3, i32* null 498 br label %second 499 500second: 501 store volatile i32 4, i32* null 502 ret void 503} 504 505; Test a case where there are multiple backedges and multiple loop exits 506; that end in unreachable. 507 508; CHECK-LABEL: test7: 509; CHECK: .LBB{{[0-9]+}}_1: 510; CHECK-NEXT: loop {{$}} 511; CHECK-NOT: block 512; CHECK: block {{$}} 513; CHECK: br_if 0, {{[^,]+}}{{$}} 514; CHECK-NOT: block 515; CHECK: br_if 1, {{[^,]+}}{{$}} 516; CHECK-NOT: block 517; CHECK: unreachable 518; CHECK-NEXT: .LBB{{[0-9]+}}_4: 519; CHECK-NEXT: end_block{{$}} 520; CHECK-NOT: block 521; CHECK: br_if 0, {{[^,]+}}{{$}} 522; CHECK-NEXT: end_loop{{$}} 523; CHECK-NOT: block 524; CHECK: unreachable 525define void @test7(i1 %tobool2, i1 %tobool9) { 526entry: 527 store volatile i32 0, i32* null 528 br label %loop 529 530loop: 531 store volatile i32 1, i32* null 532 br i1 %tobool2, label %l1, label %l0 533 534l0: 535 store volatile i32 2, i32* null 536 br i1 %tobool9, label %loop, label %u0 537 538l1: 539 store volatile i32 3, i32* null 540 br i1 %tobool9, label %loop, label %u1 541 542u0: 543 store volatile i32 4, i32* null 544 unreachable 545 546u1: 547 store volatile i32 5, i32* null 548 unreachable 549} 550 551; Test an interesting case using nested loops and switches. 552 553; CHECK-LABEL: test8: 554; CHECK: .LBB{{[0-9]+}}_1: 555; CHECK-NEXT: loop i32{{$}} 556; CHECK-NEXT: i32.const $push{{[^,]+}}, 0{{$}} 557; CHECK-NEXT: br_if 0, {{[^,]+}}{{$}} 558; CHECK-NEXT: br 0{{$}} 559; CHECK-NEXT: .LBB{{[0-9]+}}_2: 560; CHECK-NEXT: end_loop{{$}} 561define i32 @test8() { 562bb: 563 br label %bb1 564 565bb1: 566 br i1 undef, label %bb2, label %bb3 567 568bb2: 569 switch i8 undef, label %bb1 [ 570 i8 44, label %bb2 571 ] 572 573bb3: 574 switch i8 undef, label %bb1 [ 575 i8 44, label %bb2 576 ] 577} 578 579; Test an interesting case using nested loops that share a bottom block. 580 581; CHECK-LABEL: test9: 582; CHECK: .LBB{{[0-9]+}}_1: 583; CHECK-NEXT: block {{$}} 584; CHECK-NEXT: loop {{$}} 585; CHECK-NOT: block 586; CHECK: br_if 1, {{[^,]+}}{{$}} 587; CHECK-NEXT: .LBB{{[0-9]+}}_2: 588; CHECK-NEXT: loop {{$}} 589; CHECK-NOT: block 590; CHECK: block {{$}} 591; CHECK-NOT: block 592; CHECK: br_if 0, {{[^,]+}}{{$}} 593; CHECK-NOT: block 594; CHECK: br_if 2, {{[^,]+}}{{$}} 595; CHECK-NEXT: br 1{{$}} 596; CHECK-NEXT: .LBB{{[0-9]+}}_4: 597; CHECK-NEXT: end_block{{$}} 598; CHECK-NOT: block 599; CHECK: br_if 1, {{[^,]+}}{{$}} 600; CHECK-NEXT: br 0{{$}} 601; CHECK-NEXT: .LBB{{[0-9]+}}_5: 602; CHECK-NOT: block 603; CHECK: end_block 604; CHECK-NOT: block 605; CHECK: return{{$}} 606declare i1 @a() 607define void @test9() { 608entry: 609 store volatile i32 0, i32* null 610 br label %header 611 612header: 613 store volatile i32 1, i32* null 614 %call4 = call i1 @a() 615 br i1 %call4, label %header2, label %end 616 617header2: 618 store volatile i32 2, i32* null 619 %call = call i1 @a() 620 br i1 %call, label %if.then, label %if.else 621 622if.then: 623 store volatile i32 3, i32* null 624 %call3 = call i1 @a() 625 br i1 %call3, label %header2, label %header 626 627if.else: 628 store volatile i32 4, i32* null 629 %call2 = call i1 @a() 630 br i1 %call2, label %header2, label %header 631 632end: 633 store volatile i32 5, i32* null 634 ret void 635} 636 637; Test an interesting case involving nested loops sharing a loop bottom, 638; and loop exits to a block with unreachable. 639 640; CHECK-LABEL: test10: 641; CHECK: .LBB{{[0-9]+}}_1: 642; CHECK-NEXT: loop {{$}} 643; CHECK: br_if 0, {{[^,]+}}{{$}} 644; CHECK: .LBB{{[0-9]+}}_3: 645; CHECK-NEXT: block {{$}} 646; CHECK-NEXT: loop {{$}} 647; CHECK: .LBB{{[0-9]+}}_4: 648; CHECK-NEXT: loop {{$}} 649; CHECK: br_if 0, {{[^,]+}}{{$}} 650; CHECK-NEXT: end_loop{{$}} 651; CHECK-NEXT: block {{$}} 652; CHECK-NOT: br_if 653; CHECK: br_table $pop{{[^,]+}}, 0, 3, 1, 2, 3 654; CHECK-NEXT: .LBB{{[0-9]+}}_6: 655; CHECK-NEXT: end_block{{$}} 656; CHECK-NEXT: end_loop{{$}} 657; CHECK-NEXT: return{{$}} 658; CHECK-NEXT: .LBB{{[0-9]+}}_7: 659; CHECK-NEXT: end_block{{$}} 660; CHECK: br 0{{$}} 661; CHECK-NEXT: .LBB{{[0-9]+}}_8: 662; CHECK-NEXT: end_loop{{$}} 663define void @test10() { 664bb0: 665 br label %bb1 666 667bb1: 668 %tmp = phi i32 [ 2, %bb0 ], [ 3, %bb3 ] 669 %tmp3 = phi i32 [ undef, %bb0 ], [ %tmp11, %bb3 ] 670 %tmp4 = icmp eq i32 %tmp3, 0 671 br i1 %tmp4, label %bb4, label %bb2 672 673bb2: 674 br label %bb3 675 676bb3: 677 %tmp11 = phi i32 [ 1, %bb5 ], [ 0, %bb2 ] 678 br label %bb1 679 680bb4: 681 %tmp6 = phi i32 [ %tmp9, %bb5 ], [ 4, %bb1 ] 682 %tmp7 = phi i32 [ %tmp6, %bb5 ], [ %tmp, %bb1 ] 683 br label %bb5 684 685bb5: 686 %tmp9 = phi i32 [ %tmp6, %bb5 ], [ %tmp7, %bb4 ] 687 switch i32 %tmp9, label %bb2 [ 688 i32 0, label %bb5 689 i32 1, label %bb6 690 i32 3, label %bb4 691 i32 4, label %bb3 692 ] 693 694bb6: 695 ret void 696} 697 698; Test a CFG DAG with interesting merging. 699 700; CHECK-LABEL: test11: 701; CHECK: block {{$}} 702; CHECK-NEXT: block {{$}} 703; CHECK-NEXT: block {{$}} 704; CHECK-NEXT: block {{$}} 705; CHECK: br_if 0, {{[^,]+}}{{$}} 706; CHECK-NOT: block 707; CHECK: block {{$}} 708; CHECK-NEXT: i32.const 709; CHECK-NEXT: br_if 0, {{[^,]+}}{{$}} 710; CHECK-NOT: block 711; CHECK: br_if 2, {{[^,]+}}{{$}} 712; CHECK-NEXT: .LBB{{[0-9]+}}_3: 713; CHECK-NEXT: end_block{{$}} 714; CHECK-NOT: block 715; CHECK: return{{$}} 716; CHECK-NEXT: .LBB{{[0-9]+}}_4: 717; CHECK-NEXT: end_block{{$}} 718; CHECK-NOT: block 719; CHECK: br_if 1, {{[^,]+}}{{$}} 720; CHECK-NOT: block 721; CHECK: br_if 2, {{[^,]+}}{{$}} 722; CHECK-NEXT: .LBB{{[0-9]+}}_6: 723; CHECK-NEXT: end_block{{$}} 724; CHECK-NOT: block 725; CHECK: return{{$}} 726; CHECK-NEXT: .LBB{{[0-9]+}}_7: 727; CHECK-NEXT: end_block{{$}} 728; CHECK-NOT: block 729; CHECK: return{{$}} 730; CHECK-NEXT: .LBB{{[0-9]+}}_8: 731; CHECK-NEXT: end_block{{$}} 732; CHECK-NOT: block 733; CHECK: return{{$}} 734define void @test11() { 735bb0: 736 store volatile i32 0, i32* null 737 br i1 undef, label %bb1, label %bb4 738bb1: 739 store volatile i32 1, i32* null 740 br i1 undef, label %bb3, label %bb2 741bb2: 742 store volatile i32 2, i32* null 743 br i1 undef, label %bb3, label %bb7 744bb3: 745 store volatile i32 3, i32* null 746 ret void 747bb4: 748 store volatile i32 4, i32* null 749 br i1 undef, label %bb8, label %bb5 750bb5: 751 store volatile i32 5, i32* null 752 br i1 undef, label %bb6, label %bb7 753bb6: 754 store volatile i32 6, i32* null 755 ret void 756bb7: 757 store volatile i32 7, i32* null 758 ret void 759bb8: 760 store volatile i32 8, i32* null 761 ret void 762} 763 764; CHECK-LABEL: test12: 765; CHECK: .LBB{{[0-9]+}}_1: 766; CHECK-NEXT: block {{$}} 767; CHECK-NEXT: loop {{$}} 768; CHECK-NEXT: block {{$}} 769; CHECK-NEXT: block {{$}} 770; CHECK: br_table {{[^,]+}}, 1, 3, 3, 3, 1, 0{{$}} 771; CHECK-NEXT: .LBB{{[0-9]+}}_2: 772; CHECK-NEXT: end_block{{$}} 773; CHECK: br_if 0, {{[^,]+}}{{$}} 774; CHECK: br_if 2, {{[^,]+}}{{$}} 775; CHECK-NEXT: .LBB{{[0-9]+}}_4: 776; CHECK-NEXT: end_block{{$}} 777; CHECK: br 0{{$}} 778; CHECK-NEXT: .LBB{{[0-9]+}}_5: 779; CHECK-NEXT: end_loop{{$}} 780; CHECK-NEXT: end_block{{$}} 781; CHECK-NEXT: return{{$}} 782define void @test12(i8* %arg) { 783bb: 784 br label %bb1 785 786bb1: 787 %tmp = phi i32 [ 0, %bb ], [ %tmp5, %bb4 ] 788 %tmp2 = getelementptr i8, i8* %arg, i32 %tmp 789 %tmp3 = load i8, i8* %tmp2 790 switch i8 %tmp3, label %bb7 [ 791 i8 42, label %bb4 792 i8 76, label %bb4 793 i8 108, label %bb4 794 i8 104, label %bb4 795 ] 796 797bb4: 798 %tmp5 = add i32 %tmp, 1 799 br label %bb1 800 801bb7: 802 ret void 803} 804 805; A block can be "branched to" from another even if it is also reachable via 806; fallthrough from the other. This would normally be optimized away, so use 807; optnone to disable optimizations to test this case. 808 809; CHECK-LABEL: test13: 810; CHECK: block {{$}} 811; CHECK-NEXT: block {{$}} 812; CHECK: br_if 0, $pop0{{$}} 813; CHECK: block {{$}} 814; CHECK: br_if 0, $pop3{{$}} 815; CHECK: .LBB{{[0-9]+}}_3: 816; CHECK-NEXT: end_block{{$}} 817; CHECK: br_if 1, $pop{{[0-9]+}}{{$}} 818; CHECK-NEXT: br 1{{$}} 819; CHECK-NEXT: .LBB{{[0-9]+}}_4: 820; CHECK-NEXT: end_block{{$}} 821; CHECK-NEXT: return{{$}} 822; CHECK-NEXT: .LBB{{[0-9]+}}_5: 823; CHECK-NEXT: end_block{{$}} 824; CHECK-NEXT: unreachable{{$}} 825define void @test13() noinline optnone { 826bb: 827 br i1 undef, label %bb5, label %bb2 828bb1: 829 unreachable 830bb2: 831 br i1 undef, label %bb3, label %bb4 832bb3: 833 br label %bb4 834bb4: 835 %tmp = phi i1 [ false, %bb2 ], [ false, %bb3 ] 836 br i1 %tmp, label %bb1, label %bb1 837bb5: 838 ret void 839} 840 841; Test a case with a single-block loop that has another loop 842; as a successor. The end_loop for the first loop should go 843; before the loop for the second. 844 845; CHECK-LABEL: test14: 846; CHECK: .LBB{{[0-9]+}}_1:{{$}} 847; CHECK-NEXT: loop {{$}} 848; CHECK-NEXT: i32.const $push0=, 0{{$}} 849; CHECK-NEXT: br_if 0, $pop0{{$}} 850; CHECK-NEXT: end_loop{{$}} 851; CHECK-NEXT: .LBB{{[0-9]+}}_3:{{$}} 852; CHECK-NEXT: loop {{$}} 853; CHECK-NEXT: i32.const $push1=, 0{{$}} 854; CHECK-NEXT: br_if 0, $pop1{{$}} 855; CHECK-NEXT: end_loop{{$}} 856; CHECK-NEXT: return{{$}} 857define void @test14() { 858bb: 859 br label %bb1 860 861bb1: 862 %tmp = bitcast i1 undef to i1 863 br i1 %tmp, label %bb3, label %bb1 864 865bb3: 866 br label %bb4 867 868bb4: 869 br i1 undef, label %bb7, label %bb48 870 871bb7: 872 br i1 undef, label %bb12, label %bb12 873 874bb12: 875 br i1 undef, label %bb17, label %bb17 876 877bb17: 878 br i1 undef, label %bb22, label %bb22 879 880bb22: 881 br i1 undef, label %bb27, label %bb27 882 883bb27: 884 br i1 undef, label %bb30, label %bb30 885 886bb30: 887 br i1 undef, label %bb35, label %bb35 888 889bb35: 890 br i1 undef, label %bb38, label %bb38 891 892bb38: 893 br i1 undef, label %bb48, label %bb48 894 895bb48: 896 %tmp49 = bitcast i1 undef to i1 897 br i1 %tmp49, label %bb3, label %bb50 898 899bb50: 900 ret void 901} 902 903; Test that a block boundary which ends one block, begins another block, and 904; also begins a loop, has the markers placed in the correct order. 905 906; CHECK-LABEL: test15: 907; CHECK: block 908; CHECK-NEXT: block 909; CHECK: br_if 0, $pop{{.*}}{{$}} 910; CHECK: .LBB{{[0-9]+}}_2: 911; CHECK-NEXT: block {{$}} 912; CHECK-NEXT: block {{$}} 913; CHECK-NEXT: loop {{$}} 914; CHECK: br_if 1, $pop{{.*}}{{$}} 915; CHECK: br_if 0, ${{.*}}{{$}} 916; CHECK-NEXT: br 2{{$}} 917; CHECK-NEXT: .LBB{{[0-9]+}}_4: 918; CHECK-NEXT: end_loop{{$}} 919; CHECK: .LBB{{[0-9]+}}_5: 920; CHECK-NEXT: end_block{{$}} 921; CHECK: br_if 1, $pop{{.*}}{{$}} 922; CHECK: return{{$}} 923; CHECK: .LBB{{[0-9]+}}_7: 924; CHECK-NEXT: end_block{{$}} 925; CHECK: .LBB{{[0-9]+}}_8: 926; CHECK-NEXT: end_block{{$}} 927; CHECK-NEXT: return{{$}} 928%0 = type { i8, i32 } 929declare void @test15_callee0() 930declare void @test15_callee1() 931define void @test15() { 932bb: 933 %tmp1 = icmp eq i8 1, 0 934 br i1 %tmp1, label %bb2, label %bb14 935 936bb2: 937 %tmp3 = phi %0** [ %tmp6, %bb5 ], [ null, %bb ] 938 %tmp4 = icmp eq i32 0, 11 939 br i1 %tmp4, label %bb5, label %bb8 940 941bb5: 942 %tmp = bitcast i8* null to %0** 943 %tmp6 = getelementptr %0*, %0** %tmp3, i32 1 944 %tmp7 = icmp eq %0** %tmp6, null 945 br i1 %tmp7, label %bb10, label %bb2 946 947bb8: 948 %tmp9 = icmp eq %0** null, undef 949 br label %bb10 950 951bb10: 952 %tmp11 = phi %0** [ null, %bb8 ], [ %tmp, %bb5 ] 953 %tmp12 = icmp eq %0** null, %tmp11 954 br i1 %tmp12, label %bb15, label %bb13 955 956bb13: 957 call void @test15_callee0() 958 ret void 959 960bb14: 961 call void @test15_callee1() 962 ret void 963 964bb15: 965 ret void 966} 967