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