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