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 9 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 10 target triple = "wasm32-unknown-unknown" 11 12 declare 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{{$}} 40 define void @test0(i32 %n) { 41 entry: 42 br label %header 43 44 header: 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 51 exit: 52 ret void 53 54 back: 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{{$}} 85 define void @test1(i32 %n) { 86 entry: 87 br label %header 88 89 header: 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 96 exit: 97 ret void 98 99 back: 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{{$}} 128 define void @test2(double* nocapture %p, i32 %n) { 129 entry: 130 %cmp.4 = icmp sgt i32 %n, 0 131 br i1 %cmp.4, label %for.body.preheader, label %for.end 132 133 for.body.preheader: 134 br label %for.body 135 136 for.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 146 for.end.loopexit: 147 br label %for.end 148 149 for.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]+}}{{$}} 183 define i32 @doublediamond(i32 %a, i32 %b, i32* %p) { 184 entry: 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 189 true: 190 store volatile i32 1, i32* %p 191 br label %exit 192 false: 193 store volatile i32 2, i32* %p 194 br i1 %d, label %ft, label %ff 195 ft: 196 store volatile i32 3, i32* %p 197 br label %exit 198 ff: 199 store volatile i32 4, i32* %p 200 br label %exit 201 exit: 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]+}}{{$}} 216 define i32 @triangle(i32* %p, i32 %a) { 217 entry: 218 %c = icmp eq i32 %a, 0 219 store volatile i32 0, i32* %p 220 br i1 %c, label %true, label %exit 221 true: 222 store volatile i32 1, i32* %p 223 br label %exit 224 exit: 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]+}}{{$}} 247 define i32 @diamond(i32* %p, i32 %a) { 248 entry: 249 %c = icmp eq i32 %a, 0 250 store volatile i32 0, i32* %p 251 br i1 %c, label %true, label %false 252 true: 253 store volatile i32 1, i32* %p 254 br label %exit 255 false: 256 store volatile i32 2, i32* %p 257 br label %exit 258 exit: 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]+}}{{$}} 269 define i32 @single_block(i32* %p) { 270 entry: 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: 287 define i32 @minimal_loop(i32* %p) { 288 entry: 289 store volatile i32 0, i32* %p 290 br label %loop 291 loop: 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]+}}{{$}} 312 define i32 @simple_loop(i32* %p, i32 %a) { 313 entry: 314 %c = icmp eq i32 %a, 0 315 store volatile i32 0, i32* %p 316 br label %loop 317 loop: 318 store volatile i32 1, i32* %p 319 br i1 %c, label %loop, label %exit 320 exit: 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]+}}{{$}} 341 define i32 @doubletriangle(i32 %a, i32 %b, i32* %p) { 342 entry: 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 347 true: 348 store volatile i32 2, i32* %p 349 br i1 %d, label %tt, label %tf 350 tt: 351 store volatile i32 3, i32* %p 352 br label %tf 353 tf: 354 store volatile i32 4, i32* %p 355 br label %exit 356 exit: 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]+}}{{$}} 381 define i32 @ifelse_earlyexits(i32 %a, i32 %b, i32* %p) { 382 entry: 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 387 true: 388 store volatile i32 1, i32* %p 389 br label %exit 390 false: 391 store volatile i32 2, i32* %p 392 br i1 %d, label %ft, label %exit 393 ft: 394 store volatile i32 3, i32* %p 395 br label %exit 396 exit: 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{{$}} 432 define i32 @doublediamond_in_a_loop(i32 %a, i32 %b, i32* %p) { 433 entry: 434 br label %header 435 header: 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 440 true: 441 store volatile i32 1, i32* %p 442 br label %exit 443 false: 444 store volatile i32 2, i32* %p 445 br i1 %d, label %ft, label %ff 446 ft: 447 store volatile i32 3, i32* %p 448 br label %exit 449 ff: 450 store volatile i32 4, i32* %p 451 br label %exit 452 exit: 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 485 declare void @bar() 486 define void @test3(i32 %w) { 487 entry: 488 br i1 undef, label %outer.ph, label %exit 489 490 outer.ph: 491 br label %outer 492 493 outer: 494 %tobool = icmp eq i32 undef, 0 495 br i1 %tobool, label %inner, label %unreachable 496 497 unreachable: 498 unreachable 499 500 inner: 501 %c = icmp eq i32 undef, %w 502 br i1 %c, label %if.end, label %inner 503 504 exit: 505 ret void 506 507 if.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{{$}} 550 define void @test4(i32 %t) { 551 entry: 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 559 bb0: 560 ret void 561 562 bb1: 563 ret void 564 565 bb2: 566 ret void 567 568 default: 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{{$}} 595 define void @test5(i1 %p, i1 %q) { 596 entry: 597 br label %header 598 599 header: 600 store volatile i32 0, i32* null 601 br i1 %p, label %more, label %alt 602 603 more: 604 store volatile i32 1, i32* null 605 br i1 %q, label %header, label %return 606 607 alt: 608 store volatile i32 2, i32* null 609 ret void 610 611 return: 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{{$}} 662 define void @test6(i1 %p, i1 %q) { 663 entry: 664 br label %header 665 666 header: 667 store volatile i32 0, i32* null 668 br i1 %p, label %more, label %second 669 670 more: 671 store volatile i32 1, i32* null 672 br i1 %q, label %evenmore, label %first 673 674 evenmore: 675 store volatile i32 1, i32* null 676 br i1 %q, label %header, label %return 677 678 return: 679 store volatile i32 2, i32* null 680 ret void 681 682 first: 683 store volatile i32 3, i32* null 684 br label %second 685 686 second: 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 733 define void @test7(i1 %tobool2, i1 %tobool9) { 734 entry: 735 store volatile i32 0, i32* null 736 br label %loop 737 738 loop: 739 store volatile i32 1, i32* null 740 br i1 %tobool2, label %l1, label %l0 741 742 l0: 743 store volatile i32 2, i32* null 744 br i1 %tobool9, label %loop, label %u0 745 746 l1: 747 store volatile i32 3, i32* null 748 br i1 %tobool9, label %loop, label %u1 749 750 u0: 751 store volatile i32 4, i32* null 752 unreachable 753 754 u1: 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{{$}} 777 define i32 @test8() { 778 bb: 779 br label %bb1 780 781 bb1: 782 br i1 undef, label %bb2, label %bb3 783 784 bb2: 785 switch i8 undef, label %bb1 [ 786 i8 44, label %bb2 787 ] 788 789 bb3: 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{{$}} 841 declare i1 @a() 842 define void @test9() { 843 entry: 844 store volatile i32 0, i32* null 845 br label %header 846 847 header: 848 store volatile i32 1, i32* null 849 %call4 = call i1 @a() 850 br i1 %call4, label %header2, label %end 851 852 header2: 853 store volatile i32 2, i32* null 854 %call = call i1 @a() 855 br i1 %call, label %if.then, label %if.else 856 857 if.then: 858 store volatile i32 3, i32* null 859 %call3 = call i1 @a() 860 br i1 %call3, label %header2, label %header 861 862 if.else: 863 store volatile i32 4, i32* null 864 %call2 = call i1 @a() 865 br i1 %call2, label %header2, label %header 866 867 end: 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: 923 define void @test10() { 924 bb0: 925 br label %bb1 926 927 bb1: 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 933 bb2: 934 br label %bb3 935 936 bb3: 937 %tmp11 = phi i32 [ 1, %bb5 ], [ 0, %bb2 ] 938 br label %bb1 939 940 bb4: 941 %tmp6 = phi i32 [ %tmp9, %bb5 ], [ 4, %bb1 ] 942 %tmp7 = phi i32 [ %tmp6, %bb5 ], [ %tmp, %bb1 ] 943 br label %bb5 944 945 bb5: 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 954 bb6: 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{{$}} 1024 define void @test11() { 1025 bb0: 1026 store volatile i32 0, i32* null 1027 br i1 undef, label %bb1, label %bb4 1028 bb1: 1029 store volatile i32 1, i32* null 1030 br i1 undef, label %bb3, label %bb2 1031 bb2: 1032 store volatile i32 2, i32* null 1033 br i1 undef, label %bb3, label %bb7 1034 bb3: 1035 store volatile i32 3, i32* null 1036 ret void 1037 bb4: 1038 store volatile i32 4, i32* null 1039 br i1 undef, label %bb8, label %bb5 1040 bb5: 1041 store volatile i32 5, i32* null 1042 br i1 undef, label %bb6, label %bb7 1043 bb6: 1044 store volatile i32 6, i32* null 1045 ret void 1046 bb7: 1047 store volatile i32 7, i32* null 1048 ret void 1049 bb8: 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{{$}} 1103 define void @test12(i8* %arg) { 1104 bb: 1105 br label %bb1 1106 1107 bb1: 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 1118 bb4: 1119 %tmp5 = add i32 %tmp, 1 1120 br label %bb1 1121 1122 bb7: 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{{$}} 1164 define void @test13() noinline optnone { 1165 bb: 1166 br i1 undef, label %bb5, label %bb2 1167 bb1: 1168 unreachable 1169 bb2: 1170 br i1 undef, label %bb3, label %bb4 1171 bb3: 1172 br label %bb4 1173 bb4: 1174 %tmp = phi i1 [ false, %bb2 ], [ false, %bb3 ] 1175 br i1 %tmp, label %bb1, label %bb1 1176 bb5: 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{{$}} 1196 define void @test14() { 1197 bb: 1198 br label %bb1 1199 1200 bb1: 1201 %tmp = bitcast i1 undef to i1 1202 br i1 %tmp, label %bb3, label %bb1 1203 1204 bb3: 1205 br label %bb4 1206 1207 bb4: 1208 br i1 undef, label %bb7, label %bb48 1209 1210 bb7: 1211 br i1 undef, label %bb12, label %bb12 1212 1213 bb12: 1214 br i1 undef, label %bb17, label %bb17 1215 1216 bb17: 1217 br i1 undef, label %bb22, label %bb22 1218 1219 bb22: 1220 br i1 undef, label %bb27, label %bb27 1221 1222 bb27: 1223 br i1 undef, label %bb30, label %bb30 1224 1225 bb30: 1226 br i1 undef, label %bb35, label %bb35 1227 1228 bb35: 1229 br i1 undef, label %bb38, label %bb38 1230 1231 bb38: 1232 br i1 undef, label %bb48, label %bb48 1233 1234 bb48: 1235 %tmp49 = bitcast i1 undef to i1 1236 br i1 %tmp49, label %bb3, label %bb50 1237 1238 bb50: 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 } 1281 declare void @test15_callee0() 1282 declare void @test15_callee1() 1283 define void @test15() { 1284 bb: 1285 %tmp1 = icmp eq i8 1, 0 1286 br i1 %tmp1, label %bb2, label %bb14 1287 1288 bb2: 1289 %tmp3 = phi %0** [ %tmp6, %bb5 ], [ null, %bb ] 1290 %tmp4 = icmp eq i32 0, 11 1291 br i1 %tmp4, label %bb5, label %bb8 1292 1293 bb5: 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 1299 bb8: 1300 %tmp9 = icmp eq %0** null, undef 1301 br label %bb10 1302 1303 bb10: 1304 %tmp11 = phi %0** [ null, %bb8 ], [ %tmp, %bb5 ] 1305 %tmp12 = icmp eq %0** null, %tmp11 1306 br i1 %tmp12, label %bb15, label %bb13 1307 1308 bb13: 1309 call void @test15_callee0() 1310 ret void 1311 1312 bb14: 1313 call void @test15_callee1() 1314 ret void 1315 1316 bb15: 1317 ret void 1318 } 1319