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