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