1 ; RUN: opt -passes='loop(unswitch),verify<loops>' -S < %s | FileCheck %s 2 3 declare void @some_func() noreturn 4 declare void @sink(i32) 5 6 declare i1 @cond() 7 declare i32 @cond.i32() 8 9 ; This test contains two trivial unswitch condition in one loop. 10 ; LoopUnswitch pass should be able to unswitch the second one 11 ; after unswitching the first one. 12 define i32 @test1(i32* %var, i1 %cond1, i1 %cond2) { 13 ; CHECK-LABEL: @test1( 14 entry: 15 br label %loop_begin 16 ; CHECK-NEXT: entry: 17 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit.split 18 ; 19 ; CHECK: entry.split: 20 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split.split, label %loop_exit 21 ; 22 ; CHECK: entry.split.split: 23 ; CHECK-NEXT: br label %loop_begin 24 25 loop_begin: 26 br i1 %cond1, label %continue, label %loop_exit ; first trivial condition 27 ; CHECK: loop_begin: 28 ; CHECK-NEXT: br label %continue 29 30 continue: 31 %var_val = load i32, i32* %var 32 br i1 %cond2, label %do_something, label %loop_exit ; second trivial condition 33 ; CHECK: continue: 34 ; CHECK-NEXT: load 35 ; CHECK-NEXT: br label %do_something 36 37 do_something: 38 call void @some_func() noreturn nounwind 39 br label %loop_begin 40 ; CHECK: do_something: 41 ; CHECK-NEXT: call 42 ; CHECK-NEXT: br label %loop_begin 43 44 loop_exit: 45 ret i32 0 46 ; CHECK: loop_exit: 47 ; CHECK-NEXT: br label %loop_exit.split 48 ; 49 ; CHECK: loop_exit.split: 50 ; CHECK-NEXT: ret 51 } 52 53 ; Test for two trivially unswitchable switches. 54 define i32 @test3(i32* %var, i32 %cond1, i32 %cond2) { 55 ; CHECK-LABEL: @test3( 56 entry: 57 br label %loop_begin 58 ; CHECK-NEXT: entry: 59 ; CHECK-NEXT: switch i32 %cond1, label %entry.split [ 60 ; CHECK-NEXT: i32 0, label %loop_exit1 61 ; CHECK-NEXT: ] 62 ; 63 ; CHECK: entry.split: 64 ; CHECK-NEXT: switch i32 %cond2, label %loop_exit2 [ 65 ; CHECK-NEXT: i32 42, label %loop_exit2 66 ; CHECK-NEXT: i32 0, label %entry.split.split 67 ; CHECK-NEXT: ] 68 ; 69 ; CHECK: entry.split.split: 70 ; CHECK-NEXT: br label %loop_begin 71 72 loop_begin: 73 switch i32 %cond1, label %continue [ 74 i32 0, label %loop_exit1 75 ] 76 ; CHECK: loop_begin: 77 ; CHECK-NEXT: br label %continue 78 79 continue: 80 %var_val = load i32, i32* %var 81 switch i32 %cond2, label %loop_exit2 [ 82 i32 0, label %do_something 83 i32 42, label %loop_exit2 84 ] 85 ; CHECK: continue: 86 ; CHECK-NEXT: load 87 ; CHECK-NEXT: br label %do_something 88 89 do_something: 90 call void @some_func() noreturn nounwind 91 br label %loop_begin 92 ; CHECK: do_something: 93 ; CHECK-NEXT: call 94 ; CHECK-NEXT: br label %loop_begin 95 96 loop_exit1: 97 ret i32 0 98 ; CHECK: loop_exit1: 99 ; CHECK-NEXT: ret 100 101 loop_exit2: 102 ret i32 0 103 ; CHECK: loop_exit2: 104 ; CHECK-NEXT: ret 105 ; 106 ; We shouldn't have any unreachable blocks here because the unswitched switches 107 ; turn into branches instead. 108 ; CHECK-NOT: unreachable 109 } 110 111 ; Test for a trivially unswitchable switch with multiple exiting cases and 112 ; multiple looping cases. 113 define i32 @test4(i32* %var, i32 %cond1, i32 %cond2) { 114 ; CHECK-LABEL: @test4( 115 entry: 116 br label %loop_begin 117 ; CHECK-NEXT: entry: 118 ; CHECK-NEXT: switch i32 %cond2, label %loop_exit2 [ 119 ; CHECK-NEXT: i32 13, label %loop_exit1 120 ; CHECK-NEXT: i32 42, label %loop_exit3 121 ; CHECK-NEXT: i32 0, label %entry.split 122 ; CHECK-NEXT: i32 1, label %entry.split 123 ; CHECK-NEXT: i32 2, label %entry.split 124 ; CHECK-NEXT: ] 125 ; 126 ; CHECK: entry.split: 127 ; CHECK-NEXT: br label %loop_begin 128 129 loop_begin: 130 %var_val = load i32, i32* %var 131 switch i32 %cond2, label %loop_exit2 [ 132 i32 0, label %loop0 133 i32 1, label %loop1 134 i32 13, label %loop_exit1 135 i32 2, label %loop2 136 i32 42, label %loop_exit3 137 ] 138 ; CHECK: loop_begin: 139 ; CHECK-NEXT: load 140 ; CHECK-NEXT: switch i32 %cond2, label %loop2 [ 141 ; CHECK-NEXT: i32 0, label %loop0 142 ; CHECK-NEXT: i32 1, label %loop1 143 ; CHECK-NEXT: ] 144 145 loop0: 146 call void @some_func() noreturn nounwind 147 br label %loop_latch 148 ; CHECK: loop0: 149 ; CHECK-NEXT: call 150 ; CHECK-NEXT: br label %loop_latch 151 152 loop1: 153 call void @some_func() noreturn nounwind 154 br label %loop_latch 155 ; CHECK: loop1: 156 ; CHECK-NEXT: call 157 ; CHECK-NEXT: br label %loop_latch 158 159 loop2: 160 call void @some_func() noreturn nounwind 161 br label %loop_latch 162 ; CHECK: loop2: 163 ; CHECK-NEXT: call 164 ; CHECK-NEXT: br label %loop_latch 165 166 loop_latch: 167 br label %loop_begin 168 ; CHECK: loop_latch: 169 ; CHECK-NEXT: br label %loop_begin 170 171 loop_exit1: 172 ret i32 0 173 ; CHECK: loop_exit1: 174 ; CHECK-NEXT: ret 175 176 loop_exit2: 177 ret i32 0 178 ; CHECK: loop_exit2: 179 ; CHECK-NEXT: ret 180 181 loop_exit3: 182 ret i32 0 183 ; CHECK: loop_exit3: 184 ; CHECK-NEXT: ret 185 } 186 187 ; This test contains a trivially unswitchable branch with an LCSSA phi node in 188 ; a loop exit block. 189 define i32 @test5(i1 %cond1, i32 %x, i32 %y) { 190 ; CHECK-LABEL: @test5( 191 entry: 192 br label %loop_begin 193 ; CHECK-NEXT: entry: 194 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit 195 ; 196 ; CHECK: entry.split: 197 ; CHECK-NEXT: br label %loop_begin 198 199 loop_begin: 200 br i1 %cond1, label %latch, label %loop_exit 201 ; CHECK: loop_begin: 202 ; CHECK-NEXT: br label %latch 203 204 latch: 205 call void @some_func() noreturn nounwind 206 br label %loop_begin 207 ; CHECK: latch: 208 ; CHECK-NEXT: call 209 ; CHECK-NEXT: br label %loop_begin 210 211 loop_exit: 212 %result1 = phi i32 [ %x, %loop_begin ] 213 %result2 = phi i32 [ %y, %loop_begin ] 214 %result = add i32 %result1, %result2 215 ret i32 %result 216 ; CHECK: loop_exit: 217 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %x, %entry ] 218 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %y, %entry ] 219 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1]], %[[R2]] 220 ; CHECK-NEXT: ret i32 %[[R]] 221 } 222 223 ; This test contains a trivially unswitchable branch with a real phi node in LCSSA 224 ; position in a shared exit block where a different path through the loop 225 ; produces a non-invariant input to the PHI node. 226 define i32 @test6(i32* %var, i1 %cond1, i1 %cond2, i32 %x, i32 %y) { 227 ; CHECK-LABEL: @test6( 228 entry: 229 br label %loop_begin 230 ; CHECK-NEXT: entry: 231 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit.split 232 ; 233 ; CHECK: entry.split: 234 ; CHECK-NEXT: br label %loop_begin 235 236 loop_begin: 237 br i1 %cond1, label %continue, label %loop_exit 238 ; CHECK: loop_begin: 239 ; CHECK-NEXT: br label %continue 240 241 continue: 242 %var_val = load i32, i32* %var 243 br i1 %cond2, label %latch, label %loop_exit 244 ; CHECK: continue: 245 ; CHECK-NEXT: load 246 ; CHECK-NEXT: br i1 %cond2, label %latch, label %loop_exit 247 248 latch: 249 call void @some_func() noreturn nounwind 250 br label %loop_begin 251 ; CHECK: latch: 252 ; CHECK-NEXT: call 253 ; CHECK-NEXT: br label %loop_begin 254 255 loop_exit: 256 %result1 = phi i32 [ %x, %loop_begin ], [ %var_val, %continue ] 257 %result2 = phi i32 [ %var_val, %continue ], [ %y, %loop_begin ] 258 %result = add i32 %result1, %result2 259 ret i32 %result 260 ; CHECK: loop_exit: 261 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %var_val, %continue ] 262 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %var_val, %continue ] 263 ; CHECK-NEXT: br label %loop_exit.split 264 ; 265 ; CHECK: loop_exit.split: 266 ; CHECK-NEXT: %[[R1S:.*]] = phi i32 [ %x, %entry ], [ %[[R1]], %loop_exit ] 267 ; CHECK-NEXT: %[[R2S:.*]] = phi i32 [ %y, %entry ], [ %[[R2]], %loop_exit ] 268 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1S]], %[[R2S]] 269 ; CHECK-NEXT: ret i32 %[[R]] 270 } 271 272 ; This test contains a trivially unswitchable switch with an LCSSA phi node in 273 ; a loop exit block. 274 define i32 @test7(i32 %cond1, i32 %x, i32 %y) { 275 ; CHECK-LABEL: @test7( 276 entry: 277 br label %loop_begin 278 ; CHECK-NEXT: entry: 279 ; CHECK-NEXT: switch i32 %cond1, label %entry.split [ 280 ; CHECK-NEXT: i32 0, label %loop_exit 281 ; CHECK-NEXT: i32 1, label %loop_exit 282 ; CHECK-NEXT: ] 283 ; 284 ; CHECK: entry.split: 285 ; CHECK-NEXT: br label %loop_begin 286 287 loop_begin: 288 switch i32 %cond1, label %latch [ 289 i32 0, label %loop_exit 290 i32 1, label %loop_exit 291 ] 292 ; CHECK: loop_begin: 293 ; CHECK-NEXT: br label %latch 294 295 latch: 296 call void @some_func() noreturn nounwind 297 br label %loop_begin 298 ; CHECK: latch: 299 ; CHECK-NEXT: call 300 ; CHECK-NEXT: br label %loop_begin 301 302 loop_exit: 303 %result1 = phi i32 [ %x, %loop_begin ], [ %x, %loop_begin ] 304 %result2 = phi i32 [ %y, %loop_begin ], [ %y, %loop_begin ] 305 %result = add i32 %result1, %result2 306 ret i32 %result 307 ; CHECK: loop_exit: 308 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %x, %entry ], [ %x, %entry ] 309 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %y, %entry ], [ %y, %entry ] 310 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1]], %[[R2]] 311 ; CHECK-NEXT: ret i32 %[[R]] 312 } 313 314 ; This test contains a trivially unswitchable switch with a real phi node in 315 ; LCSSA position in a shared exit block where a different path through the loop 316 ; produces a non-invariant input to the PHI node. 317 define i32 @test8(i32* %var, i32 %cond1, i32 %cond2, i32 %x, i32 %y) { 318 ; CHECK-LABEL: @test8( 319 entry: 320 br label %loop_begin 321 ; CHECK-NEXT: entry: 322 ; CHECK-NEXT: switch i32 %cond1, label %entry.split [ 323 ; CHECK-NEXT: i32 0, label %loop_exit.split 324 ; CHECK-NEXT: i32 1, label %loop_exit2 325 ; CHECK-NEXT: i32 2, label %loop_exit.split 326 ; CHECK-NEXT: ] 327 ; 328 ; CHECK: entry.split: 329 ; CHECK-NEXT: br label %loop_begin 330 331 loop_begin: 332 switch i32 %cond1, label %continue [ 333 i32 0, label %loop_exit 334 i32 1, label %loop_exit2 335 i32 2, label %loop_exit 336 ] 337 ; CHECK: loop_begin: 338 ; CHECK-NEXT: br label %continue 339 340 continue: 341 %var_val = load i32, i32* %var 342 switch i32 %cond2, label %latch [ 343 i32 0, label %loop_exit 344 ] 345 ; CHECK: continue: 346 ; CHECK-NEXT: load 347 ; CHECK-NEXT: switch i32 %cond2, label %latch [ 348 ; CHECK-NEXT: i32 0, label %loop_exit 349 ; CHECK-NEXT: ] 350 351 latch: 352 call void @some_func() noreturn nounwind 353 br label %loop_begin 354 ; CHECK: latch: 355 ; CHECK-NEXT: call 356 ; CHECK-NEXT: br label %loop_begin 357 358 loop_exit: 359 %result1.1 = phi i32 [ %x, %loop_begin ], [ %x, %loop_begin ], [ %var_val, %continue ] 360 %result1.2 = phi i32 [ %var_val, %continue ], [ %y, %loop_begin ], [ %y, %loop_begin ] 361 %result1 = add i32 %result1.1, %result1.2 362 ret i32 %result1 363 ; CHECK: loop_exit: 364 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %var_val, %continue ] 365 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %var_val, %continue ] 366 ; CHECK-NEXT: br label %loop_exit.split 367 ; 368 ; CHECK: loop_exit.split: 369 ; CHECK-NEXT: %[[R1S:.*]] = phi i32 [ %x, %entry ], [ %x, %entry ], [ %[[R1]], %loop_exit ] 370 ; CHECK-NEXT: %[[R2S:.*]] = phi i32 [ %y, %entry ], [ %y, %entry ], [ %[[R2]], %loop_exit ] 371 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1S]], %[[R2S]] 372 ; CHECK-NEXT: ret i32 %[[R]] 373 374 loop_exit2: 375 %result2.1 = phi i32 [ %x, %loop_begin ] 376 %result2.2 = phi i32 [ %y, %loop_begin ] 377 %result2 = add i32 %result2.1, %result2.2 378 ret i32 %result2 379 ; CHECK: loop_exit2: 380 ; CHECK-NEXT: %[[R1:.*]] = phi i32 [ %x, %entry ] 381 ; CHECK-NEXT: %[[R2:.*]] = phi i32 [ %y, %entry ] 382 ; CHECK-NEXT: %[[R:.*]] = add i32 %[[R1]], %[[R2]] 383 ; CHECK-NEXT: ret i32 %[[R]] 384 } 385 386 ; This test, extracted from the LLVM test suite, has an interesting dominator 387 ; tree to update as there are edges to sibling domtree nodes within child 388 ; domtree nodes of the unswitched node. 389 define void @xgets(i1 %cond1, i1* %cond2.ptr) { 390 ; CHECK-LABEL: @xgets( 391 entry: 392 br label %for.cond.preheader 393 ; CHECK: entry: 394 ; CHECK-NEXT: br label %for.cond.preheader 395 396 for.cond.preheader: 397 br label %for.cond 398 ; CHECK: for.cond.preheader: 399 ; CHECK-NEXT: br i1 %cond1, label %for.cond.preheader.split, label %if.end17.thread.loopexit 400 ; 401 ; CHECK: for.cond.preheader.split: 402 ; CHECK-NEXT: br label %for.cond 403 404 for.cond: 405 br i1 %cond1, label %land.lhs.true, label %if.end17.thread.loopexit 406 ; CHECK: for.cond: 407 ; CHECK-NEXT: br label %land.lhs.true 408 409 land.lhs.true: 410 br label %if.then20 411 ; CHECK: land.lhs.true: 412 ; CHECK-NEXT: br label %if.then20 413 414 if.then20: 415 %cond2 = load volatile i1, i1* %cond2.ptr 416 br i1 %cond2, label %if.then23, label %if.else 417 ; CHECK: if.then20: 418 ; CHECK-NEXT: %[[COND2:.*]] = load volatile i1, i1* %cond2.ptr 419 ; CHECK-NEXT: br i1 %[[COND2]], label %if.then23, label %if.else 420 421 if.else: 422 br label %for.cond 423 ; CHECK: if.else: 424 ; CHECK-NEXT: br label %for.cond 425 426 if.end17.thread.loopexit: 427 br label %if.end17.thread 428 ; CHECK: if.end17.thread.loopexit: 429 ; CHECK-NEXT: br label %if.end17.thread 430 431 if.end17.thread: 432 br label %cleanup 433 ; CHECK: if.end17.thread: 434 ; CHECK-NEXT: br label %cleanup 435 436 if.then23: 437 br label %cleanup 438 ; CHECK: if.then23: 439 ; CHECK-NEXT: br label %cleanup 440 441 cleanup: 442 ret void 443 ; CHECK: cleanup: 444 ; CHECK-NEXT: ret void 445 } 446 447 define i32 @test_partial_condition_unswitch_and(i32* %var, i1 %cond1, i1 %cond2) { 448 ; CHECK-LABEL: @test_partial_condition_unswitch_and( 449 entry: 450 br label %loop_begin 451 ; CHECK-NEXT: entry: 452 ; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split 453 ; 454 ; CHECK: entry.split: 455 ; CHECK-NEXT: br i1 %cond2, label %entry.split.split, label %loop_exit 456 ; 457 ; CHECK: entry.split.split: 458 ; CHECK-NEXT: br label %loop_begin 459 460 loop_begin: 461 br i1 %cond1, label %continue, label %loop_exit 462 ; CHECK: loop_begin: 463 ; CHECK-NEXT: br label %continue 464 465 continue: 466 %var_val = load i32, i32* %var 467 %var_cond = trunc i32 %var_val to i1 468 %cond_and = and i1 %var_cond, %cond2 469 br i1 %cond_and, label %do_something, label %loop_exit 470 ; CHECK: continue: 471 ; CHECK-NEXT: %[[VAR:.*]] = load i32 472 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 473 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true 474 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit 475 476 do_something: 477 call void @some_func() noreturn nounwind 478 br label %loop_begin 479 ; CHECK: do_something: 480 ; CHECK-NEXT: call 481 ; CHECK-NEXT: br label %loop_begin 482 483 loop_exit: 484 ret i32 0 485 ; CHECK: loop_exit: 486 ; CHECK-NEXT: br label %loop_exit.split 487 ; 488 ; CHECK: loop_exit.split: 489 ; CHECK-NEXT: ret 490 } 491 492 define i32 @test_partial_condition_unswitch_or(i32* %var, i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4, i1 %cond5, i1 %cond6) { 493 ; CHECK-LABEL: @test_partial_condition_unswitch_or( 494 entry: 495 br label %loop_begin 496 ; CHECK-NEXT: entry: 497 ; CHECK-NEXT: %[[INV_OR1:.*]] = or i1 %cond4, %cond2 498 ; CHECK-NEXT: %[[INV_OR2:.*]] = or i1 %[[INV_OR1]], %cond3 499 ; CHECK-NEXT: %[[INV_OR3:.*]] = or i1 %[[INV_OR2]], %cond1 500 ; CHECK-NEXT: br i1 %[[INV_OR3]], label %loop_exit.split, label %entry.split 501 ; 502 ; CHECK: entry.split: 503 ; CHECK-NEXT: br label %loop_begin 504 505 loop_begin: 506 %var_val = load i32, i32* %var 507 %var_cond = trunc i32 %var_val to i1 508 %cond_or1 = or i1 %var_cond, %cond1 509 %cond_or2 = or i1 %cond2, %cond3 510 %cond_or3 = or i1 %cond_or1, %cond_or2 511 %cond_xor1 = xor i1 %cond5, %var_cond 512 %cond_and1 = and i1 %cond6, %var_cond 513 %cond_or4 = or i1 %cond_xor1, %cond_and1 514 %cond_or5 = or i1 %cond_or3, %cond_or4 515 %cond_or6 = or i1 %cond_or5, %cond4 516 br i1 %cond_or6, label %loop_exit, label %do_something 517 ; CHECK: loop_begin: 518 ; CHECK-NEXT: %[[VAR:.*]] = load i32 519 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 520 ; CHECK-NEXT: %[[COND_OR1:.*]] = or i1 %[[VAR_COND]], false 521 ; CHECK-NEXT: %[[COND_OR2:.*]] = or i1 false, false 522 ; CHECK-NEXT: %[[COND_OR3:.*]] = or i1 %[[COND_OR1]], %[[COND_OR2]] 523 ; CHECK-NEXT: %[[COND_XOR:.*]] = xor i1 %cond5, %[[VAR_COND]] 524 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %cond6, %[[VAR_COND]] 525 ; CHECK-NEXT: %[[COND_OR4:.*]] = or i1 %[[COND_XOR]], %[[COND_AND]] 526 ; CHECK-NEXT: %[[COND_OR5:.*]] = or i1 %[[COND_OR3]], %[[COND_OR4]] 527 ; CHECK-NEXT: %[[COND_OR6:.*]] = or i1 %[[COND_OR5]], false 528 ; CHECK-NEXT: br i1 %[[COND_OR6]], label %loop_exit, label %do_something 529 530 do_something: 531 call void @some_func() noreturn nounwind 532 br label %loop_begin 533 ; CHECK: do_something: 534 ; CHECK-NEXT: call 535 ; CHECK-NEXT: br label %loop_begin 536 537 loop_exit: 538 ret i32 0 539 ; CHECK: loop_exit.split: 540 ; CHECK-NEXT: ret 541 } 542 543 define i32 @test_partial_condition_unswitch_with_lcssa_phi1(i32* %var, i1 %cond, i32 %x) { 544 ; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi1( 545 entry: 546 br label %loop_begin 547 ; CHECK-NEXT: entry: 548 ; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split 549 ; 550 ; CHECK: entry.split: 551 ; CHECK-NEXT: br label %loop_begin 552 553 loop_begin: 554 %var_val = load i32, i32* %var 555 %var_cond = trunc i32 %var_val to i1 556 %cond_and = and i1 %var_cond, %cond 557 br i1 %cond_and, label %do_something, label %loop_exit 558 ; CHECK: loop_begin: 559 ; CHECK-NEXT: %[[VAR:.*]] = load i32 560 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 561 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true 562 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit 563 564 do_something: 565 call void @some_func() noreturn nounwind 566 br label %loop_begin 567 ; CHECK: do_something: 568 ; CHECK-NEXT: call 569 ; CHECK-NEXT: br label %loop_begin 570 571 loop_exit: 572 %x.lcssa = phi i32 [ %x, %loop_begin ] 573 ret i32 %x.lcssa 574 ; CHECK: loop_exit: 575 ; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ] 576 ; CHECK-NEXT: br label %loop_exit.split 577 ; 578 ; CHECK: loop_exit.split: 579 ; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ] 580 ; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]] 581 } 582 583 define i32 @test_partial_condition_unswitch_with_lcssa_phi2(i32* %var, i1 %cond, i32 %x, i32 %y) { 584 ; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi2( 585 entry: 586 br label %loop_begin 587 ; CHECK-NEXT: entry: 588 ; CHECK-NEXT: br i1 %cond, label %entry.split, label %loop_exit.split 589 ; 590 ; CHECK: entry.split: 591 ; CHECK-NEXT: br label %loop_begin 592 593 loop_begin: 594 %var_val = load i32, i32* %var 595 %var_cond = trunc i32 %var_val to i1 596 %cond_and = and i1 %var_cond, %cond 597 br i1 %cond_and, label %do_something, label %loop_exit 598 ; CHECK: loop_begin: 599 ; CHECK-NEXT: %[[VAR:.*]] = load i32 600 ; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1 601 ; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true 602 ; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit 603 604 do_something: 605 call void @some_func() noreturn nounwind 606 br i1 %var_cond, label %loop_begin, label %loop_exit 607 ; CHECK: do_something: 608 ; CHECK-NEXT: call 609 ; CHECK-NEXT: br i1 %[[VAR_COND]], label %loop_begin, label %loop_exit 610 611 loop_exit: 612 %xy.lcssa = phi i32 [ %x, %loop_begin ], [ %y, %do_something ] 613 ret i32 %xy.lcssa 614 ; CHECK: loop_exit: 615 ; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ], [ %y, %do_something ] 616 ; CHECK-NEXT: br label %loop_exit.split 617 ; 618 ; CHECK: loop_exit.split: 619 ; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ] 620 ; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]] 621 } 622 623 ; Unswitch will not actually change the loop nest from: 624 ; A < B < C 625 define void @hoist_inner_loop0() { 626 ; CHECK-LABEL: define void @hoist_inner_loop0( 627 entry: 628 br label %a.header 629 ; CHECK: entry: 630 ; CHECK-NEXT: br label %a.header 631 632 a.header: 633 br label %b.header 634 ; CHECK: a.header: 635 ; CHECK-NEXT: br label %b.header 636 637 b.header: 638 %v1 = call i1 @cond() 639 br label %c.header 640 ; CHECK: b.header: 641 ; CHECK-NEXT: %v1 = call i1 @cond() 642 ; CHECK-NEXT: br i1 %v1, label %[[B_LATCH_SPLIT:.*]], label %[[B_HEADER_SPLIT:.*]] 643 ; 644 ; CHECK: [[B_HEADER_SPLIT]]: 645 ; CHECK-NEXT: br label %c.header 646 647 c.header: 648 br i1 %v1, label %b.latch, label %c.latch 649 ; CHECK: c.header: 650 ; CHECK-NEXT: br label %c.latch 651 652 c.latch: 653 %v2 = call i1 @cond() 654 br i1 %v2, label %c.header, label %b.latch 655 ; CHECK: c.latch: 656 ; CHECK-NEXT: %v2 = call i1 @cond() 657 ; CHECK-NEXT: br i1 %v2, label %c.header, label %b.latch 658 659 b.latch: 660 %v3 = call i1 @cond() 661 br i1 %v3, label %b.header, label %a.latch 662 ; CHECK: b.latch: 663 ; CHECK-NEXT: br label %[[B_LATCH_SPLIT]] 664 ; 665 ; CHECK: [[B_LATCH_SPLIT]]: 666 ; CHECK-NEXT: %v3 = call i1 @cond() 667 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch 668 669 a.latch: 670 br label %a.header 671 ; CHECK: a.latch: 672 ; CHECK-NEXT: br label %a.header 673 674 exit: 675 ret void 676 ; CHECK: exit: 677 ; CHECK-NEXT: ret void 678 } 679 680 ; Unswitch will transform the loop nest from: 681 ; A < B < C 682 ; into 683 ; A < (B, C) 684 define void @hoist_inner_loop1(i32* %ptr) { 685 ; CHECK-LABEL: define void @hoist_inner_loop1( 686 entry: 687 br label %a.header 688 ; CHECK: entry: 689 ; CHECK-NEXT: br label %a.header 690 691 a.header: 692 %x.a = load i32, i32* %ptr 693 br label %b.header 694 ; CHECK: a.header: 695 ; CHECK-NEXT: %x.a = load i32, i32* %ptr 696 ; CHECK-NEXT: br label %b.header 697 698 b.header: 699 %x.b = load i32, i32* %ptr 700 %v1 = call i1 @cond() 701 br label %c.header 702 ; CHECK: b.header: 703 ; CHECK-NEXT: %x.b = load i32, i32* %ptr 704 ; CHECK-NEXT: %v1 = call i1 @cond() 705 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]] 706 ; 707 ; CHECK: [[B_HEADER_SPLIT]]: 708 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ] 709 ; CHECK-NEXT: br label %c.header 710 711 c.header: 712 br i1 %v1, label %b.latch, label %c.latch 713 ; CHECK: c.header: 714 ; CHECK-NEXT: br label %c.latch 715 716 c.latch: 717 ; Use values from other loops to check LCSSA form. 718 store i32 %x.a, i32* %ptr 719 store i32 %x.b, i32* %ptr 720 %v2 = call i1 @cond() 721 br i1 %v2, label %c.header, label %a.exit.c 722 ; CHECK: c.latch: 723 ; CHECK-NEXT: store i32 %x.a, i32* %ptr 724 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr 725 ; CHECK-NEXT: %v2 = call i1 @cond() 726 ; CHECK-NEXT: br i1 %v2, label %c.header, label %a.exit.c 727 728 b.latch: 729 %v3 = call i1 @cond() 730 br i1 %v3, label %b.header, label %a.exit.b 731 ; CHECK: b.latch: 732 ; CHECK-NEXT: %v3 = call i1 @cond() 733 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.exit.b 734 735 a.exit.c: 736 br label %a.latch 737 ; CHECK: a.exit.c 738 ; CHECK-NEXT: br label %a.latch 739 740 a.exit.b: 741 br label %a.latch 742 ; CHECK: a.exit.b: 743 ; CHECK-NEXT: br label %a.latch 744 745 a.latch: 746 br label %a.header 747 ; CHECK: a.latch: 748 ; CHECK-NEXT: br label %a.header 749 750 exit: 751 ret void 752 ; CHECK: exit: 753 ; CHECK-NEXT: ret void 754 } 755 756 ; Unswitch will transform the loop nest from: 757 ; A < B < C 758 ; into 759 ; (A < B), C 760 define void @hoist_inner_loop2(i32* %ptr) { 761 ; CHECK-LABEL: define void @hoist_inner_loop2( 762 entry: 763 br label %a.header 764 ; CHECK: entry: 765 ; CHECK-NEXT: br label %a.header 766 767 a.header: 768 %x.a = load i32, i32* %ptr 769 br label %b.header 770 ; CHECK: a.header: 771 ; CHECK-NEXT: %x.a = load i32, i32* %ptr 772 ; CHECK-NEXT: br label %b.header 773 774 b.header: 775 %x.b = load i32, i32* %ptr 776 %v1 = call i1 @cond() 777 br label %c.header 778 ; CHECK: b.header: 779 ; CHECK-NEXT: %x.b = load i32, i32* %ptr 780 ; CHECK-NEXT: %v1 = call i1 @cond() 781 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]] 782 ; 783 ; CHECK: [[B_HEADER_SPLIT]]: 784 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ] 785 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ] 786 ; CHECK-NEXT: br label %c.header 787 788 c.header: 789 br i1 %v1, label %b.latch, label %c.latch 790 ; CHECK: c.header: 791 ; CHECK-NEXT: br label %c.latch 792 793 c.latch: 794 ; Use values from other loops to check LCSSA form. 795 store i32 %x.a, i32* %ptr 796 store i32 %x.b, i32* %ptr 797 %v2 = call i1 @cond() 798 br i1 %v2, label %c.header, label %exit 799 ; CHECK: c.latch: 800 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr 801 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr 802 ; CHECK-NEXT: %v2 = call i1 @cond() 803 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit 804 805 b.latch: 806 %v3 = call i1 @cond() 807 br i1 %v3, label %b.header, label %a.latch 808 ; CHECK: b.latch: 809 ; CHECK-NEXT: %v3 = call i1 @cond() 810 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch 811 812 a.latch: 813 br label %a.header 814 ; CHECK: a.latch: 815 ; CHECK-NEXT: br label %a.header 816 817 exit: 818 ret void 819 ; CHECK: exit: 820 ; CHECK-NEXT: ret void 821 } 822 823 ; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop. 824 ; Unswitch will transform the loop nest from: 825 ; A < B < C < D 826 ; into 827 ; (A < B), (C < D) 828 define void @hoist_inner_loop3(i32* %ptr) { 829 ; CHECK-LABEL: define void @hoist_inner_loop3( 830 entry: 831 br label %a.header 832 ; CHECK: entry: 833 ; CHECK-NEXT: br label %a.header 834 835 a.header: 836 %x.a = load i32, i32* %ptr 837 br label %b.header 838 ; CHECK: a.header: 839 ; CHECK-NEXT: %x.a = load i32, i32* %ptr 840 ; CHECK-NEXT: br label %b.header 841 842 b.header: 843 %x.b = load i32, i32* %ptr 844 %v1 = call i1 @cond() 845 br label %c.header 846 ; CHECK: b.header: 847 ; CHECK-NEXT: %x.b = load i32, i32* %ptr 848 ; CHECK-NEXT: %v1 = call i1 @cond() 849 ; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]] 850 ; 851 ; CHECK: [[B_HEADER_SPLIT]]: 852 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ] 853 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ] 854 ; CHECK-NEXT: br label %c.header 855 856 c.header: 857 br i1 %v1, label %b.latch, label %c.body 858 ; CHECK: c.header: 859 ; CHECK-NEXT: br label %c.body 860 861 c.body: 862 %x.c = load i32, i32* %ptr 863 br label %d.header 864 ; CHECK: c.body: 865 ; CHECK-NEXT: %x.c = load i32, i32* %ptr 866 ; CHECK-NEXT: br label %d.header 867 868 d.header: 869 ; Use values from other loops to check LCSSA form. 870 store i32 %x.a, i32* %ptr 871 store i32 %x.b, i32* %ptr 872 store i32 %x.c, i32* %ptr 873 %v2 = call i1 @cond() 874 br i1 %v2, label %d.header, label %c.latch 875 ; CHECK: d.header: 876 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr 877 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr 878 ; CHECK-NEXT: store i32 %x.c, i32* %ptr 879 ; CHECK-NEXT: %v2 = call i1 @cond() 880 ; CHECK-NEXT: br i1 %v2, label %d.header, label %c.latch 881 882 c.latch: 883 %v3 = call i1 @cond() 884 br i1 %v3, label %c.header, label %exit 885 ; CHECK: c.latch: 886 ; CHECK-NEXT: %v3 = call i1 @cond() 887 ; CHECK-NEXT: br i1 %v3, label %c.header, label %exit 888 889 b.latch: 890 %v4 = call i1 @cond() 891 br i1 %v4, label %b.header, label %a.latch 892 ; CHECK: b.latch: 893 ; CHECK-NEXT: %v4 = call i1 @cond() 894 ; CHECK-NEXT: br i1 %v4, label %b.header, label %a.latch 895 896 a.latch: 897 br label %a.header 898 ; CHECK: a.latch: 899 ; CHECK-NEXT: br label %a.header 900 901 exit: 902 ret void 903 ; CHECK: exit: 904 ; CHECK-NEXT: ret void 905 } 906 907 ; This test is designed to exercise checking multiple remaining exits from the 908 ; loop being unswitched. 909 ; Unswitch will transform the loop nest from: 910 ; A < B < C < D 911 ; into 912 ; A < B < (C, D) 913 define void @hoist_inner_loop4() { 914 ; CHECK-LABEL: define void @hoist_inner_loop4( 915 entry: 916 br label %a.header 917 ; CHECK: entry: 918 ; CHECK-NEXT: br label %a.header 919 920 a.header: 921 br label %b.header 922 ; CHECK: a.header: 923 ; CHECK-NEXT: br label %b.header 924 925 b.header: 926 br label %c.header 927 ; CHECK: b.header: 928 ; CHECK-NEXT: br label %c.header 929 930 c.header: 931 %v1 = call i1 @cond() 932 br label %d.header 933 ; CHECK: c.header: 934 ; CHECK-NEXT: %v1 = call i1 @cond() 935 ; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT:.*]], label %c.latch 936 ; 937 ; CHECK: [[C_HEADER_SPLIT]]: 938 ; CHECK-NEXT: br label %d.header 939 940 d.header: 941 br i1 %v1, label %d.exiting1, label %c.latch 942 ; CHECK: d.header: 943 ; CHECK-NEXT: br label %d.exiting1 944 945 d.exiting1: 946 %v2 = call i1 @cond() 947 br i1 %v2, label %d.exiting2, label %a.latch 948 ; CHECK: d.exiting1: 949 ; CHECK-NEXT: %v2 = call i1 @cond() 950 ; CHECK-NEXT: br i1 %v2, label %d.exiting2, label %a.latch 951 952 d.exiting2: 953 %v3 = call i1 @cond() 954 br i1 %v3, label %d.exiting3, label %loopexit.d 955 ; CHECK: d.exiting2: 956 ; CHECK-NEXT: %v3 = call i1 @cond() 957 ; CHECK-NEXT: br i1 %v3, label %d.exiting3, label %loopexit.d 958 959 d.exiting3: 960 %v4 = call i1 @cond() 961 br i1 %v4, label %d.latch, label %b.latch 962 ; CHECK: d.exiting3: 963 ; CHECK-NEXT: %v4 = call i1 @cond() 964 ; CHECK-NEXT: br i1 %v4, label %d.latch, label %b.latch 965 966 d.latch: 967 br label %d.header 968 ; CHECK: d.latch: 969 ; CHECK-NEXT: br label %d.header 970 971 c.latch: 972 %v5 = call i1 @cond() 973 br i1 %v5, label %c.header, label %loopexit.c 974 ; CHECK: c.latch: 975 ; CHECK-NEXT: %v5 = call i1 @cond() 976 ; CHECK-NEXT: br i1 %v5, label %c.header, label %loopexit.c 977 978 b.latch: 979 br label %b.header 980 ; CHECK: b.latch: 981 ; CHECK-NEXT: br label %b.header 982 983 a.latch: 984 br label %a.header 985 ; CHECK: a.latch: 986 ; CHECK-NEXT: br label %a.header 987 988 loopexit.d: 989 br label %exit 990 ; CHECK: loopexit.d: 991 ; CHECK-NEXT: br label %exit 992 993 loopexit.c: 994 br label %exit 995 ; CHECK: loopexit.c: 996 ; CHECK-NEXT: br label %exit 997 998 exit: 999 ret void 1000 ; CHECK: exit: 1001 ; CHECK-NEXT: ret void 1002 } 1003 1004 ; Unswitch will transform the loop nest from: 1005 ; A < B < C < D 1006 ; into 1007 ; A < ((B < C), D) 1008 define void @hoist_inner_loop5(i32* %ptr) { 1009 ; CHECK-LABEL: define void @hoist_inner_loop5( 1010 entry: 1011 br label %a.header 1012 ; CHECK: entry: 1013 ; CHECK-NEXT: br label %a.header 1014 1015 a.header: 1016 %x.a = load i32, i32* %ptr 1017 br label %b.header 1018 ; CHECK: a.header: 1019 ; CHECK-NEXT: %x.a = load i32, i32* %ptr 1020 ; CHECK-NEXT: br label %b.header 1021 1022 b.header: 1023 %x.b = load i32, i32* %ptr 1024 br label %c.header 1025 ; CHECK: b.header: 1026 ; CHECK-NEXT: %x.b = load i32, i32* %ptr 1027 ; CHECK-NEXT: br label %c.header 1028 1029 c.header: 1030 %x.c = load i32, i32* %ptr 1031 %v1 = call i1 @cond() 1032 br label %d.header 1033 ; CHECK: c.header: 1034 ; CHECK-NEXT: %x.c = load i32, i32* %ptr 1035 ; CHECK-NEXT: %v1 = call i1 @cond() 1036 ; CHECK-NEXT: br i1 %v1, label %c.latch, label %[[C_HEADER_SPLIT:.*]] 1037 ; 1038 ; CHECK: [[C_HEADER_SPLIT]]: 1039 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %c.header ] 1040 ; CHECK-NEXT: %[[X_C_LCSSA:.*]] = phi i32 [ %x.c, %c.header ] 1041 ; CHECK-NEXT: br label %d.header 1042 1043 d.header: 1044 br i1 %v1, label %c.latch, label %d.latch 1045 ; CHECK: d.header: 1046 ; CHECK-NEXT: br label %d.latch 1047 1048 d.latch: 1049 ; Use values from other loops to check LCSSA form. 1050 store i32 %x.a, i32* %ptr 1051 store i32 %x.b, i32* %ptr 1052 store i32 %x.c, i32* %ptr 1053 %v2 = call i1 @cond() 1054 br i1 %v2, label %d.header, label %a.latch 1055 ; CHECK: d.latch: 1056 ; CHECK-NEXT: store i32 %x.a, i32* %ptr 1057 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr 1058 ; CHECK-NEXT: store i32 %[[X_C_LCSSA]], i32* %ptr 1059 ; CHECK-NEXT: %v2 = call i1 @cond() 1060 ; CHECK-NEXT: br i1 %v2, label %d.header, label %a.latch 1061 1062 c.latch: 1063 %v3 = call i1 @cond() 1064 br i1 %v3, label %c.header, label %b.latch 1065 ; CHECK: c.latch: 1066 ; CHECK-NEXT: %v3 = call i1 @cond() 1067 ; CHECK-NEXT: br i1 %v3, label %c.header, label %b.latch 1068 1069 b.latch: 1070 br label %b.header 1071 ; CHECK: b.latch: 1072 ; CHECK-NEXT: br label %b.header 1073 1074 a.latch: 1075 br label %a.header 1076 ; CHECK: a.latch: 1077 ; CHECK-NEXT: br label %a.header 1078 1079 exit: 1080 ret void 1081 ; CHECK: exit: 1082 ; CHECK-NEXT: ret void 1083 } 1084 1085 ; Same as `@hoist_inner_loop2` but using a switch. 1086 ; Unswitch will transform the loop nest from: 1087 ; A < B < C 1088 ; into 1089 ; (A < B), C 1090 define void @hoist_inner_loop_switch(i32* %ptr) { 1091 ; CHECK-LABEL: define void @hoist_inner_loop_switch( 1092 entry: 1093 br label %a.header 1094 ; CHECK: entry: 1095 ; CHECK-NEXT: br label %a.header 1096 1097 a.header: 1098 %x.a = load i32, i32* %ptr 1099 br label %b.header 1100 ; CHECK: a.header: 1101 ; CHECK-NEXT: %x.a = load i32, i32* %ptr 1102 ; CHECK-NEXT: br label %b.header 1103 1104 b.header: 1105 %x.b = load i32, i32* %ptr 1106 %v1 = call i32 @cond.i32() 1107 br label %c.header 1108 ; CHECK: b.header: 1109 ; CHECK-NEXT: %x.b = load i32, i32* %ptr 1110 ; CHECK-NEXT: %v1 = call i32 @cond.i32() 1111 ; CHECK-NEXT: switch i32 %v1, label %[[B_HEADER_SPLIT:.*]] [ 1112 ; CHECK-NEXT: i32 1, label %b.latch 1113 ; CHECK-NEXT: i32 2, label %b.latch 1114 ; CHECK-NEXT: i32 3, label %b.latch 1115 ; CHECK-NEXT: ] 1116 ; 1117 ; CHECK: [[B_HEADER_SPLIT]]: 1118 ; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ] 1119 ; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ] 1120 ; CHECK-NEXT: br label %c.header 1121 1122 c.header: 1123 switch i32 %v1, label %c.latch [ 1124 i32 1, label %b.latch 1125 i32 2, label %b.latch 1126 i32 3, label %b.latch 1127 ] 1128 ; CHECK: c.header: 1129 ; CHECK-NEXT: br label %c.latch 1130 1131 c.latch: 1132 ; Use values from other loops to check LCSSA form. 1133 store i32 %x.a, i32* %ptr 1134 store i32 %x.b, i32* %ptr 1135 %v2 = call i1 @cond() 1136 br i1 %v2, label %c.header, label %exit 1137 ; CHECK: c.latch: 1138 ; CHECK-NEXT: store i32 %[[X_A_LCSSA]], i32* %ptr 1139 ; CHECK-NEXT: store i32 %[[X_B_LCSSA]], i32* %ptr 1140 ; CHECK-NEXT: %v2 = call i1 @cond() 1141 ; CHECK-NEXT: br i1 %v2, label %c.header, label %exit 1142 1143 b.latch: 1144 %v3 = call i1 @cond() 1145 br i1 %v3, label %b.header, label %a.latch 1146 ; CHECK: b.latch: 1147 ; CHECK-NEXT: %v3 = call i1 @cond() 1148 ; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch 1149 1150 a.latch: 1151 br label %a.header 1152 ; CHECK: a.latch: 1153 ; CHECK-NEXT: br label %a.header 1154 1155 exit: 1156 ret void 1157 ; CHECK: exit: 1158 ; CHECK-NEXT: ret void 1159 } 1160 1161 define void @test_unswitch_to_common_succ_with_phis(i32* %var, i32 %cond) { 1162 ; CHECK-LABEL: @test_unswitch_to_common_succ_with_phis( 1163 entry: 1164 br label %header 1165 ; CHECK-NEXT: entry: 1166 ; CHECK-NEXT: switch i32 %cond, label %loopexit1 [ 1167 ; CHECK-NEXT: i32 13, label %loopexit2 1168 ; CHECK-NEXT: i32 0, label %entry.split 1169 ; CHECK-NEXT: i32 1, label %entry.split 1170 ; CHECK-NEXT: ] 1171 ; 1172 ; CHECK: entry.split: 1173 ; CHECK-NEXT: br label %header 1174 1175 header: 1176 %var_val = load i32, i32* %var 1177 switch i32 %cond, label %loopexit1 [ 1178 i32 0, label %latch 1179 i32 1, label %latch 1180 i32 13, label %loopexit2 1181 ] 1182 ; CHECK: header: 1183 ; CHECK-NEXT: load 1184 ; CHECK-NEXT: br label %latch 1185 1186 latch: 1187 ; No-op PHI node to exercise weird PHI update scenarios. 1188 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ] 1189 call void @sink(i32 %phi) 1190 br label %header 1191 ; CHECK: latch: 1192 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ] 1193 ; CHECK-NEXT: call void @sink(i32 %[[PHI]]) 1194 ; CHECK-NEXT: br label %header 1195 1196 loopexit1: 1197 ret void 1198 ; CHECK: loopexit1: 1199 ; CHECK-NEXT: ret 1200 1201 loopexit2: 1202 ret void 1203 ; CHECK: loopexit2: 1204 ; CHECK-NEXT: ret 1205 } 1206 1207 define void @test_unswitch_to_default_common_succ_with_phis(i32* %var, i32 %cond) { 1208 ; CHECK-LABEL: @test_unswitch_to_default_common_succ_with_phis( 1209 entry: 1210 br label %header 1211 ; CHECK-NEXT: entry: 1212 ; CHECK-NEXT: switch i32 %cond, label %entry.split [ 1213 ; CHECK-NEXT: i32 13, label %loopexit 1214 ; CHECK-NEXT: ] 1215 ; 1216 ; CHECK: entry.split: 1217 ; CHECK-NEXT: br label %header 1218 1219 header: 1220 %var_val = load i32, i32* %var 1221 switch i32 %cond, label %latch [ 1222 i32 0, label %latch 1223 i32 1, label %latch 1224 i32 13, label %loopexit 1225 ] 1226 ; CHECK: header: 1227 ; CHECK-NEXT: load 1228 ; CHECK-NEXT: br label %latch 1229 1230 latch: 1231 ; No-op PHI node to exercise weird PHI update scenarios. 1232 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ], [ %var_val, %header ] 1233 call void @sink(i32 %phi) 1234 br label %header 1235 ; CHECK: latch: 1236 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ] 1237 ; CHECK-NEXT: call void @sink(i32 %[[PHI]]) 1238 ; CHECK-NEXT: br label %header 1239 1240 loopexit: 1241 ret void 1242 ; CHECK: loopexit: 1243 ; CHECK-NEXT: ret 1244 } 1245