1481 lines · plain
1; RUN: opt -passes='loop(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s2; RUN: opt -verify-memoryssa -passes='loop-mssa(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s3 4declare void @some_func() noreturn5declare 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 one12; after unswitching the first one.13define i32 @test1(ptr %var, i1 %cond1, i1 %cond2) {14; CHECK-LABEL: @test1(15entry:16 br label %loop_begin17; CHECK-NEXT: entry:18; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit.split19;20; CHECK: entry.split:21; CHECK-NEXT: br i1 %{{.*}}, label %entry.split.split, label %loop_exit22;23; CHECK: entry.split.split:24; CHECK-NEXT: br label %loop_begin25 26loop_begin:27 br i1 %cond1, label %continue, label %loop_exit ; first trivial condition28; CHECK: loop_begin:29; CHECK-NEXT: br label %continue30 31continue:32 %var_val = load i32, ptr %var33 br i1 %cond2, label %do_something, label %loop_exit ; second trivial condition34; CHECK: continue:35; CHECK-NEXT: load36; CHECK-NEXT: br label %do_something37 38do_something:39 call void @some_func() noreturn nounwind40 br label %loop_begin41; CHECK: do_something:42; CHECK-NEXT: call43; CHECK-NEXT: br label %loop_begin44 45loop_exit:46 ret i32 047; CHECK: loop_exit:48; CHECK-NEXT: br label %loop_exit.split49;50; CHECK: loop_exit.split:51; CHECK-NEXT: ret52}53 54; Test for two trivially unswitchable switches.55define i32 @test3(ptr %var, i32 %cond1, i32 %cond2) {56; CHECK-LABEL: @test3(57entry:58 br label %loop_begin59; CHECK-NEXT: entry:60; CHECK-NEXT: switch i32 %cond1, label %entry.split [61; CHECK-NEXT: i32 0, label %loop_exit162; CHECK-NEXT: ]63;64; CHECK: entry.split:65; CHECK-NEXT: switch i32 %cond2, label %loop_exit2 [66; CHECK-NEXT: i32 42, label %loop_exit267; CHECK-NEXT: i32 0, label %entry.split.split68; CHECK-NEXT: ]69;70; CHECK: entry.split.split:71; CHECK-NEXT: br label %loop_begin72 73loop_begin:74 switch i32 %cond1, label %continue [75 i32 0, label %loop_exit176 ]77; CHECK: loop_begin:78; CHECK-NEXT: br label %continue79 80continue:81 %var_val = load i32, ptr %var82 switch i32 %cond2, label %loop_exit2 [83 i32 0, label %do_something84 i32 42, label %loop_exit285 ]86; CHECK: continue:87; CHECK-NEXT: load88; CHECK-NEXT: br label %do_something89 90do_something:91 call void @some_func() noreturn nounwind92 br label %loop_begin93; CHECK: do_something:94; CHECK-NEXT: call95; CHECK-NEXT: br label %loop_begin96 97loop_exit1:98 ret i32 099; CHECK: loop_exit1:100; CHECK-NEXT: ret101 102loop_exit2:103 ret i32 0104; CHECK: loop_exit2:105; CHECK-NEXT: ret106;107; We shouldn't have any unreachable blocks here because the unswitched switches108; turn into branches instead.109; CHECK-NOT: unreachable110}111 112; Test for a trivially unswitchable switch with multiple exiting cases and113; multiple looping cases.114define i32 @test4(ptr %var, i32 %cond1, i32 %cond2) {115; CHECK-LABEL: @test4(116entry:117 br label %loop_begin118; CHECK-NEXT: entry:119; CHECK-NEXT: switch i32 %cond2, label %loop_exit2 [120; CHECK-NEXT: i32 13, label %loop_exit1121; CHECK-NEXT: i32 42, label %loop_exit3122; CHECK-NEXT: i32 0, label %entry.split123; CHECK-NEXT: i32 1, label %entry.split124; CHECK-NEXT: i32 2, label %entry.split125; CHECK-NEXT: ]126;127; CHECK: entry.split:128; CHECK-NEXT: br label %loop_begin129 130loop_begin:131 %var_val = load i32, ptr %var132 switch i32 %cond2, label %loop_exit2 [133 i32 0, label %loop0134 i32 1, label %loop1135 i32 13, label %loop_exit1136 i32 2, label %loop2137 i32 42, label %loop_exit3138 ]139; CHECK: loop_begin:140; CHECK-NEXT: load141; CHECK-NEXT: switch i32 %cond2, label %loop2 [142; CHECK-NEXT: i32 0, label %loop0143; CHECK-NEXT: i32 1, label %loop1144; CHECK-NEXT: ]145 146loop0:147 call void @some_func() noreturn nounwind148 br label %loop_latch149; CHECK: loop0:150; CHECK-NEXT: call151; CHECK-NEXT: br label %loop_latch152 153loop1:154 call void @some_func() noreturn nounwind155 br label %loop_latch156; CHECK: loop1:157; CHECK-NEXT: call158; CHECK-NEXT: br label %loop_latch159 160loop2:161 call void @some_func() noreturn nounwind162 br label %loop_latch163; CHECK: loop2:164; CHECK-NEXT: call165; CHECK-NEXT: br label %loop_latch166 167loop_latch:168 br label %loop_begin169; CHECK: loop_latch:170; CHECK-NEXT: br label %loop_begin171 172loop_exit1:173 ret i32 0174; CHECK: loop_exit1:175; CHECK-NEXT: ret176 177loop_exit2:178 ret i32 0179; CHECK: loop_exit2:180; CHECK-NEXT: ret181 182loop_exit3:183 ret i32 0184; CHECK: loop_exit3:185; CHECK-NEXT: ret186}187 188; This test contains a trivially unswitchable branch with an LCSSA phi node in189; a loop exit block.190define i32 @test5(i1 %cond1, i32 %x, i32 %y) {191; CHECK-LABEL: @test5(192entry:193 br label %loop_begin194; CHECK-NEXT: entry:195; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit196;197; CHECK: entry.split:198; CHECK-NEXT: br label %loop_begin199 200loop_begin:201 br i1 %cond1, label %latch, label %loop_exit202; CHECK: loop_begin:203; CHECK-NEXT: br label %latch204 205latch:206 call void @some_func() noreturn nounwind207 br label %loop_begin208; CHECK: latch:209; CHECK-NEXT: call210; CHECK-NEXT: br label %loop_begin211 212loop_exit:213 %result1 = phi i32 [ %x, %loop_begin ]214 %result2 = phi i32 [ %y, %loop_begin ]215 %result = add i32 %result1, %result2216 ret i32 %result217; 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 LCSSA225; position in a shared exit block where a different path through the loop226; produces a non-invariant input to the PHI node.227define i32 @test6(ptr %var, i1 %cond1, i1 %cond2, i32 %x, i32 %y) {228; CHECK-LABEL: @test6(229entry:230 br label %loop_begin231; CHECK-NEXT: entry:232; CHECK-NEXT: br i1 %{{.*}}, label %entry.split, label %loop_exit.split233;234; CHECK: entry.split:235; CHECK-NEXT: br label %loop_begin236 237loop_begin:238 br i1 %cond1, label %continue, label %loop_exit239; CHECK: loop_begin:240; CHECK-NEXT: br label %continue241 242continue:243 %var_val = load i32, ptr %var244 br i1 %cond2, label %latch, label %loop_exit245; CHECK: continue:246; CHECK-NEXT: load247; CHECK-NEXT: br i1 %cond2, label %latch, label %loop_exit248 249latch:250 call void @some_func() noreturn nounwind251 br label %loop_begin252; CHECK: latch:253; CHECK-NEXT: call254; CHECK-NEXT: br label %loop_begin255 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, %result2260 ret i32 %result261; 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.split265;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 in274; a loop exit block.275define i32 @test7(i32 %cond1, i32 %x, i32 %y) {276; CHECK-LABEL: @test7(277entry:278 br label %loop_begin279; CHECK-NEXT: entry:280; CHECK-NEXT: switch i32 %cond1, label %entry.split [281; CHECK-NEXT: i32 0, label %loop_exit282; CHECK-NEXT: i32 1, label %loop_exit283; CHECK-NEXT: ]284;285; CHECK: entry.split:286; CHECK-NEXT: br label %loop_begin287 288loop_begin:289 switch i32 %cond1, label %latch [290 i32 0, label %loop_exit291 i32 1, label %loop_exit292 ]293; CHECK: loop_begin:294; CHECK-NEXT: br label %latch295 296latch:297 call void @some_func() noreturn nounwind298 br label %loop_begin299; CHECK: latch:300; CHECK-NEXT: call301; CHECK-NEXT: br label %loop_begin302 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, %result2307 ret i32 %result308; 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 in316; LCSSA position in a shared exit block where a different path through the loop317; produces a non-invariant input to the PHI node.318define i32 @test8(ptr %var, i32 %cond1, i32 %cond2, i32 %x, i32 %y) {319; CHECK-LABEL: @test8(320entry:321 br label %loop_begin322; CHECK-NEXT: entry:323; CHECK-NEXT: switch i32 %cond1, label %entry.split [324; CHECK-NEXT: i32 0, label %loop_exit.split325; CHECK-NEXT: i32 1, label %loop_exit2326; CHECK-NEXT: i32 2, label %loop_exit.split327; CHECK-NEXT: ]328;329; CHECK: entry.split:330; CHECK-NEXT: br label %loop_begin331 332loop_begin:333 switch i32 %cond1, label %continue [334 i32 0, label %loop_exit335 i32 1, label %loop_exit2336 i32 2, label %loop_exit337 ]338; CHECK: loop_begin:339; CHECK-NEXT: br label %continue340 341continue:342 %var_val = load i32, ptr %var343 switch i32 %cond2, label %latch [344 i32 0, label %loop_exit345 ]346; CHECK: continue:347; CHECK-NEXT: load348; CHECK-NEXT: switch i32 %cond2, label %latch [349; CHECK-NEXT: i32 0, label %loop_exit350; CHECK-NEXT: ]351 352latch:353 call void @some_func() noreturn nounwind354 br label %loop_begin355; CHECK: latch:356; CHECK-NEXT: call357; CHECK-NEXT: br label %loop_begin358 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.2363 ret i32 %result1364; 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.split368;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.2379 ret i32 %result2380; 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 dominator388; tree to update as there are edges to sibling domtree nodes within child389; domtree nodes of the unswitched node.390define void @xgets(i1 %cond1, ptr %cond2.ptr) {391; CHECK-LABEL: @xgets(392entry:393 br label %for.cond.preheader394; CHECK: entry:395; CHECK-NEXT: br label %for.cond.preheader396 397for.cond.preheader:398 br label %for.cond399; CHECK: for.cond.preheader:400; CHECK-NEXT: br i1 %cond1, label %for.cond.preheader.split, label %if.end17.thread.loopexit401;402; CHECK: for.cond.preheader.split:403; CHECK-NEXT: br label %for.cond404 405for.cond:406 br i1 %cond1, label %land.lhs.true, label %if.end17.thread.loopexit407; CHECK: for.cond:408; CHECK-NEXT: br label %land.lhs.true409 410land.lhs.true:411 br label %if.then20412; CHECK: land.lhs.true:413; CHECK-NEXT: br label %if.then20414 415if.then20:416 %cond2 = load volatile i1, ptr %cond2.ptr417 br i1 %cond2, label %if.then23, label %if.else418; CHECK: if.then20:419; CHECK-NEXT: %[[COND2:.*]] = load volatile i1, ptr %cond2.ptr420; CHECK-NEXT: br i1 %[[COND2]], label %if.then23, label %if.else421 422if.else:423 br label %for.cond424; CHECK: if.else:425; CHECK-NEXT: br label %for.cond426 427if.end17.thread.loopexit:428 br label %if.end17.thread429; CHECK: if.end17.thread.loopexit:430; CHECK-NEXT: br label %if.end17.thread431 432if.end17.thread:433 br label %cleanup434; CHECK: if.end17.thread:435; CHECK-NEXT: br label %cleanup436 437if.then23:438 br label %cleanup439; CHECK: if.then23:440; CHECK-NEXT: br label %cleanup441 442cleanup:443 ret void444; CHECK: cleanup:445; CHECK-NEXT: ret void446}447 448define i32 @test_partial_condition_unswitch_and(ptr %var, i1 %cond1, i1 %cond2) {449; CHECK-LABEL: @test_partial_condition_unswitch_and(450entry:451 br label %loop_begin452; CHECK-NEXT: entry:453; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split454;455; CHECK: entry.split:456; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2457; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split.split, label %loop_exit458;459; CHECK: entry.split.split:460; CHECK-NEXT: br label %loop_begin461 462loop_begin:463 br i1 %cond1, label %continue, label %loop_exit464; CHECK: loop_begin:465; CHECK-NEXT: br label %continue466 467continue:468 %var_val = load i32, ptr %var469 %var_cond = trunc i32 %var_val to i1470 %cond_and = and i1 %var_cond, %cond2471 br i1 %cond_and, label %do_something, label %loop_exit472; CHECK: continue:473; CHECK-NEXT: %[[VAR:.*]] = load i32474; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1475; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true476; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit477 478do_something:479 call void @some_func() noreturn nounwind480 br label %loop_begin481; CHECK: do_something:482; CHECK-NEXT: call483; CHECK-NEXT: br label %loop_begin484 485loop_exit:486 ret i32 0487; CHECK: loop_exit:488; CHECK-NEXT: br label %loop_exit.split489;490; CHECK: loop_exit.split:491; CHECK-NEXT: ret492}493 494define i32 @test_partial_condition_unswitch_and_select(ptr %var, i1 %cond1, i1 %cond2) {495; CHECK-LABEL: @test_partial_condition_unswitch_and_select(496entry:497 br label %loop_begin498; CHECK-NEXT: entry:499; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split500;501; CHECK: entry.split:502; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2503; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split.split, label %loop_exit504;505; CHECK: entry.split.split:506; CHECK-NEXT: br label %loop_begin507 508loop_begin:509 br i1 %cond1, label %continue, label %loop_exit510; CHECK: loop_begin:511; CHECK-NEXT: br label %continue512 513continue:514 %var_val = load i32, ptr %var515 %var_cond = trunc i32 %var_val to i1516 %cond_and = select i1 %var_cond, i1 %cond2, i1 false517 br i1 %cond_and, label %do_something, label %loop_exit518; CHECK: continue:519; CHECK-NEXT: %[[VAR:.*]] = load i32520; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1521; CHECK-NEXT: %[[COND_AND:.*]] = select i1 %[[VAR_COND]], i1 true, i1 false522; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit523 524do_something:525 call void @some_func() noreturn nounwind526 br label %loop_begin527; CHECK: do_something:528; CHECK-NEXT: call529; CHECK-NEXT: br label %loop_begin530 531loop_exit:532 ret i32 0533; CHECK: loop_exit:534; CHECK-NEXT: br label %loop_exit.split535;536; CHECK: loop_exit.split:537; CHECK-NEXT: ret538}539 540define i32 @test_partial_condition_unswitch_or_simple_select(ptr %var, i1 %cond1, i1 %cond2) {541; CHECK-LABEL: @test_partial_condition_unswitch_or_simple_select(542entry:543 br label %loop_begin544; CHECK-NEXT: entry:545; CHECK-NEXT: br i1 %cond1, label %entry.split, label %loop_exit.split546;547; CHECK: entry.split:548; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond2549; CHECK-NEXT: br i1 [[FROZEN]], label %loop_exit.split1, label %entry.split.split550;551; CHECK: entry.split.split:552; CHECK-NEXT: br label %loop_begin553 554loop_begin:555 br i1 %cond1, label %continue, label %loop_exit556; CHECK: loop_begin:557; CHECK-NEXT: br label %continue558 559continue:560 %var_val = load i32, ptr %var561 %var_cond = trunc i32 %var_val to i1562 %cond_or = select i1 %var_cond, i1 true, i1 %cond2563 br i1 %cond_or, label %loop_exit, label %do_something564; CHECK: continue:565; CHECK-NEXT: %[[VAR:.*]] = load i32566; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1567; CHECK-NEXT: %[[COND_OR:.*]] = select i1 %[[VAR_COND]], i1 true, i1 false568; CHECK-NEXT: br i1 %[[COND_OR]], label %loop_exit, label %do_something569 570do_something:571 call void @some_func() noreturn nounwind572 br label %loop_begin573; CHECK: do_something:574; CHECK-NEXT: call575; CHECK-NEXT: br label %loop_begin576 577loop_exit:578 ret i32 0579; CHECK: loop_exit:580; CHECK-NEXT: br label %loop_exit.split1581;582; CHECK: loop_exit.split1:583; CHECK-NEXT: br label %loop_exit.split584;585; CHECK: loop_exit.split:586; CHECK-NEXT: ret587}588 589define i32 @test_partial_condition_unswitch_or(ptr %var, i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4, i1 %cond5, i1 %cond6) {590; CHECK-LABEL: @test_partial_condition_unswitch_or(591entry:592 br label %loop_begin593; CHECK-NEXT: entry:594; CHECK-NEXT: %[[C4_FR:.+]] = freeze i1 %cond4595; CHECK-NEXT: %[[C2_FR:.+]] = freeze i1 %cond2596; CHECK-NEXT: %[[C3_FR:.+]] = freeze i1 %cond3597; CHECK-NEXT: %[[C1_FR:.+]] = freeze i1 %cond1598; CHECK-NEXT: %[[INV_OR1:.*]] = or i1 %[[C4_FR]], %[[C2_FR]]599; CHECK-NEXT: %[[INV_OR2:.*]] = or i1 %[[INV_OR1]], %[[C3_FR]]600; CHECK-NEXT: %[[INV_OR3:.*]] = or i1 %[[INV_OR2]], %[[C1_FR]]601; CHECK-NEXT: br i1 %[[INV_OR3]], label %loop_exit.split, label %entry.split602;603; CHECK: entry.split:604; CHECK-NEXT: br label %loop_begin605 606loop_begin:607 %var_val = load i32, ptr %var608 %var_cond = trunc i32 %var_val to i1609 %cond_or1 = or i1 %var_cond, %cond1610 %cond_or2 = or i1 %cond2, %cond3611 %cond_or3 = or i1 %cond_or1, %cond_or2612 %cond_xor1 = xor i1 %cond5, %var_cond613 %cond_and1 = and i1 %cond6, %var_cond614 %cond_or4 = or i1 %cond_xor1, %cond_and1615 %cond_or5 = or i1 %cond_or3, %cond_or4616 %cond_or6 = or i1 %cond_or5, %cond4617 br i1 %cond_or6, label %loop_exit, label %do_something618; CHECK: loop_begin:619; CHECK-NEXT: %[[VAR:.*]] = load i32620; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1621; CHECK-NEXT: %[[COND_OR1:.*]] = or i1 %[[VAR_COND]], false622; CHECK-NEXT: %[[COND_OR2:.*]] = or i1 false, false623; CHECK-NEXT: %[[COND_OR3:.*]] = or i1 %[[COND_OR1]], %[[COND_OR2]]624; CHECK-NEXT: %[[COND_XOR:.*]] = xor i1 %cond5, %[[VAR_COND]]625; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %cond6, %[[VAR_COND]]626; CHECK-NEXT: %[[COND_OR4:.*]] = or i1 %[[COND_XOR]], %[[COND_AND]]627; CHECK-NEXT: %[[COND_OR5:.*]] = or i1 %[[COND_OR3]], %[[COND_OR4]]628; CHECK-NEXT: %[[COND_OR6:.*]] = or i1 %[[COND_OR5]], false629; CHECK-NEXT: br i1 %[[COND_OR6]], label %loop_exit, label %do_something630 631do_something:632 call void @some_func() noreturn nounwind633 br label %loop_begin634; CHECK: do_something:635; CHECK-NEXT: call636; CHECK-NEXT: br label %loop_begin637 638loop_exit:639 ret i32 0640; CHECK: loop_exit.split:641; CHECK-NEXT: ret642}643 644define i32 @test_partial_condition_unswitch_with_lcssa_phi1(ptr %var, i1 %cond, i32 %x) {645; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi1(646entry:647 br label %loop_begin648; CHECK-NEXT: entry:649; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond650; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split, label %loop_exit.split651;652; CHECK: entry.split:653; CHECK-NEXT: br label %loop_begin654 655loop_begin:656 %var_val = load i32, ptr %var657 %var_cond = trunc i32 %var_val to i1658 %cond_and = and i1 %var_cond, %cond659 br i1 %cond_and, label %do_something, label %loop_exit660; CHECK: loop_begin:661; CHECK-NEXT: %[[VAR:.*]] = load i32662; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1663; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true664; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit665 666do_something:667 call void @some_func() noreturn nounwind668 br label %loop_begin669; CHECK: do_something:670; CHECK-NEXT: call671; CHECK-NEXT: br label %loop_begin672 673loop_exit:674 %x.lcssa = phi i32 [ %x, %loop_begin ]675 ret i32 %x.lcssa676; CHECK: loop_exit:677; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ]678; CHECK-NEXT: br label %loop_exit.split679;680; CHECK: loop_exit.split:681; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ]682; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]]683}684 685define i32 @test_partial_condition_unswitch_with_lcssa_phi2(ptr %var, i1 %cond, i32 %x, i32 %y) {686; CHECK-LABEL: @test_partial_condition_unswitch_with_lcssa_phi2(687entry:688 br label %loop_begin689; CHECK-NEXT: entry:690; CHECK-NEXT: [[FROZEN:%.+]] = freeze i1 %cond691; CHECK-NEXT: br i1 [[FROZEN]], label %entry.split, label %loop_exit.split692;693; CHECK: entry.split:694; CHECK-NEXT: br label %loop_begin695 696loop_begin:697 %var_val = load i32, ptr %var698 %var_cond = trunc i32 %var_val to i1699 %cond_and = and i1 %var_cond, %cond700 br i1 %cond_and, label %do_something, label %loop_exit701; CHECK: loop_begin:702; CHECK-NEXT: %[[VAR:.*]] = load i32703; CHECK-NEXT: %[[VAR_COND:.*]] = trunc i32 %[[VAR]] to i1704; CHECK-NEXT: %[[COND_AND:.*]] = and i1 %[[VAR_COND]], true705; CHECK-NEXT: br i1 %[[COND_AND]], label %do_something, label %loop_exit706 707do_something:708 call void @some_func() noreturn nounwind709 br i1 %var_cond, label %loop_begin, label %loop_exit710; CHECK: do_something:711; CHECK-NEXT: call712; CHECK-NEXT: br i1 %[[VAR_COND]], label %loop_begin, label %loop_exit713 714loop_exit:715 %xy.lcssa = phi i32 [ %x, %loop_begin ], [ %y, %do_something ]716 ret i32 %xy.lcssa717; CHECK: loop_exit:718; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %x, %loop_begin ], [ %y, %do_something ]719; CHECK-NEXT: br label %loop_exit.split720;721; CHECK: loop_exit.split:722; CHECK-NEXT: %[[LCSSA_SPLIT:.*]] = phi i32 [ %x, %entry ], [ %[[LCSSA]], %loop_exit ]723; CHECK-NEXT: ret i32 %[[LCSSA_SPLIT]]724}725 726; Unswitch will not actually change the loop nest from:727; A < B < C728define void @hoist_inner_loop0() {729; CHECK-LABEL: define void @hoist_inner_loop0(730entry:731 br label %a.header732; CHECK: entry:733; CHECK-NEXT: br label %a.header734 735a.header:736 br label %b.header737; CHECK: a.header:738; CHECK-NEXT: br label %b.header739 740b.header:741 %v1 = call i1 @cond()742 br label %c.header743; CHECK: b.header:744; CHECK-NEXT: %v1 = call i1 @cond()745; CHECK-NEXT: br i1 %v1, label %[[B_LATCH_SPLIT:.*]], label %[[B_HEADER_SPLIT:.*]]746;747; CHECK: [[B_HEADER_SPLIT]]:748; CHECK-NEXT: br label %c.header749 750c.header:751 br i1 %v1, label %b.latch, label %c.latch752; CHECK: c.header:753; CHECK-NEXT: br label %c.latch754 755c.latch:756 %v2 = call i1 @cond()757 br i1 %v2, label %c.header, label %b.latch758; CHECK: c.latch:759; CHECK-NEXT: %v2 = call i1 @cond()760; CHECK-NEXT: br i1 %v2, label %c.header, label %b.latch761 762b.latch:763 %v3 = call i1 @cond()764 br i1 %v3, label %b.header, label %a.latch765; CHECK: b.latch:766; CHECK-NEXT: br label %[[B_LATCH_SPLIT]]767;768; CHECK: [[B_LATCH_SPLIT]]:769; CHECK-NEXT: %v3 = call i1 @cond()770; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch771 772a.latch:773 br label %a.header774; CHECK: a.latch:775; CHECK-NEXT: br label %a.header776 777exit:778 ret void779; CHECK: exit:780; CHECK-NEXT: ret void781}782 783; Unswitch will transform the loop nest from:784; A < B < C785; into786; A < (B, C)787define void @hoist_inner_loop1(ptr %ptr) {788; CHECK-LABEL: define void @hoist_inner_loop1(789entry:790 br label %a.header791; CHECK: entry:792; CHECK-NEXT: br label %a.header793 794a.header:795 %x.a = load i32, ptr %ptr796 br label %b.header797; CHECK: a.header:798; CHECK-NEXT: %x.a = load i32, ptr %ptr799; CHECK-NEXT: br label %b.header800 801b.header:802 %x.b = load i32, ptr %ptr803 %v1 = call i1 @cond()804 br label %c.header805; CHECK: b.header:806; CHECK-NEXT: %x.b = load i32, ptr %ptr807; CHECK-NEXT: %v1 = call i1 @cond()808; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]809;810; CHECK: [[B_HEADER_SPLIT]]:811; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]812; CHECK-NEXT: br label %c.header813 814c.header:815 br i1 %v1, label %b.latch, label %c.latch816; CHECK: c.header:817; CHECK-NEXT: br label %c.latch818 819c.latch:820 ; Use values from other loops to check LCSSA form.821 store i32 %x.a, ptr %ptr822 store i32 %x.b, ptr %ptr823 %v2 = call i1 @cond()824 br i1 %v2, label %c.header, label %a.exit.c825; CHECK: c.latch:826; CHECK-NEXT: store i32 %x.a, ptr %ptr827; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr828; CHECK-NEXT: %v2 = call i1 @cond()829; CHECK-NEXT: br i1 %v2, label %c.header, label %a.exit.c830 831b.latch:832 %v3 = call i1 @cond()833 br i1 %v3, label %b.header, label %a.exit.b834; CHECK: b.latch:835; CHECK-NEXT: %v3 = call i1 @cond()836; CHECK-NEXT: br i1 %v3, label %b.header, label %a.exit.b837 838a.exit.c:839 br label %a.latch840; CHECK: a.exit.c841; CHECK-NEXT: br label %a.latch842 843a.exit.b:844 br label %a.latch845; CHECK: a.exit.b:846; CHECK-NEXT: br label %a.latch847 848a.latch:849 br label %a.header850; CHECK: a.latch:851; CHECK-NEXT: br label %a.header852 853exit:854 ret void855; CHECK: exit:856; CHECK-NEXT: ret void857}858 859; Unswitch will transform the loop nest from:860; A < B < C861; into862; (A < B), C863define void @hoist_inner_loop2(ptr %ptr) {864; CHECK-LABEL: define void @hoist_inner_loop2(865entry:866 br label %a.header867; CHECK: entry:868; CHECK-NEXT: br label %a.header869 870a.header:871 %x.a = load i32, ptr %ptr872 br label %b.header873; CHECK: a.header:874; CHECK-NEXT: %x.a = load i32, ptr %ptr875; CHECK-NEXT: br label %b.header876 877b.header:878 %x.b = load i32, ptr %ptr879 %v1 = call i1 @cond()880 br label %c.header881; CHECK: b.header:882; CHECK-NEXT: %x.b = load i32, ptr %ptr883; CHECK-NEXT: %v1 = call i1 @cond()884; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]885;886; CHECK: [[B_HEADER_SPLIT]]:887; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]888; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]889; CHECK-NEXT: br label %c.header890 891c.header:892 br i1 %v1, label %b.latch, label %c.latch893; CHECK: c.header:894; CHECK-NEXT: br label %c.latch895 896c.latch:897 ; Use values from other loops to check LCSSA form.898 store i32 %x.a, ptr %ptr899 store i32 %x.b, ptr %ptr900 %v2 = call i1 @cond()901 br i1 %v2, label %c.header, label %exit902; CHECK: c.latch:903; CHECK-NEXT: store i32 %[[X_A_LCSSA]], ptr %ptr904; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr905; CHECK-NEXT: %v2 = call i1 @cond()906; CHECK-NEXT: br i1 %v2, label %c.header, label %exit907 908b.latch:909 %v3 = call i1 @cond()910 br i1 %v3, label %b.header, label %a.latch911; CHECK: b.latch:912; CHECK-NEXT: %v3 = call i1 @cond()913; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch914 915a.latch:916 br label %a.header917; CHECK: a.latch:918; CHECK-NEXT: br label %a.header919 920exit:921 ret void922; CHECK: exit:923; CHECK-NEXT: ret void924}925 926; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.927; Unswitch will transform the loop nest from:928; A < B < C < D929; into930; (A < B), (C < D)931define void @hoist_inner_loop3(ptr %ptr) {932; CHECK-LABEL: define void @hoist_inner_loop3(933entry:934 br label %a.header935; CHECK: entry:936; CHECK-NEXT: br label %a.header937 938a.header:939 %x.a = load i32, ptr %ptr940 br label %b.header941; CHECK: a.header:942; CHECK-NEXT: %x.a = load i32, ptr %ptr943; CHECK-NEXT: br label %b.header944 945b.header:946 %x.b = load i32, ptr %ptr947 %v1 = call i1 @cond()948 br label %c.header949; CHECK: b.header:950; CHECK-NEXT: %x.b = load i32, ptr %ptr951; CHECK-NEXT: %v1 = call i1 @cond()952; CHECK-NEXT: br i1 %v1, label %b.latch, label %[[B_HEADER_SPLIT:.*]]953;954; CHECK: [[B_HEADER_SPLIT]]:955; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]956; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]957; CHECK-NEXT: br label %c.header958 959c.header:960 br i1 %v1, label %b.latch, label %c.body961; CHECK: c.header:962; CHECK-NEXT: br label %c.body963 964c.body:965 %x.c = load i32, ptr %ptr966 br label %d.header967; CHECK: c.body:968; CHECK-NEXT: %x.c = load i32, ptr %ptr969; CHECK-NEXT: br label %d.header970 971d.header:972 ; Use values from other loops to check LCSSA form.973 store i32 %x.a, ptr %ptr974 store i32 %x.b, ptr %ptr975 store i32 %x.c, ptr %ptr976 %v2 = call i1 @cond()977 br i1 %v2, label %d.header, label %c.latch978; CHECK: d.header:979; CHECK-NEXT: store i32 %[[X_A_LCSSA]], ptr %ptr980; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr981; CHECK-NEXT: store i32 %x.c, ptr %ptr982; CHECK-NEXT: %v2 = call i1 @cond()983; CHECK-NEXT: br i1 %v2, label %d.header, label %c.latch984 985c.latch:986 %v3 = call i1 @cond()987 br i1 %v3, label %c.header, label %exit988; CHECK: c.latch:989; CHECK-NEXT: %v3 = call i1 @cond()990; CHECK-NEXT: br i1 %v3, label %c.header, label %exit991 992b.latch:993 %v4 = call i1 @cond()994 br i1 %v4, label %b.header, label %a.latch995; CHECK: b.latch:996; CHECK-NEXT: %v4 = call i1 @cond()997; CHECK-NEXT: br i1 %v4, label %b.header, label %a.latch998 999a.latch:1000 br label %a.header1001; CHECK: a.latch:1002; CHECK-NEXT: br label %a.header1003 1004exit:1005 ret void1006; CHECK: exit:1007; CHECK-NEXT: ret void1008}1009 1010; This test is designed to exercise checking multiple remaining exits from the1011; loop being unswitched.1012; Unswitch will transform the loop nest from:1013; A < B < C < D1014; into1015; A < B < (C, D)1016define void @hoist_inner_loop4() {1017; CHECK-LABEL: define void @hoist_inner_loop4(1018entry:1019 br label %a.header1020; CHECK: entry:1021; CHECK-NEXT: br label %a.header1022 1023a.header:1024 br label %b.header1025; CHECK: a.header:1026; CHECK-NEXT: br label %b.header1027 1028b.header:1029 br label %c.header1030; CHECK: b.header:1031; CHECK-NEXT: br label %c.header1032 1033c.header:1034 %v1 = call i1 @cond()1035 br label %d.header1036; CHECK: c.header:1037; CHECK-NEXT: %v1 = call i1 @cond()1038; CHECK-NEXT: br i1 %v1, label %[[C_HEADER_SPLIT:.*]], label %c.latch1039;1040; CHECK: [[C_HEADER_SPLIT]]:1041; CHECK-NEXT: br label %d.header1042 1043d.header:1044 br i1 %v1, label %d.exiting1, label %c.latch1045; CHECK: d.header:1046; CHECK-NEXT: br label %d.exiting11047 1048d.exiting1:1049 %v2 = call i1 @cond()1050 br i1 %v2, label %d.exiting2, label %a.latch1051; CHECK: d.exiting1:1052; CHECK-NEXT: %v2 = call i1 @cond()1053; CHECK-NEXT: br i1 %v2, label %d.exiting2, label %a.latch1054 1055d.exiting2:1056 %v3 = call i1 @cond()1057 br i1 %v3, label %d.exiting3, label %loopexit.d1058; CHECK: d.exiting2:1059; CHECK-NEXT: %v3 = call i1 @cond()1060; CHECK-NEXT: br i1 %v3, label %d.exiting3, label %loopexit.d1061 1062d.exiting3:1063 %v4 = call i1 @cond()1064 br i1 %v4, label %d.latch, label %b.latch1065; CHECK: d.exiting3:1066; CHECK-NEXT: %v4 = call i1 @cond()1067; CHECK-NEXT: br i1 %v4, label %d.latch, label %b.latch1068 1069d.latch:1070 br label %d.header1071; CHECK: d.latch:1072; CHECK-NEXT: br label %d.header1073 1074c.latch:1075 %v5 = call i1 @cond()1076 br i1 %v5, label %c.header, label %loopexit.c1077; CHECK: c.latch:1078; CHECK-NEXT: %v5 = call i1 @cond()1079; CHECK-NEXT: br i1 %v5, label %c.header, label %loopexit.c1080 1081b.latch:1082 br label %b.header1083; CHECK: b.latch:1084; CHECK-NEXT: br label %b.header1085 1086a.latch:1087 br label %a.header1088; CHECK: a.latch:1089; CHECK-NEXT: br label %a.header1090 1091loopexit.d:1092 br label %exit1093; CHECK: loopexit.d:1094; CHECK-NEXT: br label %exit1095 1096loopexit.c:1097 br label %exit1098; CHECK: loopexit.c:1099; CHECK-NEXT: br label %exit1100 1101exit:1102 ret void1103; CHECK: exit:1104; CHECK-NEXT: ret void1105}1106 1107; Unswitch will transform the loop nest from:1108; A < B < C < D1109; into1110; A < ((B < C), D)1111define void @hoist_inner_loop5(ptr %ptr) {1112; CHECK-LABEL: define void @hoist_inner_loop5(1113entry:1114 br label %a.header1115; CHECK: entry:1116; CHECK-NEXT: br label %a.header1117 1118a.header:1119 %x.a = load i32, ptr %ptr1120 br label %b.header1121; CHECK: a.header:1122; CHECK-NEXT: %x.a = load i32, ptr %ptr1123; CHECK-NEXT: br label %b.header1124 1125b.header:1126 %x.b = load i32, ptr %ptr1127 br label %c.header1128; CHECK: b.header:1129; CHECK-NEXT: %x.b = load i32, ptr %ptr1130; CHECK-NEXT: br label %c.header1131 1132c.header:1133 %x.c = load i32, ptr %ptr1134 %v1 = call i1 @cond()1135 br label %d.header1136; CHECK: c.header:1137; CHECK-NEXT: %x.c = load i32, ptr %ptr1138; CHECK-NEXT: %v1 = call i1 @cond()1139; CHECK-NEXT: br i1 %v1, label %c.latch, label %[[C_HEADER_SPLIT:.*]]1140;1141; CHECK: [[C_HEADER_SPLIT]]:1142; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %c.header ]1143; CHECK-NEXT: %[[X_C_LCSSA:.*]] = phi i32 [ %x.c, %c.header ]1144; CHECK-NEXT: br label %d.header1145 1146d.header:1147 br i1 %v1, label %c.latch, label %d.latch1148; CHECK: d.header:1149; CHECK-NEXT: br label %d.latch1150 1151d.latch:1152 ; Use values from other loops to check LCSSA form.1153 store i32 %x.a, ptr %ptr1154 store i32 %x.b, ptr %ptr1155 store i32 %x.c, ptr %ptr1156 %v2 = call i1 @cond()1157 br i1 %v2, label %d.header, label %a.latch1158; CHECK: d.latch:1159; CHECK-NEXT: store i32 %x.a, ptr %ptr1160; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr1161; CHECK-NEXT: store i32 %[[X_C_LCSSA]], ptr %ptr1162; CHECK-NEXT: %v2 = call i1 @cond()1163; CHECK-NEXT: br i1 %v2, label %d.header, label %a.latch1164 1165c.latch:1166 %v3 = call i1 @cond()1167 br i1 %v3, label %c.header, label %b.latch1168; CHECK: c.latch:1169; CHECK-NEXT: %v3 = call i1 @cond()1170; CHECK-NEXT: br i1 %v3, label %c.header, label %b.latch1171 1172b.latch:1173 br label %b.header1174; CHECK: b.latch:1175; CHECK-NEXT: br label %b.header1176 1177a.latch:1178 br label %a.header1179; CHECK: a.latch:1180; CHECK-NEXT: br label %a.header1181 1182exit:1183 ret void1184; CHECK: exit:1185; CHECK-NEXT: ret void1186}1187 1188; Same as `@hoist_inner_loop2` but using a switch.1189; Unswitch will transform the loop nest from:1190; A < B < C1191; into1192; (A < B), C1193define void @hoist_inner_loop_switch(ptr %ptr) {1194; CHECK-LABEL: define void @hoist_inner_loop_switch(1195entry:1196 br label %a.header1197; CHECK: entry:1198; CHECK-NEXT: br label %a.header1199 1200a.header:1201 %x.a = load i32, ptr %ptr1202 br label %b.header1203; CHECK: a.header:1204; CHECK-NEXT: %x.a = load i32, ptr %ptr1205; CHECK-NEXT: br label %b.header1206 1207b.header:1208 %x.b = load i32, ptr %ptr1209 %v1 = call i32 @cond.i32()1210 br label %c.header1211; CHECK: b.header:1212; CHECK-NEXT: %x.b = load i32, ptr %ptr1213; CHECK-NEXT: %v1 = call i32 @cond.i32()1214; CHECK-NEXT: switch i32 %v1, label %[[B_HEADER_SPLIT:.*]] [1215; CHECK-NEXT: i32 1, label %b.latch1216; CHECK-NEXT: i32 2, label %b.latch1217; CHECK-NEXT: i32 3, label %b.latch1218; CHECK-NEXT: ]1219;1220; CHECK: [[B_HEADER_SPLIT]]:1221; CHECK-NEXT: %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]1222; CHECK-NEXT: %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]1223; CHECK-NEXT: br label %c.header1224 1225c.header:1226 switch i32 %v1, label %c.latch [1227 i32 1, label %b.latch1228 i32 2, label %b.latch1229 i32 3, label %b.latch1230 ]1231; CHECK: c.header:1232; CHECK-NEXT: br label %c.latch1233 1234c.latch:1235 ; Use values from other loops to check LCSSA form.1236 store i32 %x.a, ptr %ptr1237 store i32 %x.b, ptr %ptr1238 %v2 = call i1 @cond()1239 br i1 %v2, label %c.header, label %exit1240; CHECK: c.latch:1241; CHECK-NEXT: store i32 %[[X_A_LCSSA]], ptr %ptr1242; CHECK-NEXT: store i32 %[[X_B_LCSSA]], ptr %ptr1243; CHECK-NEXT: %v2 = call i1 @cond()1244; CHECK-NEXT: br i1 %v2, label %c.header, label %exit1245 1246b.latch:1247 %v3 = call i1 @cond()1248 br i1 %v3, label %b.header, label %a.latch1249; CHECK: b.latch:1250; CHECK-NEXT: %v3 = call i1 @cond()1251; CHECK-NEXT: br i1 %v3, label %b.header, label %a.latch1252 1253a.latch:1254 br label %a.header1255; CHECK: a.latch:1256; CHECK-NEXT: br label %a.header1257 1258exit:1259 ret void1260; CHECK: exit:1261; CHECK-NEXT: ret void1262}1263 1264define void @test_unswitch_to_common_succ_with_phis(ptr %var, i32 %cond) {1265; CHECK-LABEL: @test_unswitch_to_common_succ_with_phis(1266entry:1267 br label %header1268; CHECK-NEXT: entry:1269; CHECK-NEXT: switch i32 %cond, label %loopexit1 [1270; CHECK-NEXT: i32 13, label %loopexit21271; CHECK-NEXT: i32 0, label %entry.split1272; CHECK-NEXT: i32 1, label %entry.split1273; CHECK-NEXT: ]1274;1275; CHECK: entry.split:1276; CHECK-NEXT: br label %header1277 1278header:1279 %var_val = load i32, ptr %var1280 switch i32 %cond, label %loopexit1 [1281 i32 0, label %latch1282 i32 1, label %latch1283 i32 13, label %loopexit21284 ]1285; CHECK: header:1286; CHECK-NEXT: load1287; CHECK-NEXT: br label %latch1288 1289latch:1290 ; No-op PHI node to exercise weird PHI update scenarios.1291 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ]1292 call void @sink(i32 %phi)1293 br label %header1294; CHECK: latch:1295; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ]1296; CHECK-NEXT: call void @sink(i32 %[[PHI]])1297; CHECK-NEXT: br label %header1298 1299loopexit1:1300 ret void1301; CHECK: loopexit1:1302; CHECK-NEXT: ret1303 1304loopexit2:1305 ret void1306; CHECK: loopexit2:1307; CHECK-NEXT: ret1308}1309 1310define void @test_unswitch_to_default_common_succ_with_phis(ptr %var, i32 %cond) {1311; CHECK-LABEL: @test_unswitch_to_default_common_succ_with_phis(1312entry:1313 br label %header1314; CHECK-NEXT: entry:1315; CHECK-NEXT: switch i32 %cond, label %entry.split [1316; CHECK-NEXT: i32 13, label %loopexit1317; CHECK-NEXT: ]1318;1319; CHECK: entry.split:1320; CHECK-NEXT: br label %header1321 1322header:1323 %var_val = load i32, ptr %var1324 switch i32 %cond, label %latch [1325 i32 0, label %latch1326 i32 1, label %latch1327 i32 13, label %loopexit1328 ]1329; CHECK: header:1330; CHECK-NEXT: load1331; CHECK-NEXT: br label %latch1332 1333latch:1334 ; No-op PHI node to exercise weird PHI update scenarios.1335 %phi = phi i32 [ %var_val, %header ], [ %var_val, %header ], [ %var_val, %header ]1336 call void @sink(i32 %phi)1337 br label %header1338; CHECK: latch:1339; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %var_val, %header ]1340; CHECK-NEXT: call void @sink(i32 %[[PHI]])1341; CHECK-NEXT: br label %header1342 1343loopexit:1344 ret void1345; CHECK: loopexit:1346; CHECK-NEXT: ret1347}1348 1349declare void @f()1350declare void @g()1351define void @test_unswitch_switch_with_nonempty_unreachable() {1352; CHECK-LABEL: @test_unswitch_switch_with_nonempty_unreachable()1353entry:1354 br label %loop1355 1356loop:1357 %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef1358 br label %for.cond1359 1360for.cond:1361 switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [1362 i32 0, label %for.cond1363 i32 1, label %NonEmptyUnreachableBlock1364 i32 2, label %loop.loopexit1365 ]1366 1367loop.loopexit:1368 unreachable1369 1370NonEmptyUnreachableBlock:1371 call void @f()1372 call void @g()1373 unreachable1374 1375; CHECK:loop:1376; CHECK-NEXT: %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef1377; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [1378; CHECK-NEXT: i32 1, label %NonEmptyUnreachableBlock1379; CHECK-NEXT: i32 0, label %loop.split1380; CHECK-NEXT: i32 2, label %loop.split1381; CHECK-NEXT: ]1382 1383; CHECK:loop.split:1384; CHECK-NEXT: br label %for.cond1385 1386; CHECK:for.cond:1387; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %loop.loopexit [1388; CHECK-NEXT: i32 0, label %for.cond1389; CHECK-NEXT: ]1390 1391; CHECK:loop.loopexit:1392; CHECK-NEXT: unreachable1393 1394; CHECK:NonEmptyUnreachableBlock:1395; CHECK-NEXT: call void @f()1396; CHECK-NEXT: call void @g()1397; CHECK-NEXT: unreachable1398}1399 1400define void @test_unswitch_switch_with_nonempty_unreachable2() {1401; CHECK-LABEL: @test_unswitch_switch_with_nonempty_unreachable2()1402entry:1403 br label %loop1404 1405loop:1406 %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef1407 br label %for.cond1408 1409for.cond:1410 switch i32 %cleanup.dest.slot.0, label %for.cond [1411 i32 0, label %for.cond1412 i32 1, label %NonEmptyUnreachableBlock1413 i32 2, label %loop.loopexit1414 ]1415 1416loop.loopexit:1417 unreachable1418 1419NonEmptyUnreachableBlock:1420 call void @f()1421 call void @g()1422 unreachable1423 1424; CHECK:loop:1425; CHECK-NEXT: %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef1426; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %loop.split [1427; CHECK-NEXT: i32 1, label %NonEmptyUnreachableBlock1428; CHECK-NEXT: ]1429 1430; CHECK:loop.split:1431; CHECK-NEXT: br label %for.cond1432 1433; CHECK:for.cond:1434; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %for.cond.backedge [1435; CHECK-NEXT: i32 0, label %for.cond.backedge1436; CHECK-NEXT: i32 2, label %loop.loopexit1437; CHECK-NEXT: ]1438 1439; CHECK:for.cond.backedge:1440; CHECK-NEXT: br label %for.cond1441 1442; CHECK:loop.loopexit:1443; CHECK-NEXT: unreachable1444 1445; CHECK:NonEmptyUnreachableBlock:1446; CHECK-NEXT: call void @f()1447; CHECK-NEXT: call void @g()1448; CHECK-NEXT: unreachable1449}1450 1451; PR453551452define void @test_unswitch_switch_with_duplicate_edge() {1453; CHECK-LABEL: @test_unswitch_switch_with_duplicate_edge()1454entry:1455 br label %lbl11456 1457lbl1: ; preds = %entry1458 %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef1459 br label %for.cond11460 1461for.cond1: ; preds = %for.cond1, %lbl11462 switch i32 %cleanup.dest.slot.0, label %UnifiedUnreachableBlock [1463 i32 0, label %for.cond11464 i32 5, label %UnifiedUnreachableBlock1465 i32 2, label %lbl1.loopexit1466 ]1467 1468UnifiedUnreachableBlock: ; preds = %for.cond1, %for.cond11469 unreachable1470 1471lbl1.loopexit: ; preds = %for.cond11472 unreachable1473 1474; CHECK: for.cond1:1475; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %UnifiedUnreachableBlock [1476; CHECK-NEXT: i32 0, label %for.cond11477; CHECK-NEXT: i32 5, label %UnifiedUnreachableBlock1478; CHECK-NEXT: i32 2, label %lbl1.loopexit1479; CHECK-NEXT: ]1480}1481