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