brintos

brintos / llvm-project-archived public Read only

0
0
Text · 40.7 KiB · 9201880 Raw
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