brintos

brintos / llvm-project-archived public Read only

0
0
Text · 136.9 KiB · 9567b6b Raw
4390 lines · plain
1; RUN: opt -passes='loop(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s2; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S -verify-memoryssa < %s | FileCheck %s3 4declare i32 @a()5declare i32 @b()6declare i32 @c()7declare i32 @d()8 9declare void @sink1(i32)10declare void @sink2(i32)11 12declare i1 @cond()13declare i32 @cond.i32()14 15; Negative test: we cannot unswitch convergent calls.16define void @test_no_unswitch_convergent(ptr %ptr, i1 %cond) {17; CHECK-LABEL: @test_no_unswitch_convergent(18entry:19  br label %loop_begin20; CHECK-NEXT:  entry:21; CHECK-NEXT:    br label %loop_begin22;23; We shouldn't have unswitched into any other block either.24; CHECK-NOT:     br i1 %cond25 26loop_begin:27  br i1 %cond, label %loop_a, label %loop_b28; CHECK:       loop_begin:29; CHECK-NEXT:    br i1 %cond, label %loop_a, label %loop_b30 31loop_a:32  call i32 @a() convergent33  br label %loop_latch34 35loop_b:36  call i32 @b()37  br label %loop_latch38 39loop_latch:40  %v = load i1, ptr %ptr41  br i1 %v, label %loop_begin, label %loop_exit42 43loop_exit:44  ret void45}46 47; Negative test: we cannot unswitch noduplicate calls.48define void @test_no_unswitch_noduplicate(ptr %ptr, i1 %cond) {49; CHECK-LABEL: @test_no_unswitch_noduplicate(50entry:51  br label %loop_begin52; CHECK-NEXT:  entry:53; CHECK-NEXT:    br label %loop_begin54;55; We shouldn't have unswitched into any other block either.56; CHECK-NOT:     br i1 %cond57 58loop_begin:59  br i1 %cond, label %loop_a, label %loop_b60; CHECK:       loop_begin:61; CHECK-NEXT:    br i1 %cond, label %loop_a, label %loop_b62 63loop_a:64  call i32 @a() noduplicate65  br label %loop_latch66 67loop_b:68  call i32 @b()69  br label %loop_latch70 71loop_latch:72  %v = load i1, ptr %ptr73  br i1 %v, label %loop_begin, label %loop_exit74 75loop_exit:76  ret void77}78 79declare i32 @__CxxFrameHandler3(...)80 81; Negative test: we cannot unswitch when tokens are used across blocks as we82; might introduce PHIs.83define void @test_no_unswitch_cross_block_token(ptr %ptr, i1 %cond) nounwind personality ptr @__CxxFrameHandler3 {84; CHECK-LABEL: @test_no_unswitch_cross_block_token(85entry:86  br label %loop_begin87; CHECK-NEXT:  entry:88; CHECK-NEXT:    br label %loop_begin89;90; We shouldn't have unswitched into any other block either.91; CHECK-NOT:     br i1 %cond92 93loop_begin:94  br i1 %cond, label %loop_a, label %loop_b95; CHECK:       loop_begin:96; CHECK-NEXT:    br i1 %cond, label %loop_a, label %loop_b97 98loop_a:99  call i32 @a()100  br label %loop_cont101 102loop_b:103  call i32 @b()104  br label %loop_cont105 106loop_cont:107  invoke i32 @a()108          to label %loop_latch unwind label %loop_catch109 110loop_latch:111  br label %loop_begin112 113loop_catch:114  %catch = catchswitch within none [label %loop_catch_latch, label %loop_exit] unwind to caller115 116loop_catch_latch:117  %catchpad_latch = catchpad within %catch []118  catchret from %catchpad_latch to label %loop_begin119 120loop_exit:121  %catchpad_exit = catchpad within %catch []122  catchret from %catchpad_exit to label %exit123 124exit:125  ret void126}127 128 129; Non-trivial loop unswitching where there are two distinct trivial conditions130; to unswitch within the loop.131define i32 @test1(ptr %ptr, i1 %cond1, i1 %cond2) {132; CHECK-LABEL: @test1(133entry:134  br label %loop_begin135; CHECK-NEXT:  entry:136; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split137 138loop_begin:139  br i1 %cond1, label %loop_a, label %loop_b140 141loop_a:142  call i32 @a()143  br label %latch144; The 'loop_a' unswitched loop.145;146; CHECK:       entry.split.us:147; CHECK-NEXT:    br label %loop_begin.us148;149; CHECK:       loop_begin.us:150; CHECK-NEXT:    br label %loop_a.us151;152; CHECK:       loop_a.us:153; CHECK-NEXT:    call i32 @a()154; CHECK-NEXT:    br label %latch.us155;156; CHECK:       latch.us:157; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr158; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us159;160; CHECK:       loop_exit.split.us:161; CHECK-NEXT:    br label %loop_exit162 163loop_b:164  br i1 %cond2, label %loop_b_a, label %loop_b_b165; The second unswitched condition.166;167; CHECK:       entry.split:168; CHECK-NEXT:    br i1 %cond2, label %entry.split.split.us, label %entry.split.split169 170loop_b_a:171  call i32 @b()172  br label %latch173; The 'loop_b_a' unswitched loop.174;175; CHECK:       entry.split.split.us:176; CHECK-NEXT:    br label %loop_begin.us1177;178; CHECK:       loop_begin.us1:179; CHECK-NEXT:    br label %loop_b.us180;181; CHECK:       loop_b.us:182; CHECK-NEXT:    br label %loop_b_a.us183;184; CHECK:       loop_b_a.us:185; CHECK-NEXT:    call i32 @b()186; CHECK-NEXT:    br label %latch.us2187;188; CHECK:       latch.us2:189; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr190; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.us1, label %loop_exit.split.split.us191;192; CHECK:       loop_exit.split.split.us:193; CHECK-NEXT:    br label %loop_exit.split194 195loop_b_b:196  call i32 @c()197  br label %latch198; The 'loop_b_b' unswitched loop.199;200; CHECK:       entry.split.split:201; CHECK-NEXT:    br label %loop_begin202;203; CHECK:       loop_begin:204; CHECK-NEXT:    br label %loop_b205;206; CHECK:       loop_b:207; CHECK-NEXT:    br label %loop_b_b208;209; CHECK:       loop_b_b:210; CHECK-NEXT:    call i32 @c()211; CHECK-NEXT:    br label %latch212;213; CHECK:       latch:214; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr215; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit.split.split216;217; CHECK:       loop_exit.split.split:218; CHECK-NEXT:    br label %loop_exit.split219 220latch:221  %v = load i1, ptr %ptr222  br i1 %v, label %loop_begin, label %loop_exit223 224loop_exit:225  ret i32 0226; CHECK:       loop_exit.split:227; CHECK-NEXT:    br label %loop_exit228;229; CHECK:       loop_exit:230; CHECK-NEXT:    ret231}232 233define i32 @test2(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr, ptr %c.ptr) {234; CHECK-LABEL: @test2(235entry:236  br label %loop_begin237; CHECK-NEXT:  entry:238; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split239 240loop_begin:241  %v = load i1, ptr %ptr242  br i1 %cond1, label %loop_a, label %loop_b243 244loop_a:245  %a = load i32, ptr %a.ptr246  %ac = load i32, ptr %c.ptr247  br i1 %v, label %loop_begin, label %loop_exit248; The 'loop_a' unswitched loop.249;250; CHECK:       entry.split.us:251; CHECK-NEXT:    br label %loop_begin.us252;253; CHECK:       loop_begin.us:254; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr255; CHECK-NEXT:    br label %loop_a.us256;257; CHECK:       loop_a.us:258; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr259; CHECK-NEXT:    %[[AC:.*]] = load i32, ptr %c.ptr260; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.backedge.us, label %loop_exit.split.us261;262; CHECK:       loop_exit.split.us:263; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %loop_a.us ]264; CHECK-NEXT:    %[[AC_LCSSA:.*]] = phi i32 [ %[[AC]], %loop_a.us ]265; CHECK-NEXT:    br label %loop_exit266 267loop_b:268  %b = load i32, ptr %b.ptr269  %bc = load i32, ptr %c.ptr270  br i1 %v, label %loop_begin, label %loop_exit271; The 'loop_b' unswitched loop.272;273; CHECK:       entry.split:274; CHECK-NEXT:    br label %loop_begin275;276; CHECK:       loop_begin:277; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr278; CHECK-NEXT:    br label %loop_b279;280; CHECK:       loop_b:281; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr282; CHECK-NEXT:    %[[BC:.*]] = load i32, ptr %c.ptr283; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.backedge, label %loop_exit.split284;285; CHECK:       loop_exit.split:286; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_b ]287; CHECK-NEXT:    %[[BC_LCSSA:.*]] = phi i32 [ %[[BC]], %loop_b ]288; CHECK-NEXT:    br label %loop_exit289 290loop_exit:291  %ab.phi = phi i32 [ %a, %loop_a ], [ %b, %loop_b ]292  %c.phi = phi i32 [ %ac, %loop_a ], [ %bc, %loop_b ]293  %result = add i32 %ab.phi, %c.phi294  ret i32 %result295; CHECK:       loop_exit:296; CHECK-NEXT:    %[[AB_PHI:.*]] = phi i32 [ %[[B_LCSSA]], %loop_exit.split ], [ %[[A_LCSSA]], %loop_exit.split.us ]297; CHECK-NEXT:    %[[C_PHI:.*]] = phi i32 [ %[[BC_LCSSA]], %loop_exit.split ], [ %[[AC_LCSSA]], %loop_exit.split.us ]298; CHECK-NEXT:    %[[RESULT:.*]] = add i32 %[[AB_PHI]], %[[C_PHI]]299; CHECK-NEXT:    ret i32 %[[RESULT]]300}301 302; Test a non-trivial unswitch of an exiting edge to an exit block with other303; in-loop predecessors.304define i32 @test3a(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) {305; CHECK-LABEL: @test3a(306entry:307  br label %loop_begin308; CHECK-NEXT:  entry:309; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split310 311loop_begin:312  %v = load i1, ptr %ptr313  %a = load i32, ptr %a.ptr314  br i1 %cond1, label %loop_exit, label %loop_b315; The 'loop_exit' clone.316;317; CHECK:       entry.split.us:318; CHECK-NEXT:    br label %loop_begin.us319;320; CHECK:       loop_begin.us:321; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr322; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr323; CHECK-NEXT:    br label %loop_exit.split.us324;325; CHECK:       loop_exit.split.us:326; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %loop_begin.us ]327; CHECK-NEXT:    br label %loop_exit328 329loop_b:330  %b = load i32, ptr %b.ptr331  br i1 %v, label %loop_begin, label %loop_exit332; The 'loop_b' unswitched loop.333;334; CHECK:       entry.split:335; CHECK-NEXT:    br label %loop_begin336;337; CHECK:       loop_begin:338; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr339; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr340; CHECK-NEXT:    br label %loop_b341;342; CHECK:       loop_b:343; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr344; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit.split345;346; CHECK:       loop_exit.split:347; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_b ]348; CHECK-NEXT:    br label %loop_exit349 350loop_exit:351  %ab.phi = phi i32 [ %a, %loop_begin ], [ %b, %loop_b ]352  ret i32 %ab.phi353; CHECK:       loop_exit:354; CHECK-NEXT:    %[[AB_PHI:.*]] = phi i32 [ %[[B_LCSSA]], %loop_exit.split ], [ %[[A_LCSSA]], %loop_exit.split.us ]355; CHECK-NEXT:    ret i32 %[[AB_PHI]]356}357 358; Test a non-trivial unswitch of an exiting edge to an exit block with other359; in-loop predecessors. This is the same as @test3a but with the reversed order360; of successors so that the exiting edge is *not* the cloned edge.361define i32 @test3b(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) {362; CHECK-LABEL: @test3b(363entry:364  br label %loop_begin365; CHECK-NEXT:  entry:366; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split367 368loop_begin:369  %v = load i1, ptr %ptr370  %a = load i32, ptr %a.ptr371  br i1 %cond1, label %loop_b, label %loop_exit372; The 'loop_b' unswitched loop.373;374; CHECK:       entry.split.us:375; CHECK-NEXT:    br label %loop_begin.us376;377; CHECK:       loop_begin.us:378; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr379; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr380; CHECK-NEXT:    br label %loop_b.us381;382; CHECK:       loop_b.us:383; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr384; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us385;386; CHECK:       loop_exit.split.us:387; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_b.us ]388; CHECK-NEXT:    br label %loop_exit389 390loop_b:391  %b = load i32, ptr %b.ptr392  br i1 %v, label %loop_begin, label %loop_exit393; The original loop, now non-looping due to unswitching..394;395; CHECK:       entry.split:396; CHECK-NEXT:    br label %loop_begin397;398; CHECK:       loop_begin:399; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr400; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr401; CHECK-NEXT:    br label %loop_exit.split402;403; CHECK:       loop_exit.split:404; CHECK-NEXT:    br label %loop_exit405 406loop_exit:407  %ab.phi = phi i32 [ %b, %loop_b ], [ %a, %loop_begin ]408  ret i32 %ab.phi409; CHECK:       loop_exit:410; CHECK-NEXT:    %[[AB_PHI:.*]] = phi i32 [ %[[A]], %loop_exit.split ], [ %[[B_LCSSA]], %loop_exit.split.us ]411; CHECK-NEXT:    ret i32 %[[AB_PHI]]412}413 414; Test a non-trivial unswitch of an exiting edge to an exit block with no other415; in-loop predecessors.416define void @test4a(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) {417; CHECK-LABEL: @test4a(418entry:419  br label %loop_begin420; CHECK-NEXT:  entry:421; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split422 423loop_begin:424  %v = load i1, ptr %ptr425  %a = load i32, ptr %a.ptr426  br i1 %cond1, label %loop_exit1, label %loop_b427; The 'loop_exit' clone.428;429; CHECK:       entry.split.us:430; CHECK-NEXT:    br label %loop_begin.us431;432; CHECK:       loop_begin.us:433; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr434; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr435; CHECK-NEXT:    br label %loop_exit1.split.us436;437; CHECK:       loop_exit1.split.us:438; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %loop_begin.us ]439; CHECK-NEXT:    br label %loop_exit1440 441loop_b:442  %b = load i32, ptr %b.ptr443  br i1 %v, label %loop_begin, label %loop_exit2444; The 'loop_b' unswitched loop.445;446; CHECK:       entry.split:447; CHECK-NEXT:    br label %loop_begin448;449; CHECK:       loop_begin:450; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr451; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr452; CHECK-NEXT:    br label %loop_b453;454; CHECK:       loop_b:455; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr456; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit2457 458loop_exit1:459  %a.phi = phi i32 [ %a, %loop_begin ]460  call void @sink1(i32 %a.phi)461  ret void462; CHECK:       loop_exit1:463; CHECK-NEXT:    call void @sink1(i32 %[[A_LCSSA]])464; CHECK-NEXT:    ret void465 466loop_exit2:467  %b.phi = phi i32 [ %b, %loop_b ]468  call void @sink2(i32 %b.phi)469  ret void470; CHECK:       loop_exit2:471; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_b ]472; CHECK-NEXT:    call void @sink2(i32 %[[B_LCSSA]])473; CHECK-NEXT:    ret void474}475 476; Test a non-trivial unswitch of an exiting edge to an exit block with no other477; in-loop predecessors. This is the same as @test4a but with the edges reversed478; so that the exiting edge is *not* the cloned edge.479define void @test4b(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) {480; CHECK-LABEL: @test4b(481entry:482  br label %loop_begin483; CHECK-NEXT:  entry:484; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split485 486loop_begin:487  %v = load i1, ptr %ptr488  %a = load i32, ptr %a.ptr489  br i1 %cond1, label %loop_b, label %loop_exit1490; The 'loop_b' clone.491;492; CHECK:       entry.split.us:493; CHECK-NEXT:    br label %loop_begin.us494;495; CHECK:       loop_begin.us:496; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr497; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr498; CHECK-NEXT:    br label %loop_b.us499;500; CHECK:       loop_b.us:501; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr502; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.us, label %loop_exit2.split.us503;504; CHECK:       loop_exit2.split.us:505; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_b.us ]506; CHECK-NEXT:    br label %loop_exit2507 508loop_b:509  %b = load i32, ptr %b.ptr510  br i1 %v, label %loop_begin, label %loop_exit2511; The 'loop_exit' unswitched path.512;513; CHECK:       entry.split:514; CHECK-NEXT:    br label %loop_begin515;516; CHECK:       loop_begin:517; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr518; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr519; CHECK-NEXT:    br label %loop_exit1520 521loop_exit1:522  %a.phi = phi i32 [ %a, %loop_begin ]523  call void @sink1(i32 %a.phi)524  ret void525; CHECK:       loop_exit1:526; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ]527; CHECK-NEXT:    call void @sink1(i32 %[[A_PHI]])528; CHECK-NEXT:    ret void529 530loop_exit2:531  %b.phi = phi i32 [ %b, %loop_b ]532  call void @sink2(i32 %b.phi)533  ret void534; CHECK:       loop_exit2:535; CHECK-NEXT:    call void @sink2(i32 %[[B_LCSSA]])536; CHECK-NEXT:    ret void537}538 539; Test a non-trivial unswitch of an exiting edge to an exit block with no other540; in-loop predecessors. This is the same as @test4a but with a common merge541; block after the independent loop exits. This requires a different structural542; update to the dominator tree.543define void @test4c(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) {544; CHECK-LABEL: @test4c(545entry:546  br label %loop_begin547; CHECK-NEXT:  entry:548; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split549 550loop_begin:551  %v = load i1, ptr %ptr552  %a = load i32, ptr %a.ptr553  br i1 %cond1, label %loop_exit1, label %loop_b554; The 'loop_exit' clone.555;556; CHECK:       entry.split.us:557; CHECK-NEXT:    br label %loop_begin.us558;559; CHECK:       loop_begin.us:560; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr561; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr562; CHECK-NEXT:    br label %loop_exit1.split.us563;564; CHECK:       loop_exit1.split.us:565; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %loop_begin.us ]566; CHECK-NEXT:    br label %loop_exit1567 568loop_b:569  %b = load i32, ptr %b.ptr570  br i1 %v, label %loop_begin, label %loop_exit2571; The 'loop_b' unswitched loop.572;573; CHECK:       entry.split:574; CHECK-NEXT:    br label %loop_begin575;576; CHECK:       loop_begin:577; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr578; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr579; CHECK-NEXT:    br label %loop_b580;581; CHECK:       loop_b:582; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr583; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit2584 585loop_exit1:586  %a.phi = phi i32 [ %a, %loop_begin ]587  call void @sink1(i32 %a.phi)588  br label %exit589; CHECK:       loop_exit1:590; CHECK-NEXT:    call void @sink1(i32 %[[A_LCSSA]])591; CHECK-NEXT:    br label %exit592 593loop_exit2:594  %b.phi = phi i32 [ %b, %loop_b ]595  call void @sink2(i32 %b.phi)596  br label %exit597; CHECK:       loop_exit2:598; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_b ]599; CHECK-NEXT:    call void @sink2(i32 %[[B_LCSSA]])600; CHECK-NEXT:    br label %exit601 602exit:603  ret void604; CHECK:       exit:605; CHECK-NEXT:    ret void606}607 608; Test that we can unswitch a condition out of multiple layers of a loop nest.609define i32 @test5(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) {610; CHECK-LABEL: @test5(611entry:612  br label %loop_begin613; CHECK-NEXT:  entry:614; CHECK-NEXT:    br i1 %cond1, label %loop_begin.split.us, label %entry.split615;616; CHECK:       entry.split:617; CHECK-NEXT:    br label %loop_begin618;619; CHECK:       loop_begin:620; CHECK-NEXT:    br label %loop_begin.split621 622loop_begin:623  br label %inner_loop_begin624 625inner_loop_begin:626  %v = load i1, ptr %ptr627  %a = load i32, ptr %a.ptr628  br i1 %cond1, label %loop_exit, label %inner_loop_b629; The 'loop_exit' clone.630;631; CHECK:       loop_begin.split.us:632; CHECK-NEXT:    br label %inner_loop_begin.us633;634; CHECK:       inner_loop_begin.us:635; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr636; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr637; CHECK-NEXT:    br label %loop_exit.loopexit.split.us638;639; CHECK:       loop_exit.loopexit.split.us:640; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %inner_loop_begin.us ]641; CHECK-NEXT:    br label %loop_exit642 643inner_loop_b:644  %b = load i32, ptr %b.ptr645  br i1 %v, label %inner_loop_begin, label %loop_latch646; The 'inner_loop_b' unswitched loop.647;648; CHECK:       loop_begin.split:649; CHECK-NEXT:    br label %inner_loop_begin650;651; CHECK:       inner_loop_begin:652; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr653; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr654; CHECK-NEXT:    br label %inner_loop_b655;656; CHECK:       inner_loop_b:657; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr658; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_begin, label %loop_latch659 660loop_latch:661  %b.phi = phi i32 [ %b, %inner_loop_b ]662  %v2 = load i1, ptr %ptr663  br i1 %v2, label %loop_begin, label %loop_exit664; CHECK:       loop_latch:665; CHECK-NEXT:    %[[B_INNER_LCSSA:.*]] = phi i32 [ %[[B]], %inner_loop_b ]666; CHECK-NEXT:    %[[V2:.*]] = load i1, ptr %ptr667; CHECK-NEXT:    br i1 %[[V2]], label %loop_begin, label %loop_exit.loopexit1668 669loop_exit:670  %ab.phi = phi i32 [ %a, %inner_loop_begin ], [ %b.phi, %loop_latch ]671  ret i32 %ab.phi672; CHECK:       loop_exit.loopexit:673; CHECK-NEXT:    br label %loop_exit674;675; CHECK:       loop_exit.loopexit1:676; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B_INNER_LCSSA]], %loop_latch ]677; CHECK-NEXT:    br label %loop_exit678;679; CHECK:       loop_exit:680; CHECK-NEXT:    %[[AB_PHI:.*]] = phi i32 [ %[[A_LCSSA]], %loop_exit.loopexit ], [ %[[B_LCSSA]], %loop_exit.loopexit1 ]681; CHECK-NEXT:    ret i32 %[[AB_PHI]]682}683 684; Test that we can unswitch a condition where we end up only cloning some of685; the nested loops and needing to delete some of the nested loops.686define i32 @test6(ptr %ptr, i1 %cond1, ptr %a.ptr, ptr %b.ptr) {687; CHECK-LABEL: @test6(688entry:689  br label %loop_begin690; CHECK-NEXT:  entry:691; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split692 693loop_begin:694  %v = load i1, ptr %ptr695  br i1 %cond1, label %loop_a, label %loop_b696 697loop_a:698  br label %loop_a_inner699 700loop_a_inner:701  %va = load i1, ptr %ptr702  %a = load i32, ptr %a.ptr703  br i1 %va, label %loop_a_inner, label %loop_a_inner_exit704 705loop_a_inner_exit:706  %a.lcssa = phi i32 [ %a, %loop_a_inner ]707  br label %latch708; The 'loop_a' cloned loop.709;710; CHECK:       entry.split.us:711; CHECK-NEXT:    br label %loop_begin.us712;713; CHECK:       loop_begin.us:714; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr715; CHECK-NEXT:    br label %loop_a.us716;717; CHECK:       loop_a.us:718; CHECK-NEXT:    br label %loop_a_inner.us719;720; CHECK:       loop_a_inner.us721; CHECK-NEXT:    %[[VA:.*]] = load i1, ptr %ptr722; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr723; CHECK-NEXT:    br i1 %[[VA]], label %loop_a_inner.us, label %loop_a_inner_exit.us724;725; CHECK:       loop_a_inner_exit.us:726; CHECK-NEXT:    %[[A_INNER_LCSSA:.*]] = phi i32 [ %[[A]], %loop_a_inner.us ]727; CHECK-NEXT:    br label %latch.us728;729; CHECK:       latch.us:730; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A_INNER_LCSSA]], %loop_a_inner_exit.us ]731; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us732;733; CHECK:       loop_exit.split.us:734; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_PHI]], %latch.us ]735; CHECK-NEXT:    br label %loop_exit736 737loop_b:738  br label %loop_b_inner739 740loop_b_inner:741  %vb = load i1, ptr %ptr742  %b = load i32, ptr %b.ptr743  br i1 %vb, label %loop_b_inner, label %loop_b_inner_exit744 745loop_b_inner_exit:746  %b.lcssa = phi i32 [ %b, %loop_b_inner ]747  br label %latch748 749latch:750  %ab.phi = phi i32 [ %a.lcssa, %loop_a_inner_exit ], [ %b.lcssa, %loop_b_inner_exit ]751  br i1 %v, label %loop_begin, label %loop_exit752; The 'loop_b' unswitched loop.753;754; CHECK:       entry.split:755; CHECK-NEXT:    br label %loop_begin756;757; CHECK:       loop_begin:758; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr759; CHECK-NEXT:    br label %loop_b760;761; CHECK:       loop_b:762; CHECK-NEXT:    br label %loop_b_inner763;764; CHECK:       loop_b_inner765; CHECK-NEXT:    %[[VB:.*]] = load i1, ptr %ptr766; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr767; CHECK-NEXT:    br i1 %[[VB]], label %loop_b_inner, label %loop_b_inner_exit768;769; CHECK:       loop_b_inner_exit:770; CHECK-NEXT:    %[[B_INNER_LCSSA:.*]] = phi i32 [ %[[B]], %loop_b_inner ]771; CHECK-NEXT:    br label %latch772;773; CHECK:       latch:774; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit.split775;776; CHECK:       loop_exit.split:777; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B_INNER_LCSSA]], %latch ]778; CHECK-NEXT:    br label %loop_exit779 780loop_exit:781  %ab.lcssa = phi i32 [ %ab.phi, %latch ]782  ret i32 %ab.lcssa783; CHECK:       loop_exit:784; CHECK-NEXT:    %[[AB_PHI:.*]] = phi i32 [ %[[B_LCSSA]], %loop_exit.split ], [ %[[A_LCSSA]], %loop_exit.split.us ]785; CHECK-NEXT:    ret i32 %[[AB_PHI]]786}787 788; Test that when unswitching a deeply nested loop condition in a way that789; produces a non-loop clone that can reach multiple exit blocks which are part790; of different outer loops we correctly divide the cloned loop blocks between791; the outer loops based on reachability.792define i32 @test7a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {793; CHECK-LABEL: @test7a(794entry:795  br label %loop_begin796; CHECK-NEXT:  entry:797; CHECK-NEXT:    br label %loop_begin798 799loop_begin:800  %a = load i32, ptr %a.ptr801  br label %inner_loop_begin802; CHECK:       loop_begin:803; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr804; CHECK-NEXT:    br label %inner_loop_begin805 806inner_loop_begin:807  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]808  %cond = load i1, ptr %cond.ptr809  %b = load i32, ptr %b.ptr810  br label %inner_inner_loop_begin811; CHECK:       inner_loop_begin:812; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]813; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr814; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr815; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]816; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_loop_begin.split.us, label %inner_loop_begin.split817 818inner_inner_loop_begin:819  %v1 = load i1, ptr %ptr820  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b821 822inner_inner_loop_a:823  %v2 = load i1, ptr %ptr824  br i1 %v2, label %loop_exit, label %inner_inner_loop_c825 826inner_inner_loop_b:827  %v3 = load i1, ptr %ptr828  br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c829 830inner_inner_loop_c:831  %v4 = load i1, ptr %ptr832  br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d833 834inner_inner_loop_d:835  br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_begin836; The cloned copy that always exits with the adjustments required to fix up837; loop exits.838;839; CHECK:       inner_loop_begin.split.us:840; CHECK-NEXT:    br label %inner_inner_loop_begin.us841;842; CHECK:       inner_inner_loop_begin.us:843; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr844; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a.us, label %inner_inner_loop_b.us845;846; CHECK:       inner_inner_loop_b.us:847; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr848; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_exit.split.us, label %inner_inner_loop_c.us.loopexit849;850; CHECK:       inner_inner_loop_a.us:851; CHECK-NEXT:    %[[A_NEW_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_begin.us ]852; CHECK-NEXT:    %[[B_NEW_LCSSA:.*]] = phi i32 [ %[[B]], %inner_inner_loop_begin.us ]853; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr854; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split.us, label %inner_inner_loop_c.us855;856; CHECK:       inner_inner_loop_c.us.loopexit:857; CHECK-NEXT:    br label %inner_inner_loop_c.us858;859; CHECK:       inner_inner_loop_c.us:860; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr861; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit.split.us, label %inner_inner_loop_d.us862;863; CHECK:       inner_inner_loop_d.us:864; CHECK-NEXT:    br label %inner_loop_exit.loopexit.split865;866; CHECK:       inner_inner_loop_exit.split.us:867; CHECK-NEXT:    br label %inner_inner_loop_exit868;869; CHECK:       loop_exit.split.us:870; CHECK-NEXT:    %[[A_LCSSA_US:.*]] = phi i32 [ %[[A_NEW_LCSSA]], %inner_inner_loop_a.us ]871; CHECK-NEXT:    %[[B_LCSSA_US:.*]] = phi i32 [ %[[B_NEW_LCSSA]], %inner_inner_loop_a.us ]872; CHECK-NEXT:    br label %loop_exit873;874; CHECK:       inner_loop_exit.loopexit.split.us:875; CHECK-NEXT:    br label %inner_loop_exit.loopexit876;877; The original copy that continues to loop.878;879; CHECK:       inner_loop_begin.split:880; CHECK-NEXT:    br label %inner_inner_loop_begin881;882; CHECK:       inner_inner_loop_begin:883; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr884; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a, label %inner_inner_loop_b885;886; CHECK:       inner_inner_loop_a:887; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr888; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split, label %inner_inner_loop_c889;890; CHECK:       inner_inner_loop_b:891; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr892; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_exit.split, label %inner_inner_loop_c893;894; CHECK:       inner_inner_loop_c:895; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr896; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit.split, label %inner_inner_loop_d897;898; CHECK:       inner_inner_loop_d:899; CHECK-NEXT:    br label %inner_inner_loop_begin900;901; CHECK:       inner_inner_loop_exit.split:902; CHECK-NEXT:    br label %inner_inner_loop_exit903 904inner_inner_loop_exit:905  %a2 = load i32, ptr %a.ptr906  %v5 = load i1, ptr %ptr907  br i1 %v5, label %inner_loop_exit, label %inner_loop_begin908; CHECK:       inner_inner_loop_exit:909; CHECK-NEXT:    %[[A2]] = load i32, ptr %a.ptr910; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr911; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit1, label %inner_loop_begin912 913inner_loop_exit:914  br label %loop_begin915; CHECK:       inner_loop_exit.loopexit.split:916; CHECK-NEXT:    br label %inner_loop_exit.loopexit917;918; CHECK:       inner_loop_exit.loopexit:919; CHECK-NEXT:    br label %inner_loop_exit920;921; CHECK:       inner_loop_exit.loopexit1:922; CHECK-NEXT:    br label %inner_loop_exit923;924; CHECK:       inner_loop_exit:925; CHECK-NEXT:    br label %loop_begin926 927loop_exit:928  %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ]929  %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ]930  %result = add i32 %a.lcssa, %b.lcssa931  ret i32 %result932; CHECK:       loop_exit.split:933; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_a ]934; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %inner_inner_loop_a ]935; CHECK-NEXT:    br label %loop_exit936;937; CHECK:       loop_exit:938; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A_LCSSA]], %loop_exit.split ], [ %[[A_LCSSA_US]], %loop_exit.split.us ]939; CHECK-NEXT:    %[[B_PHI:.*]] = phi i32 [ %[[B_LCSSA]], %loop_exit.split ], [ %[[B_LCSSA_US]], %loop_exit.split.us ]940; CHECK-NEXT:    %[[RESULT:.*]] = add i32 %[[A_PHI]], %[[B_PHI]]941; CHECK-NEXT:    ret i32 %[[RESULT]]942}943 944; Same pattern as @test7a but here the original loop becomes a non-loop that945; can reach multiple exit blocks which are part of different outer loops.946define i32 @test7b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {947; CHECK-LABEL: @test7b(948entry:949  br label %loop_begin950; CHECK-NEXT:  entry:951; CHECK-NEXT:    br label %loop_begin952 953loop_begin:954  %a = load i32, ptr %a.ptr955  br label %inner_loop_begin956; CHECK:       loop_begin:957; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr958; CHECK-NEXT:    br label %inner_loop_begin959 960inner_loop_begin:961  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]962  %cond = load i1, ptr %cond.ptr963  %b = load i32, ptr %b.ptr964  br label %inner_inner_loop_begin965; CHECK:       inner_loop_begin:966; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]967; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr968; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr969; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]970; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_loop_begin.split.us, label %inner_loop_begin.split971 972inner_inner_loop_begin:973  %v1 = load i1, ptr %ptr974  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b975 976inner_inner_loop_a:977  %v2 = load i1, ptr %ptr978  br i1 %v2, label %loop_exit, label %inner_inner_loop_c979 980inner_inner_loop_b:981  %v3 = load i1, ptr %ptr982  br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c983 984inner_inner_loop_c:985  %v4 = load i1, ptr %ptr986  br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d987 988inner_inner_loop_d:989  br i1 %cond, label %inner_inner_loop_begin, label %inner_loop_exit990; The cloned copy that continues looping.991;992; CHECK:       inner_loop_begin.split.us:993; CHECK-NEXT:    br label %inner_inner_loop_begin.us994;995; CHECK:       inner_inner_loop_begin.us:996; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr997; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a.us, label %inner_inner_loop_b.us998;999; CHECK:       inner_inner_loop_b.us:1000; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1001; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_exit.split.us, label %inner_inner_loop_c.us1002;1003; CHECK:       inner_inner_loop_a.us:1004; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1005; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split.us, label %inner_inner_loop_c.us1006;1007; CHECK:       inner_inner_loop_c.us:1008; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1009; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit.split.us, label %inner_inner_loop_d.us1010;1011; CHECK:       inner_inner_loop_d.us:1012; CHECK-NEXT:    br label %inner_inner_loop_begin.us1013;1014; CHECK:       inner_inner_loop_exit.split.us:1015; CHECK-NEXT:    br label %inner_inner_loop_exit1016;1017; CHECK:       loop_exit.split.us:1018; CHECK-NEXT:    %[[A_LCSSA_US:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_a.us ]1019; CHECK-NEXT:    %[[B_LCSSA_US:.*]] = phi i32 [ %[[B]], %inner_inner_loop_a.us ]1020; CHECK-NEXT:    br label %loop_exit1021;1022; CHECK:       inner_loop_exit.loopexit.split.us:1023; CHECK-NEXT:    br label %inner_loop_exit.loopexit1024;1025; The original copy that now always exits and needs adjustments for exit1026; blocks.1027;1028; CHECK:       inner_loop_begin.split:1029; CHECK-NEXT:    br label %inner_inner_loop_begin1030;1031; CHECK:       inner_inner_loop_begin:1032; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1033; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a, label %inner_inner_loop_b1034;1035; CHECK:       inner_inner_loop_a:1036; CHECK-NEXT:    %[[A_NEW_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_begin ]1037; CHECK-NEXT:    %[[B_NEW_LCSSA:.*]] = phi i32 [ %[[B]], %inner_inner_loop_begin ]1038; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1039; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split, label %inner_inner_loop_c1040;1041; CHECK:       inner_inner_loop_b:1042; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1043; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_exit.split, label %inner_inner_loop_c.loopexit1044;1045; CHECK:       inner_inner_loop_c.loopexit:1046; CHECK-NEXT:    br label %inner_inner_loop_c1047;1048; CHECK:       inner_inner_loop_c:1049; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1050; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit.split, label %inner_inner_loop_d1051;1052; CHECK:       inner_inner_loop_d:1053; CHECK-NEXT:    br label %inner_loop_exit.loopexit.split1054;1055; CHECK:       inner_inner_loop_exit.split:1056; CHECK-NEXT:    br label %inner_inner_loop_exit1057 1058inner_inner_loop_exit:1059  %a2 = load i32, ptr %a.ptr1060  %v5 = load i1, ptr %ptr1061  br i1 %v5, label %inner_loop_exit, label %inner_loop_begin1062; CHECK:       inner_inner_loop_exit:1063; CHECK-NEXT:    %[[A2]] = load i32, ptr %a.ptr1064; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1065; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit1, label %inner_loop_begin1066 1067inner_loop_exit:1068  br label %loop_begin1069; CHECK:       inner_loop_exit.loopexit.split:1070; CHECK-NEXT:    br label %inner_loop_exit.loopexit1071;1072; CHECK:       inner_loop_exit.loopexit:1073; CHECK-NEXT:    br label %inner_loop_exit1074;1075; CHECK:       inner_loop_exit.loopexit1:1076; CHECK-NEXT:    br label %inner_loop_exit1077;1078; CHECK:       inner_loop_exit:1079; CHECK-NEXT:    br label %loop_begin1080 1081loop_exit:1082  %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ]1083  %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ]1084  %result = add i32 %a.lcssa, %b.lcssa1085  ret i32 %result1086; CHECK:       loop_exit.split:1087; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_NEW_LCSSA]], %inner_inner_loop_a ]1088; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B_NEW_LCSSA]], %inner_inner_loop_a ]1089; CHECK-NEXT:    br label %loop_exit1090;1091; CHECK:       loop_exit:1092; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A_LCSSA]], %loop_exit.split ], [ %[[A_LCSSA_US]], %loop_exit.split.us ]1093; CHECK-NEXT:    %[[B_PHI:.*]] = phi i32 [ %[[B_LCSSA]], %loop_exit.split ], [ %[[B_LCSSA_US]], %loop_exit.split.us ]1094; CHECK-NEXT:    %[[RESULT:.*]] = add i32 %[[A_PHI]], %[[B_PHI]]1095; CHECK-NEXT:    ret i32 %[[RESULT]]1096}1097 1098; Test that when the exit block set of an inner loop changes to start at a less1099; high level of the loop nest we correctly hoist the loop up the nest.1100define i32 @test8a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1101; CHECK-LABEL: @test8a(1102entry:1103  br label %loop_begin1104; CHECK-NEXT:  entry:1105; CHECK-NEXT:    br label %loop_begin1106 1107loop_begin:1108  %a = load i32, ptr %a.ptr1109  br label %inner_loop_begin1110; CHECK:       loop_begin:1111; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1112; CHECK-NEXT:    br label %inner_loop_begin1113 1114inner_loop_begin:1115  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]1116  %cond = load i1, ptr %cond.ptr1117  %b = load i32, ptr %b.ptr1118  br label %inner_inner_loop_begin1119; CHECK:       inner_loop_begin:1120; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]1121; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1122; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1123; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]1124; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_loop_begin.split.us, label %inner_loop_begin.split1125 1126inner_inner_loop_begin:1127  %v1 = load i1, ptr %ptr1128  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b1129 1130inner_inner_loop_a:1131  %v2 = load i1, ptr %ptr1132  br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit1133 1134inner_inner_loop_b:1135  br i1 %cond, label %inner_inner_loop_latch, label %inner_inner_loop_exit1136 1137inner_inner_loop_latch:1138  br label %inner_inner_loop_begin1139; The cloned region is now an exit from the inner loop.1140;1141; CHECK:       inner_loop_begin.split.us:1142; CHECK-NEXT:    %[[A_INNER_INNER_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_loop_begin ]1143; CHECK-NEXT:    br label %inner_inner_loop_begin.us1144;1145; CHECK:       inner_inner_loop_begin.us:1146; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1147; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a.us, label %inner_inner_loop_b.us1148;1149; CHECK:       inner_inner_loop_b.us:1150; CHECK-NEXT:    br label %inner_inner_loop_latch.us1151;1152; CHECK:       inner_inner_loop_a.us:1153; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1154; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_latch.us, label %inner_loop_exit.loopexit.split.us1155;1156; CHECK:       inner_inner_loop_latch.us:1157; CHECK-NEXT:    br label %inner_inner_loop_begin.us1158;1159; CHECK:       inner_loop_exit.loopexit.split.us:1160; CHECK-NEXT:    %[[A_INNER_LCSSA_US:.*]] = phi i32 [ %[[A_INNER_INNER_LCSSA]], %inner_inner_loop_a.us ]1161; CHECK-NEXT:    br label %inner_loop_exit.loopexit1162;1163; The original region exits the loop earlier.1164;1165; CHECK:       inner_loop_begin.split:1166; CHECK-NEXT:    br label %inner_inner_loop_begin1167;1168; CHECK:       inner_inner_loop_begin:1169; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1170; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a, label %inner_inner_loop_b1171;1172; CHECK:       inner_inner_loop_a:1173; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1174; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_latch, label %inner_loop_exit.loopexit.split1175;1176; CHECK:       inner_inner_loop_b:1177; CHECK-NEXT:    br label %inner_inner_loop_exit1178;1179; CHECK:       inner_inner_loop_latch:1180; CHECK-NEXT:    br label %inner_inner_loop_begin1181 1182inner_inner_loop_exit:1183  %a2 = load i32, ptr %a.ptr1184  %v4 = load i1, ptr %ptr1185  br i1 %v4, label %inner_loop_exit, label %inner_loop_begin1186; CHECK:       inner_inner_loop_exit:1187; CHECK-NEXT:    %[[A2]] = load i32, ptr %a.ptr1188; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1189; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit1, label %inner_loop_begin1190 1191inner_loop_exit:1192  %v5 = load i1, ptr %ptr1193  br i1 %v5, label %loop_exit, label %loop_begin1194; CHECK:       inner_loop_exit.loopexit.split:1195; CHECK-NEXT:    %[[A_INNER_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_a ]1196; CHECK-NEXT:    br label %inner_loop_exit.loopexit1197;1198; CHECK:       inner_loop_exit.loopexit:1199; CHECK-NEXT:    %[[A_INNER_US_PHI:.*]] = phi i32 [ %[[A_INNER_LCSSA]], %inner_loop_exit.loopexit.split ], [ %[[A_INNER_LCSSA_US]], %inner_loop_exit.loopexit.split.us ]1200; CHECK-NEXT:    br label %inner_loop_exit1201;1202; CHECK:       inner_loop_exit.loopexit1:1203; CHECK-NEXT:    %[[A_INNER_LCSSA2:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_exit ]1204; CHECK-NEXT:    br label %inner_loop_exit1205;1206; CHECK:       inner_loop_exit:1207; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A_INNER_LCSSA2]], %inner_loop_exit.loopexit1 ], [ %[[A_INNER_US_PHI]], %inner_loop_exit.loopexit ]1208; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1209; CHECK-NEXT:    br i1 %[[V]], label %loop_exit, label %loop_begin1210 1211loop_exit:1212  %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ]1213  ret i32 %a.lcssa1214; CHECK:       loop_exit:1215; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_loop_exit ]1216; CHECK-NEXT:    ret i32 %[[A_LCSSA]]1217}1218 1219; Same pattern as @test8a but where the original loop looses an exit block and1220; needs to be hoisted up the nest.1221define i32 @test8b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1222; CHECK-LABEL: @test8b(1223entry:1224  br label %loop_begin1225; CHECK-NEXT:  entry:1226; CHECK-NEXT:    br label %loop_begin1227 1228loop_begin:1229  %a = load i32, ptr %a.ptr1230  br label %inner_loop_begin1231; CHECK:       loop_begin:1232; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1233; CHECK-NEXT:    br label %inner_loop_begin1234 1235inner_loop_begin:1236  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]1237  %cond = load i1, ptr %cond.ptr1238  %b = load i32, ptr %b.ptr1239  br label %inner_inner_loop_begin1240; CHECK:       inner_loop_begin:1241; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A]], %loop_begin ], [ %[[A2:.*]], %inner_inner_loop_exit ]1242; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1243; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1244; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]1245; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_loop_begin.split.us, label %inner_loop_begin.split1246 1247inner_inner_loop_begin:1248  %v1 = load i1, ptr %ptr1249  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b1250 1251inner_inner_loop_a:1252  %v2 = load i1, ptr %ptr1253  br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit1254 1255inner_inner_loop_b:1256  br i1 %cond, label %inner_inner_loop_exit, label %inner_inner_loop_latch1257 1258inner_inner_loop_latch:1259  br label %inner_inner_loop_begin1260; The cloned region is similar to before but with one earlier exit.1261;1262; CHECK:       inner_loop_begin.split.us:1263; CHECK-NEXT:    br label %inner_inner_loop_begin.us1264;1265; CHECK:       inner_inner_loop_begin.us:1266; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1267; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a.us, label %inner_inner_loop_b.us1268;1269; CHECK:       inner_inner_loop_b.us:1270; CHECK-NEXT:    br label %inner_inner_loop_exit.split.us1271;1272; CHECK:       inner_inner_loop_a.us:1273; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1274; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_latch.us, label %inner_loop_exit.loopexit.split.us1275;1276; CHECK:       inner_inner_loop_latch.us:1277; CHECK-NEXT:    br label %inner_inner_loop_begin.us1278;1279; CHECK:       inner_inner_loop_exit.split.us:1280; CHECK-NEXT:    br label %inner_inner_loop_exit1281;1282; CHECK:       inner_loop_exit.loopexit.split.us:1283; CHECK-NEXT:    %[[A_INNER_LCSSA_US:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_a.us ]1284; CHECK-NEXT:    br label %inner_loop_exit.loopexit1285;1286; The original region is now an exit in the preheader.1287;1288; CHECK:       inner_loop_begin.split:1289; CHECK-NEXT:    %[[A_INNER_INNER_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_loop_begin ]1290; CHECK-NEXT:    br label %inner_inner_loop_begin1291;1292; CHECK:       inner_inner_loop_begin:1293; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1294; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_a, label %inner_inner_loop_b1295;1296; CHECK:       inner_inner_loop_a:1297; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1298; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_latch, label %inner_loop_exit.loopexit.split1299;1300; CHECK:       inner_inner_loop_b:1301; CHECK-NEXT:    br label %inner_inner_loop_latch1302;1303; CHECK:       inner_inner_loop_latch:1304; CHECK-NEXT:    br label %inner_inner_loop_begin1305 1306inner_inner_loop_exit:1307  %a2 = load i32, ptr %a.ptr1308  %v4 = load i1, ptr %ptr1309  br i1 %v4, label %inner_loop_exit, label %inner_loop_begin1310; CHECK:       inner_inner_loop_exit:1311; CHECK-NEXT:    %[[A2]] = load i32, ptr %a.ptr1312; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1313; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.loopexit1, label %inner_loop_begin1314 1315inner_loop_exit:1316  %v5 = load i1, ptr %ptr1317  br i1 %v5, label %loop_exit, label %loop_begin1318; CHECK:       inner_loop_exit.loopexit.split:1319; CHECK-NEXT:    %[[A_INNER_LCSSA:.*]] = phi i32 [ %[[A_INNER_INNER_LCSSA]], %inner_inner_loop_a ]1320; CHECK-NEXT:    br label %inner_loop_exit.loopexit1321;1322; CHECK:       inner_loop_exit.loopexit:1323; CHECK-NEXT:    %[[A_INNER_US_PHI:.*]] = phi i32 [ %[[A_INNER_LCSSA]], %inner_loop_exit.loopexit.split ], [ %[[A_INNER_LCSSA_US]], %inner_loop_exit.loopexit.split.us ]1324; CHECK-NEXT:    br label %inner_loop_exit1325;1326; CHECK:       inner_loop_exit.loopexit1:1327; CHECK-NEXT:    %[[A_INNER_LCSSA2:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_inner_loop_exit ]1328; CHECK-NEXT:    br label %inner_loop_exit1329;1330; CHECK:       inner_loop_exit:1331; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A_INNER_LCSSA2]], %inner_loop_exit.loopexit1 ], [ %[[A_INNER_US_PHI]], %inner_loop_exit.loopexit ]1332; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1333; CHECK-NEXT:    br i1 %[[V]], label %loop_exit, label %loop_begin1334 1335loop_exit:1336  %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ]1337  ret i32 %a.lcssa1338; CHECK:       loop_exit:1339; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_loop_exit ]1340; CHECK-NEXT:    ret i32 %[[A_LCSSA]]1341}1342 1343; Test for when unswitching produces a clone of an inner loop but1344; the clone no longer has an exiting edge *at all* and loops infinitely.1345; Because it doesn't ever exit to the outer loop it is no longer an inner loop1346; but needs to be hoisted up the nest to be a top-level loop.1347define i32 @test9a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1348; CHECK-LABEL: @test9a(1349entry:1350  br label %loop_begin1351; CHECK-NEXT:  entry:1352; CHECK-NEXT:    br label %loop_begin1353 1354loop_begin:1355  %b = load i32, ptr %b.ptr1356  %cond = load i1, ptr %cond.ptr1357  br label %inner_loop_begin1358; CHECK:       loop_begin:1359; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1360; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1361; CHECK-NEXT:    br i1 %[[COND]], label %loop_begin.split.us, label %loop_begin.split1362 1363inner_loop_begin:1364  %a = load i32, ptr %a.ptr1365  br i1 %cond, label %inner_loop_latch, label %inner_loop_exit1366 1367inner_loop_latch:1368  call void @sink1(i32 %b)1369  br label %inner_loop_begin1370; The cloned inner loop ends up as an infinite loop and thus being a top-level1371; loop with the preheader as an exit block of the outer loop.1372;1373; CHECK:       loop_begin.split.us1374; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_begin ]1375; CHECK-NEXT:    br label %inner_loop_begin.us1376;1377; CHECK:       inner_loop_begin.us:1378; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1379; CHECK-NEXT:    br label %inner_loop_latch.us1380;1381; CHECK:       inner_loop_latch.us:1382; CHECK-NEXT:    call void @sink1(i32 %[[B_LCSSA]])1383; CHECK-NEXT:    br label %inner_loop_begin.us1384;1385; The original loop becomes boring non-loop code.1386;1387; CHECK:       loop_begin.split1388; CHECK-NEXT:    br label %inner_loop_begin1389;1390; CHECK:       inner_loop_begin:1391; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1392; CHECK-NEXT:    br label %inner_loop_exit1393 1394inner_loop_exit:1395  %a.inner_lcssa = phi i32 [ %a, %inner_loop_begin ]1396  %v = load i1, ptr %ptr1397  br i1 %v, label %loop_begin, label %loop_exit1398; CHECK:       inner_loop_exit:1399; CHECK-NEXT:    %[[A_INNER_LCSSA:.*]] = phi i32 [ %[[A]], %inner_loop_begin ]1400; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1401; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit1402 1403loop_exit:1404  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]1405  ret i32 %a.lcssa1406; CHECK:       loop_exit:1407; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_LCSSA]], %inner_loop_exit ]1408; CHECK-NEXT:    ret i32 %[[A_LCSSA]]1409}1410 1411; The same core pattern as @test9a, but instead of the cloned loop becoming an1412; infinite loop, the original loop has its only exit unswitched and the1413; original loop becomes infinite and must be hoisted out of the loop nest.1414define i32 @test9b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1415; CHECK-LABEL: @test9b(1416entry:1417  br label %loop_begin1418; CHECK-NEXT:  entry:1419; CHECK-NEXT:    br label %loop_begin1420 1421loop_begin:1422  %b = load i32, ptr %b.ptr1423  %cond = load i1, ptr %cond.ptr1424  br label %inner_loop_begin1425; CHECK:       loop_begin:1426; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1427; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1428; CHECK-NEXT:    br i1 %[[COND]], label %loop_begin.split.us, label %loop_begin.split1429 1430inner_loop_begin:1431  %a = load i32, ptr %a.ptr1432  br i1 %cond, label %inner_loop_exit, label %inner_loop_latch1433 1434inner_loop_latch:1435  call void @sink1(i32 %b)1436  br label %inner_loop_begin1437; The cloned inner loop becomes a boring non-loop.1438;1439; CHECK:       loop_begin.split.us1440; CHECK-NEXT:    br label %inner_loop_begin.us1441;1442; CHECK:       inner_loop_begin.us:1443; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1444; CHECK-NEXT:    br label %inner_loop_exit.split.us1445;1446; CHECK:       inner_loop_exit.split.us1447; CHECK-NEXT:    %[[A_INNER_LCSSA_US:.*]] = phi i32 [ %[[A]], %inner_loop_begin.us ]1448; CHECK-NEXT:    br label %inner_loop_exit1449;1450; The original loop becomes an infinite loop and thus a top-level loop with the1451; preheader as an exit block for the outer loop.1452;1453; CHECK:       loop_begin.split1454; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %loop_begin ]1455; CHECK-NEXT:    br label %inner_loop_begin1456;1457; CHECK:       inner_loop_begin:1458; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1459; CHECK-NEXT:    br label %inner_loop_latch1460;1461; CHECK:       inner_loop_latch:1462; CHECK-NEXT:    call void @sink1(i32 %[[B_LCSSA]])1463; CHECK-NEXT:    br label %inner_loop_begin1464 1465inner_loop_exit:1466  %a.inner_lcssa = phi i32 [ %a, %inner_loop_begin ]1467  %v = load i1, ptr %ptr1468  br i1 %v, label %loop_begin, label %loop_exit1469; CHECK:       inner_loop_exit:1470; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1471; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit1472 1473loop_exit:1474  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]1475  ret i32 %a.lcssa1476; CHECK:       loop_exit:1477; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_LCSSA_US]], %inner_loop_exit ]1478; CHECK-NEXT:    ret i32 %[[A_LCSSA]]1479}1480 1481; Test that requires re-forming dedicated exits for the cloned loop.1482define i32 @test10a(ptr %ptr, i1 %cond, ptr %a.ptr) {1483; CHECK-LABEL: @test10a(1484entry:1485  br label %loop_begin1486; CHECK-NEXT:  entry:1487; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %cond1488; CHECK-NEXT:    br i1 %[[FROZEN]], label %entry.split.us, label %entry.split1489 1490loop_begin:1491  %a = load i32, ptr %a.ptr1492  %v1 = load i1, ptr %ptr1493  br i1 %v1, label %loop_a, label %loop_b1494 1495loop_a:1496  %v2 = load i1, ptr %ptr1497  br i1 %v2, label %loop_exit, label %loop_begin1498 1499loop_b:1500  br i1 %cond, label %loop_exit, label %loop_begin1501; The cloned loop with one edge as a direct exit.1502;1503; CHECK:       entry.split.us:1504; CHECK-NEXT:    br label %loop_begin.us1505;1506; CHECK:       loop_begin.us:1507; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1508; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1509; CHECK-NEXT:    br i1 %[[V]], label %loop_a.us, label %loop_b.us1510;1511; CHECK:       loop_b.us:1512; CHECK-NEXT:    %[[A_LCSSA_B:.*]] = phi i32 [ %[[A]], %loop_begin.us ]1513; CHECK-NEXT:    br label %loop_exit.split.us1514;1515; CHECK:       loop_a.us:1516; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1517; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split.us.loopexit, label %loop_begin.backedge.us1518;1519; CHECK:       loop_begin.backedge.us:1520; CHECK-NEXT:    br label %loop_begin.us1521;1522; CHECK:       loop_exit.split.us.loopexit:1523; CHECK-NEXT:    %[[A_LCSSA_A:.*]] = phi i32 [ %[[A]], %loop_a.us ]1524; CHECK-NEXT:    br label %loop_exit1525;1526; CHECK:       loop_exit.split.us:1527; CHECK-NEXT:    %[[A_PHI_US:.*]] = phi i32 [ %[[A_LCSSA_B]], %loop_b.us ], [ %[[A_LCSSA_A]], %loop_exit.split.us.loopexit ]1528; CHECK-NEXT:    br label %loop_exit1529 1530; The original loop without one 'loop_exit' edge.1531;1532; CHECK:       entry.split:1533; CHECK-NEXT:    br label %loop_begin1534;1535; CHECK:       loop_begin:1536; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1537; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1538; CHECK-NEXT:    br i1 %[[V]], label %loop_a, label %loop_b1539;1540; CHECK:       loop_a:1541; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1542; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split, label %loop_begin.backedge1543;1544; CHECK:       loop_begin.backedge:1545; CHECK-NEXT:    br label %loop_begin1546;1547; CHECK:       loop_b:1548; CHECK-NEXT:    br label %loop_begin.backedge1549;1550; CHECK:       loop_exit.split:1551; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %loop_a ]1552; CHECK-NEXT:    br label %loop_exit1553 1554loop_exit:1555  %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ]1556  ret i32 %a.lcssa1557; CHECK:       loop_exit:1558; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A_LCSSA]], %loop_exit.split ], [ %[[A_PHI_US]], %loop_exit.split.us ]1559; CHECK-NEXT:    ret i32 %[[A_PHI]]1560}1561 1562; Test that requires re-forming dedicated exits for the original loop.1563define i32 @test10b(ptr %ptr, i1 %cond, ptr %a.ptr) {1564; CHECK-LABEL: @test10b(1565entry:1566  br label %loop_begin1567; CHECK-NEXT:  entry:1568; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %cond1569; CHECK-NEXT:    br i1 %[[FROZEN]], label %entry.split.us, label %entry.split1570 1571loop_begin:1572  %a = load i32, ptr %a.ptr1573  %v1 = load i1, ptr %ptr1574  br i1 %v1, label %loop_a, label %loop_b1575 1576loop_a:1577  %v2 = load i1, ptr %ptr1578  br i1 %v2, label %loop_begin, label %loop_exit1579 1580loop_b:1581  br i1 %cond, label %loop_begin, label %loop_exit1582; The cloned loop without one of the exits.1583;1584; CHECK:       entry.split.us:1585; CHECK-NEXT:    br label %loop_begin.us1586;1587; CHECK:       loop_begin.us:1588; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1589; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1590; CHECK-NEXT:    br i1 %[[V]], label %loop_a.us, label %loop_b.us1591;1592; CHECK:       loop_b.us:1593; CHECK-NEXT:    br label %loop_begin.backedge.us1594;1595; CHECK:       loop_a.us:1596; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1597; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.backedge.us, label %loop_exit.split.us1598;1599; CHECK:       loop_begin.backedge.us:1600; CHECK-NEXT:    br label %loop_begin.us1601;1602; CHECK:       loop_exit.split.us:1603; CHECK-NEXT:    %[[A_LCSSA_US:.*]] = phi i32 [ %[[A]], %loop_a.us ]1604; CHECK-NEXT:    br label %loop_exit1605 1606; The original loop without one 'loop_exit' edge.1607;1608; CHECK:       entry.split:1609; CHECK-NEXT:    br label %loop_begin1610;1611; CHECK:       loop_begin:1612; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1613; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1614; CHECK-NEXT:    br i1 %[[V]], label %loop_a, label %loop_b1615;1616; CHECK:       loop_a:1617; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1618; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.backedge, label %loop_exit.split.loopexit1619;1620; CHECK:       loop_begin.backedge:1621; CHECK-NEXT:    br label %loop_begin1622;1623; CHECK:       loop_b:1624; CHECK-NEXT:    %[[A_LCSSA_B:.*]] = phi i32 [ %[[A]], %loop_begin ]1625; CHECK-NEXT:    br label %loop_exit.split1626;1627; CHECK:       loop_exit.split.loopexit:1628; CHECK-NEXT:    %[[A_LCSSA_A:.*]] = phi i32 [ %[[A]], %loop_a ]1629; CHECK-NEXT:    br label %loop_exit.split1630;1631; CHECK:       loop_exit.split:1632; CHECK-NEXT:    %[[A_PHI_SPLIT:.*]] = phi i32 [ %[[A_LCSSA_B]], %loop_b ], [ %[[A_LCSSA_A]], %loop_exit.split.loopexit ]1633; CHECK-NEXT:    br label %loop_exit1634 1635loop_exit:1636  %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ]1637  ret i32 %a.lcssa1638; CHECK:       loop_exit:1639; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A_PHI_SPLIT]], %loop_exit.split ], [ %[[A_LCSSA_US]], %loop_exit.split.us ]1640; CHECK-NEXT:    ret i32 %[[A_PHI]]1641}1642 1643; Check that if a cloned inner loop after unswitching doesn't loop and directly1644; exits even an outer loop, we don't add the cloned preheader to the outer1645; loop and do add the needed LCSSA phi nodes for the new exit block from the1646; outer loop.1647define i32 @test11a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1648; CHECK-LABEL: @test11a(1649entry:1650  br label %loop_begin1651; CHECK-NEXT:  entry:1652; CHECK-NEXT:    br label %loop_begin1653 1654loop_begin:1655  %b = load i32, ptr %b.ptr1656  %v1 = load i1, ptr %ptr1657  br i1 %v1, label %loop_latch, label %inner_loop_ph1658; CHECK:       loop_begin:1659; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1660; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1661; CHECK-NEXT:    br i1 %[[V]], label %loop_latch, label %inner_loop_ph1662 1663inner_loop_ph:1664  %cond = load i1, ptr %cond.ptr1665  br label %inner_loop_begin1666; CHECK:       inner_loop_ph:1667; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1668; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]1669; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_loop_ph.split.us, label %inner_loop_ph.split1670 1671inner_loop_begin:1672  call void @sink1(i32 %b)1673  %a = load i32, ptr %a.ptr1674  br i1 %cond, label %loop_exit, label %inner_loop_a1675 1676inner_loop_a:1677  %v2 = load i1, ptr %ptr1678  br i1 %v2, label %inner_loop_exit, label %inner_loop_begin1679; The cloned path doesn't actually loop and is an exit from the outer loop as1680; well.1681;1682; CHECK:       inner_loop_ph.split.us:1683; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %inner_loop_ph ]1684; CHECK-NEXT:    br label %inner_loop_begin.us1685;1686; CHECK:       inner_loop_begin.us:1687; CHECK-NEXT:    call void @sink1(i32 %[[B_LCSSA]])1688; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1689; CHECK-NEXT:    br label %loop_exit.loopexit.split.us1690;1691; CHECK:       loop_exit.loopexit.split.us:1692; CHECK-NEXT:    %[[A_INNER_LCSSA_US:.*]] = phi i32 [ %[[A]], %inner_loop_begin.us ]1693; CHECK-NEXT:    br label %loop_exit.loopexit1694;1695; The original remains a loop losing the exit edge.1696;1697; CHECK:       inner_loop_ph.split:1698; CHECK-NEXT:    br label %inner_loop_begin1699;1700; CHECK:       inner_loop_begin:1701; CHECK-NEXT:    call void @sink1(i32 %[[B]])1702; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1703; CHECK-NEXT:    br label %inner_loop_a1704;1705; CHECK:       inner_loop_a:1706; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1707; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit, label %inner_loop_begin1708 1709inner_loop_exit:1710  %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ]1711  %v3 = load i1, ptr %ptr1712  br i1 %v3, label %loop_latch, label %loop_exit1713; CHECK:       inner_loop_exit:1714; CHECK-NEXT:    %[[A_INNER_LCSSA:.*]] = phi i32 [ %[[A]], %inner_loop_a ]1715; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1716; CHECK-NEXT:    br i1 %[[V]], label %loop_latch, label %loop_exit.loopexit11717 1718loop_latch:1719  br label %loop_begin1720; CHECK:       loop_latch:1721; CHECK-NEXT:    br label %loop_begin1722 1723loop_exit:1724  %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ]1725  ret i32 %a.lcssa1726; CHECK:       loop_exit.loopexit:1727; CHECK-NEXT:    br label %loop_exit1728;1729; CHECK:       loop_exit.loopexit1:1730; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_LCSSA]], %inner_loop_exit ]1731; CHECK-NEXT:    br label %loop_exit1732;1733; CHECK:       loop_exit:1734; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A_INNER_LCSSA_US]], %loop_exit.loopexit ], [ %[[A_LCSSA]], %loop_exit.loopexit1 ]1735; CHECK-NEXT:    ret i32 %[[A_PHI]]1736}1737 1738; Check that if the original inner loop after unswitching doesn't loop and1739; directly exits even an outer loop, we remove the original preheader from the1740; outer loop and add needed LCSSA phi nodes for the new exit block from the1741; outer loop.1742define i32 @test11b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1743; CHECK-LABEL: @test11b(1744entry:1745  br label %loop_begin1746; CHECK-NEXT:  entry:1747; CHECK-NEXT:    br label %loop_begin1748 1749loop_begin:1750  %b = load i32, ptr %b.ptr1751  %v1 = load i1, ptr %ptr1752  br i1 %v1, label %loop_latch, label %inner_loop_ph1753; CHECK:       loop_begin:1754; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1755; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1756; CHECK-NEXT:    br i1 %[[V]], label %loop_latch, label %inner_loop_ph1757 1758inner_loop_ph:1759  %cond = load i1, ptr %cond.ptr1760  br label %inner_loop_begin1761; CHECK:       inner_loop_ph:1762; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1763; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]1764; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_loop_ph.split.us, label %inner_loop_ph.split1765 1766inner_loop_begin:1767  call void @sink1(i32 %b)1768  %a = load i32, ptr %a.ptr1769  br i1 %cond, label %inner_loop_a, label %loop_exit1770 1771inner_loop_a:1772  %v2 = load i1, ptr %ptr1773  br i1 %v2, label %inner_loop_exit, label %inner_loop_begin1774; The cloned path continues to loop without the exit out of the entire nest.1775;1776; CHECK:       inner_loop_ph.split.us:1777; CHECK-NEXT:    br label %inner_loop_begin.us1778;1779; CHECK:       inner_loop_begin.us:1780; CHECK-NEXT:    call void @sink1(i32 %[[B]])1781; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1782; CHECK-NEXT:    br label %inner_loop_a.us1783;1784; CHECK:       inner_loop_a.us:1785; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1786; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_exit.split.us, label %inner_loop_begin.us1787;1788; CHECK:       inner_loop_exit.split.us:1789; CHECK-NEXT:    %[[A_INNER_LCSSA_US:.*]] = phi i32 [ %[[A]], %inner_loop_a.us ]1790; CHECK-NEXT:    br label %inner_loop_exit1791;1792; The original remains a loop losing the exit edge.1793;1794; CHECK:       inner_loop_ph.split:1795; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %inner_loop_ph ]1796; CHECK-NEXT:    br label %inner_loop_begin1797;1798; CHECK:       inner_loop_begin:1799; CHECK-NEXT:    call void @sink1(i32 %[[B_LCSSA]])1800; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1801; CHECK-NEXT:    br label %loop_exit.loopexit1802 1803inner_loop_exit:1804  %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ]1805  %v3 = load i1, ptr %ptr1806  br i1 %v3, label %loop_latch, label %loop_exit1807; CHECK:       inner_loop_exit:1808; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1809; CHECK-NEXT:    br i1 %[[V]], label %loop_latch, label %loop_exit.loopexit11810 1811loop_latch:1812  br label %loop_begin1813; CHECK:       loop_latch:1814; CHECK-NEXT:    br label %loop_begin1815 1816loop_exit:1817  %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ]1818  ret i32 %a.lcssa1819; CHECK:       loop_exit.loopexit:1820; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %inner_loop_begin ]1821; CHECK-NEXT:    br label %loop_exit1822;1823; CHECK:       loop_exit.loopexit1:1824; CHECK-NEXT:    %[[A_LCSSA_US:.*]] = phi i32 [ %[[A_INNER_LCSSA_US]], %inner_loop_exit ]1825; CHECK-NEXT:    br label %loop_exit1826;1827; CHECK:       loop_exit:1828; CHECK-NEXT:    %[[A_PHI:.*]] = phi i32 [ %[[A_LCSSA]], %loop_exit.loopexit ], [ %[[A_LCSSA_US]], %loop_exit.loopexit1 ]1829; CHECK-NEXT:    ret i32 %[[A_PHI]]1830}1831 1832; Like test11a, but checking that when the whole thing is wrapped in yet1833; another loop, we correctly attribute the cloned preheader to that outermost1834; loop rather than only handling the case where the preheader is not in any loop1835; at all.1836define i32 @test12a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1837; CHECK-LABEL: @test12a(1838entry:1839  br label %loop_begin1840; CHECK-NEXT:  entry:1841; CHECK-NEXT:    br label %loop_begin1842 1843loop_begin:1844  br label %inner_loop_begin1845; CHECK:       loop_begin:1846; CHECK-NEXT:    br label %inner_loop_begin1847 1848inner_loop_begin:1849  %b = load i32, ptr %b.ptr1850  %v1 = load i1, ptr %ptr1851  br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph1852; CHECK:       inner_loop_begin:1853; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1854; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1855; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_latch, label %inner_inner_loop_ph1856 1857inner_inner_loop_ph:1858  %cond = load i1, ptr %cond.ptr1859  br label %inner_inner_loop_begin1860; CHECK:       inner_inner_loop_ph:1861; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1862; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]1863; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split1864 1865inner_inner_loop_begin:1866  call void @sink1(i32 %b)1867  %a = load i32, ptr %a.ptr1868  br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_a1869 1870inner_inner_loop_a:1871  %v2 = load i1, ptr %ptr1872  br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin1873; The cloned path doesn't actually loop and is an exit from the outer loop as1874; well.1875;1876; CHECK:       inner_inner_loop_ph.split.us:1877; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %inner_inner_loop_ph ]1878; CHECK-NEXT:    br label %inner_inner_loop_begin.us1879;1880; CHECK:       inner_inner_loop_begin.us:1881; CHECK-NEXT:    call void @sink1(i32 %[[B_LCSSA]])1882; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1883; CHECK-NEXT:    br label %inner_loop_exit.loopexit.split.us1884;1885; CHECK:       inner_loop_exit.loopexit.split.us:1886; CHECK-NEXT:    %[[A_INNER_INNER_LCSSA_US:.*]] = phi i32 [ %[[A]], %inner_inner_loop_begin.us ]1887; CHECK-NEXT:    br label %inner_loop_exit.loopexit1888;1889; The original remains a loop losing the exit edge.1890;1891; CHECK:       inner_inner_loop_ph.split:1892; CHECK-NEXT:    br label %inner_inner_loop_begin1893;1894; CHECK:       inner_inner_loop_begin:1895; CHECK-NEXT:    call void @sink1(i32 %[[B]])1896; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1897; CHECK-NEXT:    br label %inner_inner_loop_a1898;1899; CHECK:       inner_inner_loop_a:1900; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1901; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_exit, label %inner_inner_loop_begin1902 1903inner_inner_loop_exit:1904  %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ]1905  %v3 = load i1, ptr %ptr1906  br i1 %v3, label %inner_loop_latch, label %inner_loop_exit1907; CHECK:       inner_inner_loop_exit:1908; CHECK-NEXT:    %[[A_INNER_INNER_LCSSA:.*]] = phi i32 [ %[[A]], %inner_inner_loop_a ]1909; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1910; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_latch, label %inner_loop_exit.loopexit11911 1912inner_loop_latch:1913  br label %inner_loop_begin1914; CHECK:       inner_loop_latch:1915; CHECK-NEXT:    br label %inner_loop_begin1916 1917inner_loop_exit:1918  %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ]1919  %v4 = load i1, ptr %ptr1920  br i1 %v4, label %loop_begin, label %loop_exit1921; CHECK:       inner_loop_exit.loopexit:1922; CHECK-NEXT:    br label %inner_loop_exit1923;1924; CHECK:       inner_loop_exit.loopexit1:1925; CHECK-NEXT:    %[[A_INNER_LCSSA:.*]] = phi i32 [ %[[A_INNER_INNER_LCSSA]], %inner_inner_loop_exit ]1926; CHECK-NEXT:    br label %inner_loop_exit1927;1928; CHECK:       inner_loop_exit:1929; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A_INNER_INNER_LCSSA_US]], %inner_loop_exit.loopexit ], [ %[[A_INNER_LCSSA]], %inner_loop_exit.loopexit1 ]1930; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1931; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit1932 1933loop_exit:1934  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]1935  ret i32 %a.lcssa1936; CHECK:       loop_exit:1937; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_loop_exit ]1938; CHECK-NEXT:    ret i32 %[[A_LCSSA]]1939}1940 1941; Like test11b, but checking that when the whole thing is wrapped in yet1942; another loop, we correctly sink the preheader to the outermost loop rather1943; than only handling the case where the preheader is completely removed from1944; a loop.1945define i32 @test12b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1946; CHECK-LABEL: @test12b(1947entry:1948  br label %loop_begin1949; CHECK-NEXT:  entry:1950; CHECK-NEXT:    br label %loop_begin1951 1952loop_begin:1953  br label %inner_loop_begin1954; CHECK:       loop_begin:1955; CHECK-NEXT:    br label %inner_loop_begin1956 1957inner_loop_begin:1958  %b = load i32, ptr %b.ptr1959  %v1 = load i1, ptr %ptr1960  br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph1961; CHECK:       inner_loop_begin:1962; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr1963; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1964; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_latch, label %inner_inner_loop_ph1965 1966inner_inner_loop_ph:1967  %cond = load i1, ptr %cond.ptr1968  br label %inner_inner_loop_begin1969; CHECK:       inner_inner_loop_ph:1970; CHECK-NEXT:    %[[COND:.*]] = load i1, ptr %cond.ptr1971; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %[[COND]]1972; CHECK-NEXT:    br i1 %[[FROZEN]], label %inner_inner_loop_ph.split.us, label %inner_inner_loop_ph.split1973 1974inner_inner_loop_begin:1975  call void @sink1(i32 %b)1976  %a = load i32, ptr %a.ptr1977  br i1 %cond, label %inner_inner_loop_a, label %inner_loop_exit1978 1979inner_inner_loop_a:1980  %v2 = load i1, ptr %ptr1981  br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin1982; The cloned path continues to loop without the exit out of the entire nest.1983;1984; CHECK:       inner_inner_loop_ph.split.us:1985; CHECK-NEXT:    br label %inner_inner_loop_begin.us1986;1987; CHECK:       inner_inner_loop_begin.us:1988; CHECK-NEXT:    call void @sink1(i32 %[[B]])1989; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr1990; CHECK-NEXT:    br label %inner_inner_loop_a.us1991;1992; CHECK:       inner_inner_loop_a.us:1993; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr1994; CHECK-NEXT:    br i1 %[[V]], label %inner_inner_loop_exit.split.us, label %inner_inner_loop_begin.us1995;1996; CHECK:       inner_inner_loop_exit.split.us:1997; CHECK-NEXT:    %[[A_INNER_INNER_LCSSA_US:.*]] = phi i32 [ %[[A]], %inner_inner_loop_a.us ]1998; CHECK-NEXT:    br label %inner_inner_loop_exit1999;2000; The original remains a loop losing the exit edge.2001;2002; CHECK:       inner_inner_loop_ph.split:2003; CHECK-NEXT:    %[[B_LCSSA:.*]] = phi i32 [ %[[B]], %inner_inner_loop_ph ]2004; CHECK-NEXT:    br label %inner_inner_loop_begin2005;2006; CHECK:       inner_inner_loop_begin:2007; CHECK-NEXT:    call void @sink1(i32 %[[B_LCSSA]])2008; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr2009; CHECK-NEXT:    br label %inner_loop_exit.loopexit2010 2011inner_inner_loop_exit:2012  %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ]2013  %v3 = load i1, ptr %ptr2014  br i1 %v3, label %inner_loop_latch, label %inner_loop_exit2015; CHECK:       inner_inner_loop_exit:2016; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2017; CHECK-NEXT:    br i1 %[[V]], label %inner_loop_latch, label %inner_loop_exit.loopexit12018 2019inner_loop_latch:2020  br label %inner_loop_begin2021; CHECK:       inner_loop_latch:2022; CHECK-NEXT:    br label %inner_loop_begin2023 2024inner_loop_exit:2025  %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ]2026  %v4 = load i1, ptr %ptr2027  br i1 %v4, label %loop_begin, label %loop_exit2028; CHECK:       inner_loop_exit.loopexit:2029; CHECK-NEXT:    %[[A_INNER_LCSSA:.*]] = phi i32 [ %[[A]], %inner_inner_loop_begin ]2030; CHECK-NEXT:    br label %inner_loop_exit2031;2032; CHECK:       inner_loop_exit.loopexit1:2033; CHECK-NEXT:    %[[A_INNER_LCSSA_US:.*]] = phi i32 [ %[[A_INNER_INNER_LCSSA_US]], %inner_inner_loop_exit ]2034; CHECK-NEXT:    br label %inner_loop_exit2035;2036; CHECK:       inner_loop_exit:2037; CHECK-NEXT:    %[[A_INNER_PHI:.*]] = phi i32 [ %[[A_INNER_LCSSA]], %inner_loop_exit.loopexit ], [ %[[A_INNER_LCSSA_US]], %inner_loop_exit.loopexit1 ]2038; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2039; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit2040 2041loop_exit:2042  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]2043  ret i32 %a.lcssa2044; CHECK:       loop_exit:2045; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A_INNER_PHI]], %inner_loop_exit ]2046; CHECK-NEXT:    ret i32 %[[A_LCSSA]]2047}2048 2049; Test where the cloned loop has an inner loop that has to be traversed to form2050; the cloned loop, and where this inner loop has multiple blocks, and where the2051; exiting block that connects the inner loop to the cloned loop is not the header2052; block. This ensures that we correctly handle interesting corner cases of2053; traversing back to the header when establishing the cloned loop.2054define i32 @test13a(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) {2055; CHECK-LABEL: @test13a(2056entry:2057  br label %loop_begin2058; CHECK-NEXT:  entry:2059; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %cond2060; CHECK-NEXT:    br i1 %[[FROZEN]], label %entry.split.us, label %entry.split2061 2062loop_begin:2063  %a = load i32, ptr %a.ptr2064  %v1 = load i1, ptr %ptr2065  br i1 %v1, label %loop_a, label %loop_b2066 2067loop_a:2068  %v2 = load i1, ptr %ptr2069  br i1 %v2, label %loop_exit, label %loop_latch2070 2071loop_b:2072  %b = load i32, ptr %b.ptr2073  br i1 %cond, label %loop_b_inner_ph, label %loop_exit2074 2075loop_b_inner_ph:2076  br label %loop_b_inner_header2077 2078loop_b_inner_header:2079  %v3 = load i1, ptr %ptr2080  br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body2081 2082loop_b_inner_body:2083  %v4 = load i1, ptr %ptr2084  br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit2085 2086loop_b_inner_latch:2087  br label %loop_b_inner_header2088 2089loop_b_inner_exit:2090  br label %loop_latch2091 2092loop_latch:2093  br label %loop_begin2094; The cloned loop contains an inner loop within it.2095;2096; CHECK:       entry.split.us:2097; CHECK-NEXT:    br label %loop_begin.us2098;2099; CHECK:       loop_begin.us:2100; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr2101; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2102; CHECK-NEXT:    br i1 %[[V]], label %loop_a.us, label %loop_b.us2103;2104; CHECK:       loop_b.us:2105; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr2106; CHECK-NEXT:    br label %loop_b_inner_ph.us2107;2108; CHECK:       loop_b_inner_ph.us:2109; CHECK-NEXT:    br label %loop_b_inner_header.us2110;2111; CHECK:       loop_b_inner_header.us:2112; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2113; CHECK-NEXT:    br i1 %[[V]], label %loop_b_inner_latch.us, label %loop_b_inner_body.us2114;2115; CHECK:       loop_b_inner_body.us:2116; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2117; CHECK-NEXT:    br i1 %[[V]], label %loop_b_inner_latch.us, label %loop_b_inner_exit.us2118;2119; CHECK:       loop_b_inner_exit.us:2120; CHECK-NEXT:    br label %loop_latch.us2121;2122; CHECK:       loop_b_inner_latch.us:2123; CHECK-NEXT:    br label %loop_b_inner_header.us2124;2125; CHECK:       loop_a.us:2126; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2127; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split.us, label %loop_latch.us2128;2129; CHECK:       loop_latch.us:2130; CHECK-NEXT:    br label %loop_begin.us2131;2132; CHECK:       loop_exit.split.us:2133; CHECK-NEXT:    %[[A_LCSSA_US:.*]] = phi i32 [ %[[A]], %loop_a.us ]2134; CHECK-NEXT:    br label %loop_exit2135;2136; And the original loop no longer contains an inner loop.2137;2138; CHECK:       entry.split:2139; CHECK-NEXT:    br label %loop_begin2140;2141; CHECK:       loop_begin:2142; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr2143; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2144; CHECK-NEXT:    br i1 %[[V]], label %loop_a, label %loop_b2145;2146; CHECK:       loop_a:2147; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2148; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split.loopexit, label %loop_latch2149;2150; CHECK:       loop_b:2151; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr2152; CHECK-NEXT:    br label %loop_exit.split2153;2154; CHECK:       loop_latch:2155; CHECK-NEXT:    br label %loop_begin2156 2157loop_exit:2158  %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ]2159  ret i32 %lcssa2160; CHECK:       loop_exit.split.loopexit:2161; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %loop_a ]2162; CHECK-NEXT:    br label %loop_exit.split2163;2164; CHECK:       loop_exit.split:2165; CHECK-NEXT:    %[[AB_PHI:.*]] = phi i32 [ %[[B]], %loop_b ], [ %[[A_LCSSA]], %loop_exit.split.loopexit ]2166; CHECK-NEXT:    br label %loop_exit2167;2168; CHECK:       loop_exit:2169; CHECK-NEXT:    %[[AB_PHI_US:.*]] = phi i32 [ %[[AB_PHI]], %loop_exit.split ], [ %[[A_LCSSA_US]], %loop_exit.split.us ]2170; CHECK-NEXT:    ret i32 %[[AB_PHI_US]]2171}2172 2173; Test where the original loop has an inner loop that has to be traversed to2174; rebuild the loop, and where this inner loop has multiple blocks, and where2175; the exiting block that connects the inner loop to the original loop is not2176; the header block. This ensures that we correctly handle interesting corner2177; cases of traversing back to the header when re-establishing the original loop2178; still exists after unswitching.2179define i32 @test13b(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) {2180; CHECK-LABEL: @test13b(2181entry:2182  br label %loop_begin2183; CHECK-NEXT:  entry:2184; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %cond2185; CHECK-NEXT:    br i1 %[[FROZEN]], label %entry.split.us, label %entry.split2186 2187loop_begin:2188  %a = load i32, ptr %a.ptr2189  %v1 = load i1, ptr %ptr2190  br i1 %v1, label %loop_a, label %loop_b2191 2192loop_a:2193  %v2 = load i1, ptr %ptr2194  br i1 %v2, label %loop_exit, label %loop_latch2195 2196loop_b:2197  %b = load i32, ptr %b.ptr2198  br i1 %cond, label %loop_exit, label %loop_b_inner_ph2199 2200loop_b_inner_ph:2201  br label %loop_b_inner_header2202 2203loop_b_inner_header:2204  %v3 = load i1, ptr %ptr2205  br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body2206 2207loop_b_inner_body:2208  %v4 = load i1, ptr %ptr2209  br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit2210 2211loop_b_inner_latch:2212  br label %loop_b_inner_header2213 2214loop_b_inner_exit:2215  br label %loop_latch2216 2217loop_latch:2218  br label %loop_begin2219; The cloned loop doesn't contain an inner loop.2220;2221; CHECK:       entry.split.us:2222; CHECK-NEXT:    br label %loop_begin.us2223;2224; CHECK:       loop_begin.us:2225; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr2226; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2227; CHECK-NEXT:    br i1 %[[V]], label %loop_a.us, label %loop_b.us2228;2229; CHECK:       loop_b.us:2230; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr2231; CHECK-NEXT:    br label %loop_exit.split.us2232;2233; CHECK:       loop_a.us:2234; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2235; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split.us.loopexit, label %loop_latch.us2236;2237; CHECK:       loop_latch.us:2238; CHECK-NEXT:    br label %loop_begin.us2239;2240; CHECK:       loop_exit.split.us.loopexit:2241; CHECK-NEXT:    %[[A_LCSSA_US:.*]] = phi i32 [ %[[A]], %loop_a.us ]2242; CHECK-NEXT:    br label %loop_exit.split.us2243;2244; CHECK:       loop_exit.split.us:2245; CHECK-NEXT:    %[[AB_PHI_US:.*]] = phi i32 [ %[[B]], %loop_b.us ], [ %[[A_LCSSA_US]], %loop_exit.split.us.loopexit ]2246; CHECK-NEXT:    br label %loop_exit2247;2248; But the original loop contains an inner loop that must be traversed.;2249;2250; CHECK:       entry.split:2251; CHECK-NEXT:    br label %loop_begin2252;2253; CHECK:       loop_begin:2254; CHECK-NEXT:    %[[A:.*]] = load i32, ptr %a.ptr2255; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2256; CHECK-NEXT:    br i1 %[[V]], label %loop_a, label %loop_b2257;2258; CHECK:       loop_a:2259; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2260; CHECK-NEXT:    br i1 %[[V]], label %loop_exit.split, label %loop_latch2261;2262; CHECK:       loop_b:2263; CHECK-NEXT:    %[[B:.*]] = load i32, ptr %b.ptr2264; CHECK-NEXT:    br label %loop_b_inner_ph2265;2266; CHECK:       loop_b_inner_ph:2267; CHECK-NEXT:    br label %loop_b_inner_header2268;2269; CHECK:       loop_b_inner_header:2270; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2271; CHECK-NEXT:    br i1 %[[V]], label %loop_b_inner_latch, label %loop_b_inner_body2272;2273; CHECK:       loop_b_inner_body:2274; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2275; CHECK-NEXT:    br i1 %[[V]], label %loop_b_inner_latch, label %loop_b_inner_exit2276;2277; CHECK:       loop_b_inner_latch:2278; CHECK-NEXT:    br label %loop_b_inner_header2279;2280; CHECK:       loop_b_inner_exit:2281; CHECK-NEXT:    br label %loop_latch2282;2283; CHECK:       loop_latch:2284; CHECK-NEXT:    br label %loop_begin2285 2286loop_exit:2287  %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ]2288  ret i32 %lcssa2289; CHECK:       loop_exit.split:2290; CHECK-NEXT:    %[[A_LCSSA:.*]] = phi i32 [ %[[A]], %loop_a ]2291; CHECK-NEXT:    br label %loop_exit2292;2293; CHECK:       loop_exit:2294; CHECK-NEXT:    %[[AB_PHI:.*]] = phi i32 [ %[[A_LCSSA]], %loop_exit.split ], [ %[[AB_PHI_US]], %loop_exit.split.us ]2295; CHECK-NEXT:    ret i32 %[[AB_PHI]]2296}2297 2298define i32 @test20(ptr %var, i32 %cond1, i32 %cond2) {2299; CHECK-LABEL: @test20(2300entry:2301  br label %loop_begin2302; CHECK-NEXT:  entry:2303; CHECK-NEXT:    switch i32 %cond2, label %[[ENTRY_SPLIT_EXIT:.*]] [2304; CHECK-NEXT:      i32 0, label %[[ENTRY_SPLIT_A:.*]]2305; CHECK-NEXT:      i32 1, label %[[ENTRY_SPLIT_A]]2306; CHECK-NEXT:      i32 13, label %[[ENTRY_SPLIT_B:.*]]2307; CHECK-NEXT:      i32 2, label %[[ENTRY_SPLIT_A]]2308; CHECK-NEXT:      i32 42, label %[[ENTRY_SPLIT_C:.*]]2309; CHECK-NEXT:    ]2310 2311loop_begin:2312  %var_val = load i32, ptr %var2313  switch i32 %cond2, label %loop_exit [2314    i32 0, label %loop_a2315    i32 1, label %loop_a2316    i32 13, label %loop_b2317    i32 2, label %loop_a2318    i32 42, label %loop_c2319  ]2320 2321loop_a:2322  call i32 @a()2323  br label %loop_latch2324; Unswitched 'a' loop.2325;2326; CHECK:       [[ENTRY_SPLIT_A]]:2327; CHECK-NEXT:    br label %[[LOOP_BEGIN_A:.*]]2328;2329; CHECK:       [[LOOP_BEGIN_A]]:2330; CHECK-NEXT:    %{{.*}} = load i32, ptr %var2331; CHECK-NEXT:    br label %[[LOOP_A:.*]]2332;2333; CHECK:       [[LOOP_A]]:2334; CHECK-NEXT:    call i32 @a()2335; CHECK-NEXT:    br label %[[LOOP_LATCH_A:.*]]2336;2337; CHECK:       [[LOOP_LATCH_A]]:2338; CHECK:         br label %[[LOOP_BEGIN_A]]2339 2340loop_b:2341  call i32 @b()2342  br label %loop_latch2343; Unswitched 'b' loop.2344;2345; CHECK:       [[ENTRY_SPLIT_B]]:2346; CHECK-NEXT:    br label %[[LOOP_BEGIN_B:.*]]2347;2348; CHECK:       [[LOOP_BEGIN_B]]:2349; CHECK-NEXT:    %{{.*}} = load i32, ptr %var2350; CHECK-NEXT:    br label %[[LOOP_B:.*]]2351;2352; CHECK:       [[LOOP_B]]:2353; CHECK-NEXT:    call i32 @b()2354; CHECK-NEXT:    br label %[[LOOP_LATCH_B:.*]]2355;2356; CHECK:       [[LOOP_LATCH_B]]:2357; CHECK:         br label %[[LOOP_BEGIN_B]]2358 2359loop_c:2360  call i32 @c() noreturn nounwind2361  br label %loop_latch2362; Unswitched 'c' loop.2363;2364; CHECK:       [[ENTRY_SPLIT_C]]:2365; CHECK-NEXT:    br label %[[LOOP_BEGIN_C:.*]]2366;2367; CHECK:       [[LOOP_BEGIN_C]]:2368; CHECK-NEXT:    %{{.*}} = load i32, ptr %var2369; CHECK-NEXT:    br label %[[LOOP_C:.*]]2370;2371; CHECK:       [[LOOP_C]]:2372; CHECK-NEXT:    call i32 @c()2373; CHECK-NEXT:    br label %[[LOOP_LATCH_C:.*]]2374;2375; CHECK:       [[LOOP_LATCH_C]]:2376; CHECK:         br label %[[LOOP_BEGIN_C]]2377 2378loop_latch:2379  br label %loop_begin2380 2381loop_exit:2382  %lcssa = phi i32 [ %var_val, %loop_begin ]2383  ret i32 %lcssa2384; Unswitched exit edge (no longer a loop).2385;2386; CHECK:       [[ENTRY_SPLIT_EXIT]]:2387; CHECK-NEXT:    br label %loop_begin2388;2389; CHECK:       loop_begin:2390; CHECK-NEXT:    %[[V:.*]] = load i32, ptr %var2391; CHECK-NEXT:    br label %loop_exit2392;2393; CHECK:       loop_exit:2394; CHECK-NEXT:    %[[LCSSA:.*]] = phi i32 [ %[[V]], %loop_begin ]2395; CHECK-NEXT:    ret i32 %[[LCSSA]]2396}2397 2398; Negative test: we do not switch when the loop contains unstructured control2399; flows as it would significantly complicate the process as novel loops might2400; be formed, etc.2401define void @test_no_unswitch_unstructured_cfg(ptr %ptr, i1 %cond) {2402; CHECK-LABEL: @test_no_unswitch_unstructured_cfg(2403entry:2404  br label %loop_begin2405 2406loop_begin:2407  br i1 %cond, label %loop_left, label %loop_right2408 2409loop_left:2410  %v1 = load i1, ptr %ptr2411  br i1 %v1, label %loop_right, label %loop_merge2412 2413loop_right:2414  %v2 = load i1, ptr %ptr2415  br i1 %v2, label %loop_left, label %loop_merge2416 2417loop_merge:2418  %v3 = load i1, ptr %ptr2419  br i1 %v3, label %loop_latch, label %loop_exit2420 2421loop_latch:2422  br label %loop_begin2423 2424loop_exit:2425  ret void2426}2427 2428; A test reduced out of 403.gcc with interesting nested loops that trigger2429; multiple unswitches. A key component of this test is that there are multiple2430; paths to reach an inner loop after unswitching, and one of them is via the2431; predecessors of the unswitched loop header. That can allow us to find the loop2432; through multiple different paths.2433define void @test21(i1 %a, i1 %b) {2434; CHECK-LABEL: @test21(2435bb:2436  br label %bb32437; CHECK-NOT:     br i1 %a2438;2439; CHECK:         %[[FROZEN:.+]] = freeze i1 %a2440; CHECK-NEXT:    br i1 %[[FROZEN]], label %[[BB_SPLIT_US:.*]], label %[[BB_SPLIT:.*]]2441;2442; CHECK-NOT:     br i1 %a2443; CHECK-NOT:     br i1 %b2444;2445; CHECK:       [[BB_SPLIT]]:2446; CHECK:         br i1 %b2447;2448; CHECK-NOT:     br i1 %a2449; CHECK-NOT:     br i1 %b2450 2451bb3:2452  %tmp1.0 = phi i32 [ 0, %bb ], [ %tmp1.3, %bb23 ]2453  br label %bb72454 2455bb7:2456  %tmp.0 = phi i1 [ true, %bb3 ], [ false, %bb19 ]2457  %tmp1.1 = phi i32 [ %tmp1.0, %bb3 ], [ %tmp1.2.lcssa, %bb19 ]2458  br i1 %tmp.0, label %bb11.preheader, label %bb232459 2460bb11.preheader:2461  br i1 %a, label %bb19, label %bb14.lr.ph2462 2463bb14.lr.ph:2464  br label %bb142465 2466bb14:2467  %tmp2.02 = phi i32 [ 0, %bb14.lr.ph ], [ 1, %bb14 ]2468  br i1 %b, label %bb11.bb19_crit_edge, label %bb142469 2470bb11.bb19_crit_edge:2471  %split = phi i32 [ %tmp2.02, %bb14 ]2472  br label %bb192473 2474bb19:2475  %tmp1.2.lcssa = phi i32 [ %split, %bb11.bb19_crit_edge ], [ %tmp1.1, %bb11.preheader ]2476  %tmp21 = icmp eq i32 %tmp1.2.lcssa, 02477  br i1 %tmp21, label %bb23, label %bb72478 2479bb23:2480  %tmp1.3 = phi i32 [ %tmp1.2.lcssa, %bb19 ], [ %tmp1.1, %bb7 ]2481  br label %bb32482}2483 2484; A test reduced out of 400.perlbench that when unswitching the `%stop`2485; condition clones a loop nest outside of a containing loop. This excercises a2486; different cloning path from our other test cases and in turn verifying the2487; resulting structure can catch any failures to correctly clone these nested2488; loops.2489declare void @f()2490declare void @g()2491declare i32 @h(i32 %arg)2492define void @test22(i32 %arg) {2493; CHECK-LABEL: define void @test22(2494entry:2495  br label %loop1.header2496 2497loop1.header:2498  %stop = phi i1 [ true, %loop1.latch ], [ false, %entry ]2499  %i = phi i32 [ %i.lcssa, %loop1.latch ], [ %arg, %entry ]2500; CHECK:         %[[I:.*]] = phi i32 [ %{{.*}}, %loop1.latch ], [ %arg, %entry ]2501  br i1 %stop, label %loop1.exit, label %loop1.body.loop2.ph2502; CHECK:         br i1 %stop, label %loop1.exit, label %loop1.body.loop2.ph2503 2504loop1.body.loop2.ph:2505  br label %loop2.header2506; Just check that the we unswitched the key condition and that leads to the2507; inner loop header.2508;2509; CHECK:       loop1.body.loop2.ph:2510; CHECK-NEXT:    br i1 %stop, label %[[SPLIT_US:.*]], label %[[SPLIT:.*]]2511;2512; CHECK:       [[SPLIT_US]]:2513; CHECK-NEXT:    br label %[[LOOP2_HEADER_US:.*]]2514;2515; CHECK:       [[LOOP2_HEADER_US]]:2516; CHECK-NEXT:    %{{.*}} = phi i32 [ %[[I]], %[[SPLIT_US]] ]2517;2518; CHECK:       [[SPLIT]]:2519; CHECK-NEXT:    br label %[[LOOP2_HEADER:.*]]2520;2521; CHECK:       [[LOOP2_HEADER]]:2522; CHECK-NEXT:    %{{.*}} = phi i32 [ %[[I]], %[[SPLIT]] ]2523 2524loop2.header:2525  %i.inner = phi i32 [ %i, %loop1.body.loop2.ph ], [ %i.next, %loop2.latch ]2526  br label %loop3.header2527 2528loop3.header:2529  %sw = call i32 @h(i32 %i.inner)2530  switch i32 %sw, label %loop3.exit [2531    i32 32, label %loop3.header2532    i32 59, label %loop2.latch2533    i32 36, label %loop1.latch2534  ]2535 2536loop2.latch:2537  %i.next = add i32 %i.inner, 12538  br i1 %stop, label %loop2.exit, label %loop2.header2539 2540loop1.latch:2541  %i.lcssa = phi i32 [ %i.inner, %loop3.header ]2542  br label %loop1.header2543 2544loop3.exit:2545  call void @f()2546  ret void2547 2548loop2.exit:2549  call void @g()2550  ret void2551 2552loop1.exit:2553  call void @g()2554  ret void2555}2556 2557; Test that when we are unswitching and need to rebuild the loop block set we2558; correctly skip past inner loops. We want to use the inner loop to efficiently2559; skip whole subregions of the outer loop blocks but just because the header of2560; the outer loop is also the preheader of an inner loop shouldn't confuse this2561; walk.2562define void @test23(i1 %arg, ptr %ptr) {2563; CHECK-LABEL: define void @test23(2564entry:2565  br label %outer.header2566; CHECK:       entry:2567; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %arg2568; CHECK-NEXT:    br i1 %[[FROZEN]],2569;2570; Just verify that we unswitched the correct bits. We should call `@f` twice in2571; one unswitch and `@f` and then `@g` in the other.2572; CHECK:         call void2573; CHECK-SAME:              @f2574; CHECK:         call void2575; CHECK-SAME:              @f2576;2577; CHECK:         call void2578; CHECK-SAME:              @f2579; CHECK:         call void2580; CHECK-SAME:              @g2581 2582outer.header:2583  br label %inner.header2584 2585inner.header:2586  call void @f()2587  br label %inner.latch2588 2589inner.latch:2590  %inner.cond = load i1, ptr %ptr2591  br i1 %inner.cond, label %inner.header, label %outer.body2592 2593outer.body:2594  br i1 %arg, label %outer.body.left, label %outer.body.right2595 2596outer.body.left:2597  call void @f()2598  br label %outer.latch2599 2600outer.body.right:2601  call void @g()2602  br label %outer.latch2603 2604outer.latch:2605  %outer.cond = load i1, ptr %ptr2606  br i1 %outer.cond, label %outer.header, label %exit2607 2608exit:2609  ret void2610}2611 2612; Non-trivial loop unswitching where there are two invariant conditions, but the2613; second one is only in the cloned copy of the loop after unswitching.2614define i32 @test24(ptr %ptr, i1 %cond1, i1 %cond2) {2615; CHECK-LABEL: @test24(2616entry:2617  br label %loop_begin2618; CHECK-NEXT:  entry:2619; CHECK-NEXT:    br i1 %cond1, label %entry.split.us, label %entry.split2620 2621loop_begin:2622  br i1 %cond1, label %loop_a, label %loop_b2623 2624loop_a:2625  br i1 %cond2, label %loop_a_a, label %loop_a_c2626; The second unswitched condition.2627;2628; CHECK:       entry.split.us:2629; CHECK-NEXT:    br i1 %cond2, label %entry.split.us.split.us, label %entry.split.us.split2630 2631loop_a_a:2632  call i32 @a()2633  br label %latch2634; The 'loop_a_a' unswitched loop.2635;2636; CHECK:       entry.split.us.split.us:2637; CHECK-NEXT:    br label %loop_begin.us.us2638;2639; CHECK:       loop_begin.us.us:2640; CHECK-NEXT:    br label %loop_a.us.us2641;2642; CHECK:       loop_a.us.us:2643; CHECK-NEXT:    br label %loop_a_a.us.us2644;2645; CHECK:       loop_a_a.us.us:2646; CHECK-NEXT:    call i32 @a()2647; CHECK-NEXT:    br label %latch.us.us2648;2649; CHECK:       latch.us.us:2650; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2651; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.us.us, label %loop_exit.split.us.split.us2652;2653; CHECK:       loop_exit.split.us.split.us:2654; CHECK-NEXT:    br label %loop_exit.split2655 2656loop_a_c:2657  call i32 @c()2658  br label %latch2659; The 'loop_a_c' unswitched loop.2660;2661; CHECK:       entry.split.us.split:2662; CHECK-NEXT:    br label %loop_begin.us2663;2664; CHECK:       loop_begin.us:2665; CHECK-NEXT:    br label %loop_a.us2666;2667; CHECK:       loop_a.us:2668; CHECK-NEXT:    br label %loop_a_c.us2669;2670; CHECK:       loop_a_c.us:2671; CHECK-NEXT:    call i32 @c()2672; CHECK-NEXT:    br label %latch2673;2674; CHECK:       latch.us:2675; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2676; CHECK-NEXT:    br i1 %[[V]], label %loop_begin.us, label %loop_exit.split.us.split2677;2678; CHECK:       loop_exit.split.us.split:2679; CHECK-NEXT:    br label %loop_exit.split2680 2681loop_b:2682  call i32 @b()2683  br label %latch2684; The 'loop_b' unswitched loop.2685;2686; CHECK:       entry.split:2687; CHECK-NEXT:    br label %loop_begin2688;2689; CHECK:       loop_begin:2690; CHECK-NEXT:    br label %loop_b2691;2692; CHECK:       loop_b:2693; CHECK-NEXT:    call i32 @b()2694; CHECK-NEXT:    br label %latch2695;2696; CHECK:       latch:2697; CHECK-NEXT:    %[[V:.*]] = load i1, ptr %ptr2698; CHECK-NEXT:    br i1 %[[V]], label %loop_begin, label %loop_exit.split2699;2700; CHECK:       loop_exit.split:2701; CHECK-NEXT:    br label %loop_exit2702 2703latch:2704  %v = load i1, ptr %ptr2705  br i1 %v, label %loop_begin, label %loop_exit2706 2707loop_exit:2708  ret i32 02709; CHECK:       loop_exit:2710; CHECK-NEXT:    ret2711}2712 2713; Non-trivial partial loop unswitching of an invariant input to an 'or'.2714define i32 @test25(ptr %ptr, i1 %cond) {2715; CHECK-LABEL: @test25(2716entry:2717  br label %loop_begin2718; CHECK-NEXT:  entry:2719; CHECK-NEXT:    [[FROZEN:%.+]] = freeze i1 %cond2720; CHECK-NEXT:    br i1 [[FROZEN]], label %entry.split.us, label %entry.split2721 2722loop_begin:2723  %v1 = load i1, ptr %ptr2724  %cond_or = or i1 %v1, %cond2725  br i1 %cond_or, label %loop_a, label %loop_b2726 2727loop_a:2728  call i32 @a()2729  br label %latch2730; The 'loop_a' unswitched loop.2731;2732; CHECK:       entry.split.us:2733; CHECK-NEXT:    br label %loop_begin.us2734;2735; CHECK:       loop_begin.us:2736; CHECK-NEXT:    br label %loop_a.us2737;2738; CHECK:       loop_a.us:2739; CHECK-NEXT:    call i32 @a()2740; CHECK-NEXT:    br label %latch.us2741;2742; CHECK:       latch.us:2743; CHECK-NEXT:    %[[V2_US:.*]] = load i1, ptr %ptr2744; CHECK-NEXT:    br i1 %[[V2_US]], label %loop_begin.us, label %loop_exit.split.us2745;2746; CHECK:       loop_exit.split.us:2747; CHECK-NEXT:    br label %loop_exit2748 2749loop_b:2750  call i32 @b()2751  br label %latch2752; The original loop.2753;2754; CHECK:       entry.split:2755; CHECK-NEXT:    br label %loop_begin2756;2757; CHECK:       loop_begin:2758; CHECK-NEXT:    %[[V1:.*]] = load i1, ptr %ptr2759; CHECK-NEXT:    %[[OR:.*]] = or i1 %[[V1]], false2760; CHECK-NEXT:    br i1 %[[OR]], label %loop_a, label %loop_b2761;2762; CHECK:       loop_a:2763; CHECK-NEXT:    call i32 @a()2764; CHECK-NEXT:    br label %latch2765;2766; CHECK:       loop_b:2767; CHECK-NEXT:    call i32 @b()2768; CHECK-NEXT:    br label %latch2769 2770latch:2771  %v2 = load i1, ptr %ptr2772  br i1 %v2, label %loop_begin, label %loop_exit2773; CHECK:       latch:2774; CHECK-NEXT:    %[[V2:.*]] = load i1, ptr %ptr2775; CHECK-NEXT:    br i1 %[[V2]], label %loop_begin, label %loop_exit.split2776 2777loop_exit:2778  ret i32 02779; CHECK:       loop_exit.split:2780; CHECK-NEXT:    br label %loop_exit2781;2782; CHECK:       loop_exit:2783; CHECK-NEXT:    ret2784}2785 2786; Non-trivial partial loop unswitching of multiple invariant inputs to an `and`2787; chain.2788define i32 @test26(ptr %ptr1, ptr %ptr2, ptr %ptr3, i1 %cond1, i1 %cond2, i1 %cond3) {2789; CHECK-LABEL: @test26(2790entry:2791  br label %loop_begin2792; CHECK-NEXT:  entry:2793; CHECK-NEXT:    [[C3_FR:%.+]] = freeze i1 %cond32794; CHECK-NEXT:    [[C1_FR:%.+]] = freeze i1 %cond12795; CHECK-NEXT:    %[[INV_AND:.*]] = and i1 [[C3_FR]], [[C1_FR]]2796; CHECK-NEXT:    br i1 %[[INV_AND]], label %entry.split, label %entry.split.us2797 2798loop_begin:2799  %v1 = load i1, ptr %ptr12800  %v2 = load i1, ptr %ptr22801  %cond_and1 = and i1 %v1, %cond12802  %cond_or1 = or i1 %v2, %cond22803  %cond_and2 = and i1 %cond_and1, %cond_or12804  %cond_and3 = and i1 %cond_and2, %cond32805  br i1 %cond_and3, label %loop_a, label %loop_b2806; The 'loop_b' unswitched loop.2807;2808; CHECK:       entry.split.us:2809; CHECK-NEXT:    br label %loop_begin.us2810;2811; CHECK:       loop_begin.us:2812; CHECK-NEXT:    br label %loop_b.us2813;2814; CHECK:       loop_b.us:2815; CHECK-NEXT:    call i32 @b()2816; CHECK-NEXT:    br label %latch.us2817;2818; CHECK:       latch.us:2819; CHECK-NEXT:    %[[V3_US:.*]] = load i1, ptr %ptr32820; CHECK-NEXT:    br i1 %[[V3_US]], label %loop_begin.us, label %loop_exit.split.us2821;2822; CHECK:       loop_exit.split.us:2823; CHECK-NEXT:    br label %loop_exit2824 2825; The original loop.2826;2827; CHECK:       entry.split:2828; CHECK-NEXT:    br label %loop_begin2829;2830; CHECK:       loop_begin:2831; CHECK-NEXT:    %[[V1:.*]] = load i1, ptr %ptr12832; CHECK-NEXT:    %[[V2:.*]] = load i1, ptr %ptr22833; CHECK-NEXT:    %[[AND1:.*]] = and i1 %[[V1]], true2834; CHECK-NEXT:    %[[OR1:.*]] = or i1 %[[V2]], %cond22835; CHECK-NEXT:    %[[AND2:.*]] = and i1 %[[AND1]], %[[OR1]]2836; CHECK-NEXT:    %[[AND3:.*]] = and i1 %[[AND2]], true2837; CHECK-NEXT:    br i1 %[[AND3]], label %loop_a, label %loop_b2838 2839loop_a:2840  call i32 @a()2841  br label %latch2842; CHECK:       loop_a:2843; CHECK-NEXT:    call i32 @a()2844; CHECK-NEXT:    br label %latch2845 2846loop_b:2847  call i32 @b()2848  br label %latch2849; CHECK:       loop_b:2850; CHECK-NEXT:    call i32 @b()2851; CHECK-NEXT:    br label %latch2852 2853latch:2854  %v3 = load i1, ptr %ptr32855  br i1 %v3, label %loop_begin, label %loop_exit2856; CHECK:       latch:2857; CHECK-NEXT:    %[[V3:.*]] = load i1, ptr %ptr32858; CHECK-NEXT:    br i1 %[[V3]], label %loop_begin, label %loop_exit.split2859 2860loop_exit:2861  ret i32 02862; CHECK:       loop_exit.split:2863; CHECK-NEXT:    br label %loop_exit2864;2865; CHECK:       loop_exit:2866; CHECK-NEXT:    ret2867}2868 2869; Non-trivial partial loop unswitching of multiple invariant inputs to an `or`2870; chain. Basically an inverted version of corresponding `and` test (test26).2871define i32 @test27(ptr %ptr1, ptr %ptr2, ptr %ptr3, i1 %cond1, i1 %cond2, i1 %cond3) {2872; CHECK-LABEL: @test27(2873entry:2874  br label %loop_begin2875; CHECK-NEXT:  entry:2876; CHECK-NEXT:    [[C3_FR:%.+]] = freeze i1 %cond32877; CHECK-NEXT:    [[C1_FR:%.+]] = freeze i1 %cond12878; CHECK-NEXT:    %[[INV_OR:.*]] = or i1 [[C3_FR]], [[C1_FR]]2879; CHECK-NEXT:    br i1 %[[INV_OR]], label %entry.split.us, label %entry.split2880 2881loop_begin:2882  %v1 = load i1, ptr %ptr12883  %v2 = load i1, ptr %ptr22884  %cond_or1 = or i1 %v1, %cond12885  %cond_and1 = and i1 %v2, %cond22886  %cond_or2 = or i1 %cond_or1, %cond_and12887  %cond_or3 = or i1 %cond_or2, %cond32888  br i1 %cond_or3, label %loop_b, label %loop_a2889; The 'loop_b' unswitched loop.2890;2891; CHECK:       entry.split.us:2892; CHECK-NEXT:    br label %loop_begin.us2893;2894; CHECK:       loop_begin.us:2895; CHECK-NEXT:    br label %loop_b.us2896;2897; CHECK:       loop_b.us:2898; CHECK-NEXT:    call i32 @b()2899; CHECK-NEXT:    br label %latch.us2900;2901; CHECK:       latch.us:2902; CHECK-NEXT:    %[[V3_US:.*]] = load i1, ptr %ptr32903; CHECK-NEXT:    br i1 %[[V3_US]], label %loop_begin.us, label %loop_exit.split.us2904;2905; CHECK:       loop_exit.split.us:2906; CHECK-NEXT:    br label %loop_exit2907 2908; The original loop.2909;2910; CHECK:       entry.split:2911; CHECK-NEXT:    br label %loop_begin2912;2913; CHECK:       loop_begin:2914; CHECK-NEXT:    %[[V1:.*]] = load i1, ptr %ptr12915; CHECK-NEXT:    %[[V2:.*]] = load i1, ptr %ptr22916; CHECK-NEXT:    %[[OR1:.*]] = or i1 %[[V1]], false2917; CHECK-NEXT:    %[[AND1:.*]] = and i1 %[[V2]], %cond22918; CHECK-NEXT:    %[[OR2:.*]] = or i1 %[[OR1]], %[[AND1]]2919; CHECK-NEXT:    %[[OR3:.*]] = or i1 %[[OR2]], false2920; CHECK-NEXT:    br i1 %[[OR3]], label %loop_b, label %loop_a2921 2922loop_a:2923  call i32 @a()2924  br label %latch2925; CHECK:       loop_a:2926; CHECK-NEXT:    call i32 @a()2927; CHECK-NEXT:    br label %latch2928 2929loop_b:2930  call i32 @b()2931  br label %latch2932; CHECK:       loop_b:2933; CHECK-NEXT:    call i32 @b()2934; CHECK-NEXT:    br label %latch2935 2936latch:2937  %v3 = load i1, ptr %ptr32938  br i1 %v3, label %loop_begin, label %loop_exit2939; CHECK:       latch:2940; CHECK-NEXT:    %[[V3:.*]] = load i1, ptr %ptr32941; CHECK-NEXT:    br i1 %[[V3]], label %loop_begin, label %loop_exit.split2942 2943loop_exit:2944  ret i32 02945; CHECK:       loop_exit.split:2946; CHECK-NEXT:    br label %loop_exit2947;2948; CHECK:       loop_exit:2949; CHECK-NEXT:    ret2950}2951 2952; Non-trivial unswitching of a switch.2953define i32 @test28(ptr %ptr, i32 %cond) {2954; CHECK-LABEL: @test28(2955entry:2956  br label %loop_begin2957; CHECK-NEXT:  entry:2958; CHECK-NEXT:    switch i32 %cond, label %[[ENTRY_SPLIT_LATCH:.*]] [2959; CHECK-NEXT:      i32 0, label %[[ENTRY_SPLIT_A:.*]]2960; CHECK-NEXT:      i32 1, label %[[ENTRY_SPLIT_B:.*]]2961; CHECK-NEXT:      i32 2, label %[[ENTRY_SPLIT_C:.*]]2962; CHECK-NEXT:    ]2963 2964loop_begin:2965  switch i32 %cond, label %latch [2966    i32 0, label %loop_a2967    i32 1, label %loop_b2968    i32 2, label %loop_c2969  ]2970 2971loop_a:2972  call i32 @a()2973  br label %latch2974; Unswitched 'a' loop.2975;2976; CHECK:       [[ENTRY_SPLIT_A]]:2977; CHECK-NEXT:    br label %[[LOOP_BEGIN_A:.*]]2978;2979; CHECK:       [[LOOP_BEGIN_A]]:2980; CHECK-NEXT:    br label %[[LOOP_A:.*]]2981;2982; CHECK:       [[LOOP_A]]:2983; CHECK-NEXT:    call i32 @a()2984; CHECK-NEXT:    br label %[[LOOP_LATCH_A:.*]]2985;2986; CHECK:       [[LOOP_LATCH_A]]:2987; CHECK-NEXT:    %[[V_A:.*]] = load i1, ptr %ptr2988; CHECK:         br i1 %[[V_A]], label %[[LOOP_BEGIN_A]], label %[[LOOP_EXIT_A:.*]]2989;2990; CHECK:       [[LOOP_EXIT_A]]:2991; CHECK-NEXT:    br label %loop_exit2992 2993loop_b:2994  call i32 @b()2995  br label %latch2996; Unswitched 'b' loop.2997;2998; CHECK:       [[ENTRY_SPLIT_B]]:2999; CHECK-NEXT:    br label %[[LOOP_BEGIN_B:.*]]3000;3001; CHECK:       [[LOOP_BEGIN_B]]:3002; CHECK-NEXT:    br label %[[LOOP_B:.*]]3003;3004; CHECK:       [[LOOP_B]]:3005; CHECK-NEXT:    call i32 @b()3006; CHECK-NEXT:    br label %[[LOOP_LATCH_B:.*]]3007;3008; CHECK:       [[LOOP_LATCH_B]]:3009; CHECK-NEXT:    %[[V_B:.*]] = load i1, ptr %ptr3010; CHECK:         br i1 %[[V_B]], label %[[LOOP_BEGIN_B]], label %[[LOOP_EXIT_B:.*]]3011;3012; CHECK:       [[LOOP_EXIT_B]]:3013; CHECK-NEXT:    br label %loop_exit3014 3015loop_c:3016  call i32 @c()3017  br label %latch3018; Unswitched 'c' loop.3019;3020; CHECK:       [[ENTRY_SPLIT_C]]:3021; CHECK-NEXT:    br label %[[LOOP_BEGIN_C:.*]]3022;3023; CHECK:       [[LOOP_BEGIN_C]]:3024; CHECK-NEXT:    br label %[[LOOP_C:.*]]3025;3026; CHECK:       [[LOOP_C]]:3027; CHECK-NEXT:    call i32 @c()3028; CHECK-NEXT:    br label %[[LOOP_LATCH_C:.*]]3029;3030; CHECK:       [[LOOP_LATCH_C]]:3031; CHECK-NEXT:    %[[V_C:.*]] = load i1, ptr %ptr3032; CHECK:         br i1 %[[V_C]], label %[[LOOP_BEGIN_C]], label %[[LOOP_EXIT_C:.*]]3033;3034; CHECK:       [[LOOP_EXIT_C]]:3035; CHECK-NEXT:    br label %loop_exit3036 3037latch:3038  %v = load i1, ptr %ptr3039  br i1 %v, label %loop_begin, label %loop_exit3040; Unswitched the 'latch' only loop.3041;3042; CHECK:       [[ENTRY_SPLIT_LATCH]]:3043; CHECK-NEXT:    br label %[[LOOP_BEGIN_LATCH:.*]]3044;3045; CHECK:       [[LOOP_BEGIN_LATCH]]:3046; CHECK-NEXT:    br label %[[LOOP_LATCH_LATCH:.*]]3047;3048; CHECK:       [[LOOP_LATCH_LATCH]]:3049; CHECK-NEXT:    %[[V_LATCH:.*]] = load i1, ptr %ptr3050; CHECK:         br i1 %[[V_LATCH]], label %[[LOOP_BEGIN_LATCH]], label %[[LOOP_EXIT_LATCH:.*]]3051;3052; CHECK:       [[LOOP_EXIT_LATCH]]:3053; CHECK-NEXT:    br label %loop_exit3054 3055loop_exit:3056  ret i32 03057; CHECK:       loop_exit:3058; CHECK-NEXT:    ret i32 03059}3060 3061; A test case designed to exercise unusual properties of switches: they3062; can introduce multiple edges to successors. These need lots of special case3063; handling as they get collapsed in many cases (domtree, the unswitch itself)3064; but not in all cases (the PHI node operands).3065define i32 @test29(i32 %arg) {3066; CHECK-LABEL: @test29(3067entry:3068  br label %header3069; CHECK-NEXT:  entry:3070; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i32 %arg3071; CHECK-NEXT:    switch i32 %[[FROZEN]], label %[[ENTRY_SPLIT_C:.*]] [3072; CHECK-NEXT:      i32 0, label %[[ENTRY_SPLIT_A:.*]]3073; CHECK-NEXT:      i32 1, label %[[ENTRY_SPLIT_A]]3074; CHECK-NEXT:      i32 2, label %[[ENTRY_SPLIT_B:.*]]3075; CHECK-NEXT:      i32 3, label %[[ENTRY_SPLIT_C]]3076; CHECK-NEXT:    ]3077 3078header:3079  %tmp = call i32 @d()3080  %cmp1 = icmp eq i32 %tmp, 03081  ; We set up a chain through all the successors of the switch that doesn't3082  ; involve the switch so that we can have interesting PHI nodes in them.3083  br i1 %cmp1, label %body.a, label %dispatch3084 3085dispatch:3086  ; Switch with multiple successors. We arrange the last successor to be the3087  ; default to make the test case easier to read. This has a duplicate edge3088  ; both to the default destination (which is completely superfluous but3089  ; technically valid IR) and to a regular successor.3090  switch i32 %arg, label %body.c [3091    i32 0, label %body.a3092    i32 1, label %body.a3093    i32 2, label %body.b3094    i32 3, label %body.c3095  ]3096 3097body.a:3098  %tmp.a.phi = phi i32 [ 0, %header ], [ %tmp, %dispatch ], [ %tmp, %dispatch ]3099  %tmp.a = call i32 @a()3100  %tmp.a.sum = add i32 %tmp.a.phi, %tmp.a3101  br label %body.b3102; Unswitched 'a' loop.3103;3104; CHECK:       [[ENTRY_SPLIT_A]]:3105; CHECK-NEXT:    br label %[[HEADER_A:.*]]3106;3107; CHECK:       [[HEADER_A]]:3108; CHECK-NEXT:    %[[TMP_A:.*]] = call i32 @d()3109; CHECK-NEXT:    %[[CMP1_A:.*]] = icmp eq i32 %[[TMP_A]], 03110; CHECK-NEXT:    br i1 %[[CMP1_A]], label %[[BODY_A_A:.*]], label %[[DISPATCH_A:.*]]3111;3112; CHECK:       [[DISPATCH_A]]:3113; CHECK-NEXT:    br label %[[BODY_A_A]]3114;3115; CHECK:       [[BODY_A_A]]:3116; CHECK-NEXT:    %[[TMP_A_PHI_A:.*]] = phi i32 [ 0, %[[HEADER_A]] ], [ %[[TMP_A]], %[[DISPATCH_A]] ]3117; CHECK-NEXT:    %[[TMP_A_A:.*]] = call i32 @a()3118; CHECK-NEXT:    %[[TMP_A_SUM_A:.*]] = add i32 %[[TMP_A_PHI_A]], %[[TMP_A_A]]3119; CHECK-NEXT:    br label %[[BODY_B_A:.*]]3120;3121; CHECK:       [[BODY_B_A]]:3122; CHECK-NEXT:    %[[TMP_B_PHI_A:.*]] = phi i32 [ %[[TMP_A_SUM_A]], %[[BODY_A_A]] ]3123; CHECK-NEXT:    %[[TMP_B_A:.*]] = call i32 @b()3124; CHECK-NEXT:    %[[TMP_B_SUM_A:.*]] = add i32 %[[TMP_B_PHI_A]], %[[TMP_B_A]]3125; CHECK-NEXT:    br label %[[BODY_C_A:.*]]3126;3127; CHECK:       [[BODY_C_A]]:3128; CHECK-NEXT:    %[[TMP_C_PHI_A:.*]] = phi i32 [ %[[TMP_B_SUM_A]], %[[BODY_B_A]] ]3129; CHECK-NEXT:    %[[TMP_C_A:.*]] = call i32 @c()3130; CHECK-NEXT:    %[[TMP_C_SUM_A:.*]] = add i32 %[[TMP_C_PHI_A]], %[[TMP_C_A]]3131; CHECK-NEXT:    br label %[[LATCH_A:.*]]3132;3133; CHECK:       [[LATCH_A]]:3134; CHECK-NEXT:    %[[CMP2_A:.*]] = icmp slt i32 %[[TMP_C_SUM_A]], 423135; CHECK:         br i1 %[[CMP2_A]], label %[[HEADER_A]], label %[[LOOP_EXIT_A:.*]]3136;3137; CHECK:       [[LOOP_EXIT_A]]:3138; CHECK-NEXT:    %[[LCSSA_A:.*]] = phi i32 [ %[[TMP_C_SUM_A]], %[[LATCH_A]] ]3139; CHECK-NEXT:    br label %exit3140 3141body.b:3142  %tmp.b.phi = phi i32 [ %tmp, %dispatch ], [ %tmp.a.sum, %body.a ]3143  %tmp.b = call i32 @b()3144  %tmp.b.sum = add i32 %tmp.b.phi, %tmp.b3145  br label %body.c3146; Unswitched 'b' loop.3147;3148; CHECK:       [[ENTRY_SPLIT_B]]:3149; CHECK-NEXT:    br label %[[HEADER_B:.*]]3150;3151; CHECK:       [[HEADER_B]]:3152; CHECK-NEXT:    %[[TMP_B:.*]] = call i32 @d()3153; CHECK-NEXT:    %[[CMP1_B:.*]] = icmp eq i32 %[[TMP_B]], 03154; CHECK-NEXT:    br i1 %[[CMP1_B]], label %[[BODY_A_B:.*]], label %[[DISPATCH_B:.*]]3155;3156; CHECK:       [[DISPATCH_B]]:3157; CHECK-NEXT:    br label %[[BODY_B_B:.*]]3158;3159; CHECK:       [[BODY_A_B]]:3160; CHECK-NEXT:    %[[TMP_A_PHI_B:.*]] = phi i32 [ 0, %[[HEADER_B]] ]3161; CHECK-NEXT:    %[[TMP_A_B:.*]] = call i32 @a()3162; CHECK-NEXT:    %[[TMP_A_SUM_B:.*]] = add i32 %[[TMP_A_PHI_B]], %[[TMP_A_B]]3163; CHECK-NEXT:    br label %[[BODY_B_B:.*]]3164;3165; CHECK:       [[BODY_B_B]]:3166; CHECK-NEXT:    %[[TMP_B_PHI_B:.*]] = phi i32 [ %[[TMP_B]], %[[DISPATCH_B]] ], [ %[[TMP_A_SUM_B]], %[[BODY_A_B]] ]3167; CHECK-NEXT:    %[[TMP_B_B:.*]] = call i32 @b()3168; CHECK-NEXT:    %[[TMP_B_SUM_B:.*]] = add i32 %[[TMP_B_PHI_B]], %[[TMP_B_B]]3169; CHECK-NEXT:    br label %[[BODY_C_B:.*]]3170;3171; CHECK:       [[BODY_C_B]]:3172; CHECK-NEXT:    %[[TMP_C_PHI_B:.*]] = phi i32 [ %[[TMP_B_SUM_B]], %[[BODY_B_B]] ]3173; CHECK-NEXT:    %[[TMP_C_B:.*]] = call i32 @c()3174; CHECK-NEXT:    %[[TMP_C_SUM_B:.*]] = add i32 %[[TMP_C_PHI_B]], %[[TMP_C_B]]3175; CHECK-NEXT:    br label %[[LATCH_B:.*]]3176;3177; CHECK:       [[LATCH_B]]:3178; CHECK-NEXT:    %[[CMP2_B:.*]] = icmp slt i32 %[[TMP_C_SUM_B]], 423179; CHECK:         br i1 %[[CMP2_B]], label %[[HEADER_B]], label %[[LOOP_EXIT_B:.*]]3180;3181; CHECK:       [[LOOP_EXIT_B]]:3182; CHECK-NEXT:    %[[LCSSA_B:.*]] = phi i32 [ %[[TMP_C_SUM_B]], %[[LATCH_B]] ]3183; CHECK-NEXT:    br label %[[EXIT_SPLIT:.*]]3184 3185body.c:3186  %tmp.c.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ], [ %tmp.b.sum, %body.b ]3187  %tmp.c = call i32 @c()3188  %tmp.c.sum = add i32 %tmp.c.phi, %tmp.c3189  br label %latch3190; Unswitched 'c' loop.3191;3192; CHECK:       [[ENTRY_SPLIT_C]]:3193; CHECK-NEXT:    br label %[[HEADER_C:.*]]3194;3195; CHECK:       [[HEADER_C]]:3196; CHECK-NEXT:    %[[TMP_C:.*]] = call i32 @d()3197; CHECK-NEXT:    %[[CMP1_C:.*]] = icmp eq i32 %[[TMP_C]], 03198; CHECK-NEXT:    br i1 %[[CMP1_C]], label %[[BODY_A_C:.*]], label %[[DISPATCH_C:.*]]3199;3200; CHECK:       [[DISPATCH_C]]:3201; CHECK-NEXT:    br label %[[BODY_C_C:.*]]3202;3203; CHECK:       [[BODY_A_C]]:3204; CHECK-NEXT:    %[[TMP_A_PHI_C:.*]] = phi i32 [ 0, %[[HEADER_C]] ]3205; CHECK-NEXT:    %[[TMP_A_C:.*]] = call i32 @a()3206; CHECK-NEXT:    %[[TMP_A_SUM_C:.*]] = add i32 %[[TMP_A_PHI_C]], %[[TMP_A_C]]3207; CHECK-NEXT:    br label %[[BODY_B_C:.*]]3208;3209; CHECK:       [[BODY_B_C]]:3210; CHECK-NEXT:    %[[TMP_B_PHI_C:.*]] = phi i32 [ %[[TMP_A_SUM_C]], %[[BODY_A_C]] ]3211; CHECK-NEXT:    %[[TMP_B_C:.*]] = call i32 @b()3212; CHECK-NEXT:    %[[TMP_B_SUM_C:.*]] = add i32 %[[TMP_B_PHI_C]], %[[TMP_B_C]]3213; CHECK-NEXT:    br label %[[BODY_C_C:.*]]3214;3215; CHECK:       [[BODY_C_C]]:3216; CHECK-NEXT:    %[[TMP_C_PHI_C:.*]] = phi i32 [ %[[TMP_C]], %[[DISPATCH_C]] ], [ %[[TMP_B_SUM_C]], %[[BODY_B_C]] ]3217; CHECK-NEXT:    %[[TMP_C_C:.*]] = call i32 @c()3218; CHECK-NEXT:    %[[TMP_C_SUM_C:.*]] = add i32 %[[TMP_C_PHI_C]], %[[TMP_C_C]]3219; CHECK-NEXT:    br label %[[LATCH_C:.*]]3220;3221; CHECK:       [[LATCH_C]]:3222; CHECK-NEXT:    %[[CMP2_C:.*]] = icmp slt i32 %[[TMP_C_SUM_C]], 423223; CHECK:         br i1 %[[CMP2_C]], label %[[HEADER_C]], label %[[LOOP_EXIT_C:.*]]3224;3225; CHECK:       [[LOOP_EXIT_C]]:3226; CHECK-NEXT:    %[[LCSSA_C:.*]] = phi i32 [ %[[TMP_C_SUM_C]], %[[LATCH_C]] ]3227; CHECK-NEXT:    br label %[[EXIT_SPLIT]]3228 3229latch:3230  %cmp2 = icmp slt i32 %tmp.c.sum, 423231  br i1 %cmp2, label %header, label %exit3232 3233exit:3234  %lcssa.phi = phi i32 [ %tmp.c.sum, %latch ]3235  ret i32 %lcssa.phi3236; CHECK:       [[EXIT_SPLIT]]:3237; CHECK-NEXT:    %[[EXIT_PHI1:.*]] = phi i32 [ %[[LCSSA_C]], %[[LOOP_EXIT_C]] ], [ %[[LCSSA_B]], %[[LOOP_EXIT_B]] ]3238; CHECK-NEXT:    br label %exit3239 3240; CHECK:       exit:3241; CHECK-NEXT:    %[[EXIT_PHI2:.*]] = phi i32 [ %[[EXIT_PHI1]], %[[EXIT_SPLIT]] ], [ %[[LCSSA_A]], %[[LOOP_EXIT_A]] ]3242; CHECK-NEXT:    ret i32 %[[EXIT_PHI2]]3243}3244 3245; Similar to @test29 but designed to have one of the duplicate edges be3246; a loop exit edge as those can in some cases be special. Among other things,3247; this includes an LCSSA phi with multiple entries despite being a dedicated3248; exit block.3249define i32 @test30(i32 %arg) {3250; CHECK-LABEL: define i32 @test30(3251entry:3252  br label %header3253; CHECK-NEXT:  entry:3254; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i32 %arg3255; CHECK-NEXT:    switch i32 %[[FROZEN]], label %[[ENTRY_SPLIT_EXIT:.*]] [3256; CHECK-NEXT:      i32 -1, label %[[ENTRY_SPLIT_EXIT]]3257; CHECK-NEXT:      i32 0, label %[[ENTRY_SPLIT_A:.*]]3258; CHECK-NEXT:      i32 1, label %[[ENTRY_SPLIT_B:.*]]3259; CHECK-NEXT:      i32 2, label %[[ENTRY_SPLIT_B]]3260; CHECK-NEXT:    ]3261 3262header:3263  %tmp = call i32 @d()3264  %cmp1 = icmp eq i32 %tmp, 03265  br i1 %cmp1, label %body.a, label %dispatch3266 3267dispatch:3268  switch i32 %arg, label %loop.exit1 [3269    i32 -1, label %loop.exit13270    i32 0, label %body.a3271    i32 1, label %body.b3272    i32 2, label %body.b3273  ]3274 3275body.a:3276  %tmp.a.phi = phi i32 [ 0, %header ], [ %tmp, %dispatch ]3277  %tmp.a = call i32 @a()3278  %tmp.a.sum = add i32 %tmp.a.phi, %tmp.a3279  br label %body.b3280; Unswitched 'a' loop.3281;3282; CHECK:       [[ENTRY_SPLIT_A]]:3283; CHECK-NEXT:    br label %[[HEADER_A:.*]]3284;3285; CHECK:       [[HEADER_A]]:3286; CHECK-NEXT:    %[[TMP_A:.*]] = call i32 @d()3287; CHECK-NEXT:    %[[CMP1_A:.*]] = icmp eq i32 %[[TMP_A]], 03288; CHECK-NEXT:    br i1 %[[CMP1_A]], label %[[BODY_A_A:.*]], label %[[DISPATCH_A:.*]]3289;3290; CHECK:       [[DISPATCH_A]]:3291; CHECK-NEXT:    br label %[[BODY_A_A]]3292;3293; CHECK:       [[BODY_A_A]]:3294; CHECK-NEXT:    %[[TMP_A_PHI_A:.*]] = phi i32 [ 0, %[[HEADER_A]] ], [ %[[TMP_A]], %[[DISPATCH_A]] ]3295; CHECK-NEXT:    %[[TMP_A_A:.*]] = call i32 @a()3296; CHECK-NEXT:    %[[TMP_A_SUM_A:.*]] = add i32 %[[TMP_A_PHI_A]], %[[TMP_A_A]]3297; CHECK-NEXT:    br label %[[BODY_B_A:.*]]3298;3299; CHECK:       [[BODY_B_A]]:3300; CHECK-NEXT:    %[[TMP_B_PHI_A:.*]] = phi i32 [ %[[TMP_A_SUM_A]], %[[BODY_A_A]] ]3301; CHECK-NEXT:    %[[TMP_B_A:.*]] = call i32 @b()3302; CHECK-NEXT:    %[[TMP_B_SUM_A:.*]] = add i32 %[[TMP_B_PHI_A]], %[[TMP_B_A]]3303; CHECK-NEXT:    br label %[[LATCH_A:.*]]3304;3305; CHECK:       [[LATCH_A]]:3306; CHECK-NEXT:    %[[CMP2_A:.*]] = icmp slt i32 %[[TMP_B_SUM_A]], 423307; CHECK:         br i1 %[[CMP2_A]], label %[[HEADER_A]], label %[[LOOP_EXIT_A:.*]]3308;3309; CHECK:       [[LOOP_EXIT_A]]:3310; CHECK-NEXT:    %[[LCSSA_A:.*]] = phi i32 [ %[[TMP_B_SUM_A]], %[[LATCH_A]] ]3311; CHECK-NEXT:    br label %loop.exit23312 3313body.b:3314  %tmp.b.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ], [ %tmp.a.sum, %body.a ]3315  %tmp.b = call i32 @b()3316  %tmp.b.sum = add i32 %tmp.b.phi, %tmp.b3317  br label %latch3318; Unswitched 'b' loop.3319;3320; CHECK:       [[ENTRY_SPLIT_B]]:3321; CHECK-NEXT:    br label %[[HEADER_B:.*]]3322;3323; CHECK:       [[HEADER_B]]:3324; CHECK-NEXT:    %[[TMP_B:.*]] = call i32 @d()3325; CHECK-NEXT:    %[[CMP1_B:.*]] = icmp eq i32 %[[TMP_B]], 03326; CHECK-NEXT:    br i1 %[[CMP1_B]], label %[[BODY_A_B:.*]], label %[[DISPATCH_B:.*]]3327;3328; CHECK:       [[DISPATCH_B]]:3329; CHECK-NEXT:    br label %[[BODY_B_B]]3330;3331; CHECK:       [[BODY_A_B]]:3332; CHECK-NEXT:    %[[TMP_A_PHI_B:.*]] = phi i32 [ 0, %[[HEADER_B]] ]3333; CHECK-NEXT:    %[[TMP_A_B:.*]] = call i32 @a()3334; CHECK-NEXT:    %[[TMP_A_SUM_B:.*]] = add i32 %[[TMP_A_PHI_B]], %[[TMP_A_B]]3335; CHECK-NEXT:    br label %[[BODY_B_B:.*]]3336;3337; CHECK:       [[BODY_B_B]]:3338; CHECK-NEXT:    %[[TMP_B_PHI_B:.*]] = phi i32 [ %[[TMP_B]], %[[DISPATCH_B]] ], [ %[[TMP_A_SUM_B]], %[[BODY_A_B]] ]3339; CHECK-NEXT:    %[[TMP_B_B:.*]] = call i32 @b()3340; CHECK-NEXT:    %[[TMP_B_SUM_B:.*]] = add i32 %[[TMP_B_PHI_B]], %[[TMP_B_B]]3341; CHECK-NEXT:    br label %[[LATCH_B:.*]]3342;3343; CHECK:       [[LATCH_B]]:3344; CHECK-NEXT:    %[[CMP2_B:.*]] = icmp slt i32 %[[TMP_B_SUM_B]], 423345; CHECK:         br i1 %[[CMP2_B]], label %[[HEADER_B]], label %[[LOOP_EXIT_B:.*]]3346;3347; CHECK:       [[LOOP_EXIT_B]]:3348; CHECK-NEXT:    %[[LCSSA_B:.*]] = phi i32 [ %[[TMP_B_SUM_B]], %[[LATCH_B]] ]3349; CHECK-NEXT:    br label %[[LOOP_EXIT2_SPLIT:.*]]3350 3351latch:3352  %cmp2 = icmp slt i32 %tmp.b.sum, 423353  br i1 %cmp2, label %header, label %loop.exit23354 3355loop.exit1:3356  %l1.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ]3357  br label %exit3358; Unswitched 'exit' loop.3359;3360; CHECK:       [[ENTRY_SPLIT_EXIT]]:3361; CHECK-NEXT:    br label %[[HEADER_EXIT:.*]]3362;3363; CHECK:       [[HEADER_EXIT]]:3364; CHECK-NEXT:    %[[TMP_EXIT:.*]] = call i32 @d()3365; CHECK-NEXT:    %[[CMP1_EXIT:.*]] = icmp eq i32 %[[TMP_EXIT]], 03366; CHECK-NEXT:    br i1 %[[CMP1_EXIT]], label %[[BODY_A_EXIT:.*]], label %[[DISPATCH_EXIT:.*]]3367;3368; CHECK:       [[DISPATCH_EXIT]]:3369; CHECK-NEXT:    %[[TMP_LCSSA:.*]] = phi i32 [ %[[TMP_EXIT]], %[[HEADER_EXIT]] ]3370; CHECK-NEXT:    br label %loop.exit13371;3372; CHECK:       [[BODY_A_EXIT]]:3373; CHECK-NEXT:    %[[TMP_A_PHI_EXIT:.*]] = phi i32 [ 0, %[[HEADER_EXIT]] ]3374; CHECK-NEXT:    %[[TMP_A_EXIT:.*]] = call i32 @a()3375; CHECK-NEXT:    %[[TMP_A_SUM_EXIT:.*]] = add i32 %[[TMP_A_PHI_EXIT]], %[[TMP_A_EXIT]]3376; CHECK-NEXT:    br label %[[BODY_B_EXIT:.*]]3377;3378; CHECK:       [[BODY_B_EXIT]]:3379; CHECK-NEXT:    %[[TMP_B_PHI_EXIT:.*]] = phi i32 [ %[[TMP_A_SUM_EXIT]], %[[BODY_A_EXIT]] ]3380; CHECK-NEXT:    %[[TMP_B_EXIT:.*]] = call i32 @b()3381; CHECK-NEXT:    %[[TMP_B_SUM_EXIT:.*]] = add i32 %[[TMP_B_PHI_EXIT]], %[[TMP_B_EXIT]]3382; CHECK-NEXT:    br label %[[LATCH_EXIT:.*]]3383;3384; CHECK:       [[LATCH_EXIT]]:3385; CHECK-NEXT:    %[[CMP2_EXIT:.*]] = icmp slt i32 %[[TMP_B_SUM_EXIT]], 423386; CHECK:         br i1 %[[CMP2_EXIT]], label %[[HEADER_EXIT]], label %[[LOOP_EXIT_EXIT:.*]]3387;3388; CHECK:       loop.exit1:3389; CHECK-NEXT:    %[[L1_PHI:.*]] = phi i32 [ %[[TMP_LCSSA]], %[[DISPATCH_EXIT]] ]3390; CHECK-NEXT:    br label %exit3391;3392; CHECK:       [[LOOP_EXIT_EXIT]]:3393; CHECK-NEXT:    %[[L2_PHI:.*]] = phi i32 [ %[[TMP_B_SUM_EXIT]], %[[LATCH_EXIT]] ]3394; CHECK-NEXT:    br label %[[LOOP_EXIT2_SPLIT]]3395 3396loop.exit2:3397  %l2.phi = phi i32 [ %tmp.b.sum, %latch ]3398  br label %exit3399; CHECK:       [[LOOP_EXIT2_SPLIT]]:3400; CHECK-NEXT:    %[[LOOP_EXIT_PHI1:.*]] = phi i32 [ %[[L2_PHI]], %[[LOOP_EXIT_EXIT]] ], [ %[[LCSSA_B]], %[[LOOP_EXIT_B]] ]3401; CHECK-NEXT:    br label %loop.exit23402;3403; CHECK:       loop.exit2:3404; CHECK-NEXT:    %[[LOOP_EXIT_PHI2:.*]] = phi i32 [ %[[LOOP_EXIT_PHI1]], %[[LOOP_EXIT2_SPLIT]] ], [ %[[LCSSA_A]], %[[LOOP_EXIT_A]] ]3405; CHECK-NEXT:    br label %exit3406 3407exit:3408  %l.phi = phi i32 [ %l1.phi, %loop.exit1 ], [ %l2.phi, %loop.exit2 ]3409  ret i32 %l.phi3410; CHECK:       exit:3411; CHECK-NEXT:    %[[EXIT_PHI:.*]] = phi i32 [ %[[L1_PHI]], %loop.exit1 ], [ %[[LOOP_EXIT_PHI2]], %loop.exit2 ]3412; CHECK-NEXT:    ret i32 %[[EXIT_PHI]]3413}3414 3415; Unswitch will not actually change the loop nest from:3416;   A < B < C3417define void @hoist_inner_loop0() {3418; CHECK-LABEL: define void @hoist_inner_loop0(3419entry:3420  br label %a.header3421; CHECK:       entry:3422; CHECK-NEXT:    br label %a.header3423 3424a.header:3425  br label %b.header3426; CHECK:       a.header:3427; CHECK-NEXT:    br label %b.header3428 3429b.header:3430  %v1 = call i1 @cond()3431  br label %c.header3432; CHECK:       b.header:3433; CHECK-NEXT:    %v1 = call i1 @cond()3434; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %v13435; CHECK-NEXT:    br i1 %[[FROZEN]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]3436;3437; CHECK:       [[B_HEADER_SPLIT_US]]:3438; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]3439;3440; CHECK:       [[C_HEADER_US]]:3441; CHECK-NEXT:    call i32 @c()3442; CHECK-NEXT:    br label %[[B_LATCH_SPLIT_US:.*]]3443;3444; CHECK:       [[B_LATCH_SPLIT_US]]:3445; CHECK-NEXT:    br label %b.latch3446;3447; CHECK:       [[B_HEADER_SPLIT]]:3448; CHECK-NEXT:    br label %c.header3449 3450c.header:3451  call i32 @c()3452  br i1 %v1, label %b.latch, label %c.latch3453; CHECK:       c.header:3454; CHECK-NEXT:    call i32 @c()3455; CHECK-NEXT:    br label %c.latch3456 3457c.latch:3458  %v2 = call i1 @cond()3459  br i1 %v2, label %c.header, label %b.latch3460; CHECK:       c.latch:3461; CHECK-NEXT:    %v2 = call i1 @cond()3462; CHECK-NEXT:    br i1 %v2, label %c.header, label %[[B_LATCH_SPLIT:.*]]3463 3464b.latch:3465  %v3 = call i1 @cond()3466  br i1 %v3, label %b.header, label %a.latch3467; CHECK:       [[B_LATCH_SPLIT]]:3468; CHECK-NEXT:    br label %b.latch3469;3470; CHECK:       b.latch:3471; CHECK-NEXT:    %v3 = call i1 @cond()3472; CHECK-NEXT:    br i1 %v3, label %b.header, label %a.latch3473 3474a.latch:3475  br label %a.header3476; CHECK:       a.latch:3477; CHECK-NEXT:    br label %a.header3478 3479exit:3480  ret void3481; CHECK:       exit:3482; CHECK-NEXT:    ret void3483}3484 3485; Unswitch will transform the loop nest from:3486;   A < B < C3487; into3488;   A < (B, C)3489define void @hoist_inner_loop1(ptr %ptr) {3490; CHECK-LABEL: define void @hoist_inner_loop1(3491entry:3492  br label %a.header3493; CHECK:       entry:3494; CHECK-NEXT:    br label %a.header3495 3496a.header:3497  %x.a = load i32, ptr %ptr3498  br label %b.header3499; CHECK:       a.header:3500; CHECK-NEXT:    %x.a = load i32, ptr %ptr3501; CHECK-NEXT:    br label %b.header3502 3503b.header:3504  %x.b = load i32, ptr %ptr3505  %v1 = call i1 @cond()3506  br label %c.header3507; CHECK:       b.header:3508; CHECK-NEXT:    %x.b = load i32, ptr %ptr3509; CHECK-NEXT:    %v1 = call i1 @cond()3510; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %v13511; CHECK-NEXT:    br i1 %[[FROZEN]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]3512;3513; CHECK:       [[B_HEADER_SPLIT_US]]:3514; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]3515;3516; CHECK:       [[C_HEADER_US]]:3517; CHECK-NEXT:    call i32 @c()3518; CHECK-NEXT:    br label %[[B_LATCH_US:.*]]3519;3520; CHECK:       [[B_LATCH_US]]:3521; CHECK-NEXT:    br label %b.latch3522;3523; CHECK:       [[B_HEADER_SPLIT]]:3524; CHECK-NEXT:    %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]3525; CHECK-NEXT:    br label %c.header3526 3527c.header:3528  call i32 @c()3529  br i1 %v1, label %b.latch, label %c.latch3530; CHECK:       c.header:3531; CHECK-NEXT:    call i32 @c()3532; CHECK-NEXT:    br label %c.latch3533 3534c.latch:3535  ; Use values from other loops to check LCSSA form.3536  store i32 %x.a, ptr %ptr3537  store i32 %x.b, ptr %ptr3538  %v2 = call i1 @cond()3539  br i1 %v2, label %c.header, label %a.exit.c3540; CHECK:       c.latch:3541; CHECK-NEXT:    store i32 %x.a, ptr %ptr3542; CHECK-NEXT:    store i32 %[[X_B_LCSSA]], ptr %ptr3543; CHECK-NEXT:    %v2 = call i1 @cond()3544; CHECK-NEXT:    br i1 %v2, label %c.header, label %a.exit.c3545 3546b.latch:3547  %v3 = call i1 @cond()3548  br i1 %v3, label %b.header, label %a.exit.b3549; CHECK:       b.latch:3550; CHECK-NEXT:    %v3 = call i1 @cond()3551; CHECK-NEXT:    br i1 %v3, label %b.header, label %a.exit.b3552 3553a.exit.c:3554  br label %a.latch3555; CHECK:       a.exit.c3556; CHECK-NEXT:    br label %a.latch3557 3558a.exit.b:3559  br label %a.latch3560; CHECK:       a.exit.b:3561; CHECK-NEXT:    br label %a.latch3562 3563a.latch:3564  br label %a.header3565; CHECK:       a.latch:3566; CHECK-NEXT:    br label %a.header3567 3568exit:3569  ret void3570; CHECK:       exit:3571; CHECK-NEXT:    ret void3572}3573 3574; Unswitch will transform the loop nest from:3575;   A < B < C3576; into3577;   (A < B), C3578define void @hoist_inner_loop2(ptr %ptr) {3579; CHECK-LABEL: define void @hoist_inner_loop2(3580entry:3581  br label %a.header3582; CHECK:       entry:3583; CHECK-NEXT:    br label %a.header3584 3585a.header:3586  %x.a = load i32, ptr %ptr3587  br label %b.header3588; CHECK:       a.header:3589; CHECK-NEXT:    %x.a = load i32, ptr %ptr3590; CHECK-NEXT:    br label %b.header3591 3592b.header:3593  %x.b = load i32, ptr %ptr3594  %v1 = call i1 @cond()3595  br label %c.header3596; CHECK:       b.header:3597; CHECK-NEXT:    %x.b = load i32, ptr %ptr3598; CHECK-NEXT:    %v1 = call i1 @cond()3599; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %v13600; CHECK-NEXT:    br i1 %[[FROZEN]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]3601;3602; CHECK:       [[B_HEADER_SPLIT_US]]:3603; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]3604;3605; CHECK:       [[C_HEADER_US]]:3606; CHECK-NEXT:    call i32 @c()3607; CHECK-NEXT:    br label %[[B_LATCH_US:.*]]3608;3609; CHECK:       [[B_LATCH_US]]:3610; CHECK-NEXT:    br label %b.latch3611;3612; CHECK:       [[B_HEADER_SPLIT]]:3613; CHECK-NEXT:    %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]3614; CHECK-NEXT:    %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]3615; CHECK-NEXT:    br label %c.header3616 3617c.header:3618  call i32 @c()3619  br i1 %v1, label %b.latch, label %c.latch3620; CHECK:       c.header:3621; CHECK-NEXT:    call i32 @c()3622; CHECK-NEXT:    br label %c.latch3623 3624c.latch:3625  ; Use values from other loops to check LCSSA form.3626  store i32 %x.a, ptr %ptr3627  store i32 %x.b, ptr %ptr3628  %v2 = call i1 @cond()3629  br i1 %v2, label %c.header, label %exit3630; CHECK:       c.latch:3631; CHECK-NEXT:    store i32 %[[X_A_LCSSA]], ptr %ptr3632; CHECK-NEXT:    store i32 %[[X_B_LCSSA]], ptr %ptr3633; CHECK-NEXT:    %v2 = call i1 @cond()3634; CHECK-NEXT:    br i1 %v2, label %c.header, label %exit3635 3636b.latch:3637  %v3 = call i1 @cond()3638  br i1 %v3, label %b.header, label %a.latch3639; CHECK:       b.latch:3640; CHECK-NEXT:    %v3 = call i1 @cond()3641; CHECK-NEXT:    br i1 %v3, label %b.header, label %a.latch3642 3643a.latch:3644  br label %a.header3645; CHECK:       a.latch:3646; CHECK-NEXT:    br label %a.header3647 3648exit:3649  ret void3650; CHECK:       exit:3651; CHECK-NEXT:    ret void3652}3653 3654; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.3655; Unswitch will transform the loop nest from:3656;   A < B < C < D3657; into3658;   (A < B), (C < D)3659define void @hoist_inner_loop3(ptr %ptr) {3660; CHECK-LABEL: define void @hoist_inner_loop3(3661entry:3662  br label %a.header3663; CHECK:       entry:3664; CHECK-NEXT:    br label %a.header3665 3666a.header:3667  %x.a = load i32, ptr %ptr3668  br label %b.header3669; CHECK:       a.header:3670; CHECK-NEXT:    %x.a = load i32, ptr %ptr3671; CHECK-NEXT:    br label %b.header3672 3673b.header:3674  %x.b = load i32, ptr %ptr3675  %v1 = call i1 @cond()3676  br label %c.header3677; CHECK:       b.header:3678; CHECK-NEXT:    %x.b = load i32, ptr %ptr3679; CHECK-NEXT:    %v1 = call i1 @cond()3680; CHECK-NEXT:    %[[FROZEN:.+]] = freeze i1 %v13681; CHECK-NEXT:    br i1 %[[FROZEN]], label %[[B_HEADER_SPLIT_US:.*]], label %[[B_HEADER_SPLIT:.*]]3682;3683; CHECK:       [[B_HEADER_SPLIT_US]]:3684; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]3685;3686; CHECK:       [[C_HEADER_US]]:3687; CHECK-NEXT:    call i32 @c()3688; CHECK-NEXT:    br label %[[B_LATCH_US:.*]]3689;3690; CHECK:       [[B_LATCH_US]]:3691; CHECK-NEXT:    br label %b.latch3692;3693; CHECK:       [[B_HEADER_SPLIT]]:3694; CHECK-NEXT:    %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]3695; CHECK-NEXT:    %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]3696; CHECK-NEXT:    br label %c.header3697 3698c.header:3699  call i32 @c()3700  br i1 %v1, label %b.latch, label %c.body3701; CHECK:       c.header:3702; CHECK-NEXT:    call i32 @c()3703; CHECK-NEXT:    br label %c.body3704 3705c.body:3706  %x.c = load i32, ptr %ptr3707  br label %d.header3708; CHECK:       c.body:3709; CHECK-NEXT:    %x.c = load i32, ptr %ptr3710; CHECK-NEXT:    br label %d.header3711 3712d.header:3713  ; Use values from other loops to check LCSSA form.3714  store i32 %x.a, ptr %ptr3715  store i32 %x.b, ptr %ptr3716  store i32 %x.c, ptr %ptr3717  %v2 = call i1 @cond()3718  br i1 %v2, label %d.header, label %c.latch3719; CHECK:       d.header:3720; CHECK-NEXT:    store i32 %[[X_A_LCSSA]], ptr %ptr3721; CHECK-NEXT:    store i32 %[[X_B_LCSSA]], ptr %ptr3722; CHECK-NEXT:    store i32 %x.c, ptr %ptr3723; CHECK-NEXT:    %v2 = call i1 @cond()3724; CHECK-NEXT:    br i1 %v2, label %d.header, label %c.latch3725 3726c.latch:3727  %v3 = call i1 @cond()3728  br i1 %v3, label %c.header, label %exit3729; CHECK:       c.latch:3730; CHECK-NEXT:    %v3 = call i1 @cond()3731; CHECK-NEXT:    br i1 %v3, label %c.header, label %exit3732 3733b.latch:3734  %v4 = call i1 @cond()3735  br i1 %v4, label %b.header, label %a.latch3736; CHECK:       b.latch:3737; CHECK-NEXT:    %v4 = call i1 @cond()3738; CHECK-NEXT:    br i1 %v4, label %b.header, label %a.latch3739 3740a.latch:3741  br label %a.header3742; CHECK:       a.latch:3743; CHECK-NEXT:    br label %a.header3744 3745exit:3746  ret void3747; CHECK:       exit:3748; CHECK-NEXT:    ret void3749}3750 3751; This test is designed to exercise checking multiple remaining exits from the3752; loop being unswitched.3753; Unswitch will transform the loop nest from:3754;   A < B < C < D3755; into3756;   A < B < (C, D)3757define void @hoist_inner_loop4() {3758; CHECK-LABEL: define void @hoist_inner_loop4(3759entry:3760  br label %a.header3761; CHECK:       entry:3762; CHECK-NEXT:    br label %a.header3763 3764a.header:3765  br label %b.header3766; CHECK:       a.header:3767; CHECK-NEXT:    br label %b.header3768 3769b.header:3770  br label %c.header3771; CHECK:       b.header:3772; CHECK-NEXT:    br label %c.header3773 3774c.header:3775  %v1 = call i1 @cond()3776  br label %d.header3777; CHECK:       c.header:3778; CHECK-NEXT:    %v1 = call i1 @cond()3779; CHECK-NEXT:    [[FROZEN:%.+]] = freeze i1 %v13780; CHECK-NEXT:    br i1 [[FROZEN]], label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]3781;3782; CHECK:       [[C_HEADER_SPLIT_US]]:3783; CHECK-NEXT:    br label %[[D_HEADER_US:.*]]3784;3785; CHECK:       [[D_HEADER_US]]:3786; CHECK-NEXT:    call i32 @d()3787; CHECK-NEXT:    br label %[[C_LATCH_US:.*]]3788;3789; CHECK:       [[C_LATCH_US]]:3790; CHECK-NEXT:    br label %c.latch3791;3792; CHECK:       [[C_HEADER_SPLIT]]:3793; CHECK-NEXT:    br label %d.header3794 3795d.header:3796  call i32 @d()3797  br i1 %v1, label %c.latch, label %d.exiting13798; CHECK:       d.header:3799; CHECK-NEXT:    call i32 @d()3800; CHECK-NEXT:    br label %d.exiting13801 3802d.exiting1:3803  %v2 = call i1 @cond()3804  br i1 %v2, label %d.exiting2, label %a.latch3805; CHECK:       d.exiting1:3806; CHECK-NEXT:    %v2 = call i1 @cond()3807; CHECK-NEXT:    br i1 %v2, label %d.exiting2, label %a.latch3808 3809d.exiting2:3810  %v3 = call i1 @cond()3811  br i1 %v3, label %d.exiting3, label %loopexit.d3812; CHECK:       d.exiting2:3813; CHECK-NEXT:    %v3 = call i1 @cond()3814; CHECK-NEXT:    br i1 %v3, label %d.exiting3, label %loopexit.d3815 3816d.exiting3:3817  %v4 = call i1 @cond()3818  br i1 %v4, label %d.latch, label %b.latch3819; CHECK:       d.exiting3:3820; CHECK-NEXT:    %v4 = call i1 @cond()3821; CHECK-NEXT:    br i1 %v4, label %d.latch, label %b.latch3822 3823d.latch:3824  br label %d.header3825; CHECK:       d.latch:3826; CHECK-NEXT:    br label %d.header3827 3828c.latch:3829  %v5 = call i1 @cond()3830  br i1 %v5, label %c.header, label %loopexit.c3831; CHECK:       c.latch:3832; CHECK-NEXT:    %v5 = call i1 @cond()3833; CHECK-NEXT:    br i1 %v5, label %c.header, label %loopexit.c3834 3835b.latch:3836  br label %b.header3837; CHECK:       b.latch:3838; CHECK-NEXT:    br label %b.header3839 3840a.latch:3841  br label %a.header3842; CHECK:       a.latch:3843; CHECK-NEXT:    br label %a.header3844 3845loopexit.d:3846  br label %exit3847; CHECK:       loopexit.d:3848; CHECK-NEXT:    br label %exit3849 3850loopexit.c:3851  br label %exit3852; CHECK:       loopexit.c:3853; CHECK-NEXT:    br label %exit3854 3855exit:3856  ret void3857; CHECK:       exit:3858; CHECK-NEXT:    ret void3859}3860 3861; Unswitch will transform the loop nest from:3862;   A < B < C < D3863; into3864;   A < ((B < C), D)3865define void @hoist_inner_loop5(ptr %ptr) {3866; CHECK-LABEL: define void @hoist_inner_loop5(3867entry:3868  br label %a.header3869; CHECK:       entry:3870; CHECK-NEXT:    br label %a.header3871 3872a.header:3873  %x.a = load i32, ptr %ptr3874  br label %b.header3875; CHECK:       a.header:3876; CHECK-NEXT:    %x.a = load i32, ptr %ptr3877; CHECK-NEXT:    br label %b.header3878 3879b.header:3880  %x.b = load i32, ptr %ptr3881  br label %c.header3882; CHECK:       b.header:3883; CHECK-NEXT:    %x.b = load i32, ptr %ptr3884; CHECK-NEXT:    br label %c.header3885 3886c.header:3887  %x.c = load i32, ptr %ptr3888  %v1 = call i1 @cond()3889  br label %d.header3890; CHECK:       c.header:3891; CHECK-NEXT:    %x.c = load i32, ptr %ptr3892; CHECK-NEXT:    %v1 = call i1 @cond()3893; CHECK-NEXT:    [[FROZEN:%.+]] = freeze i1 %v13894; CHECK-NEXT:    br i1 [[FROZEN]], label %[[C_HEADER_SPLIT_US:.*]], label %[[C_HEADER_SPLIT:.*]]3895;3896; CHECK:       [[C_HEADER_SPLIT_US]]:3897; CHECK-NEXT:    br label %[[D_HEADER_US:.*]]3898;3899; CHECK:       [[D_HEADER_US]]:3900; CHECK-NEXT:    call i32 @d()3901; CHECK-NEXT:    br label %[[C_LATCH_US:.*]]3902;3903; CHECK:       [[C_LATCH_US]]:3904; CHECK-NEXT:    br label %c.latch3905;3906; CHECK:       [[C_HEADER_SPLIT]]:3907; CHECK-NEXT:    %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %c.header ]3908; CHECK-NEXT:    %[[X_C_LCSSA:.*]] = phi i32 [ %x.c, %c.header ]3909; CHECK-NEXT:    br label %d.header3910 3911d.header:3912  call i32 @d()3913  br i1 %v1, label %c.latch, label %d.latch3914; CHECK:       d.header:3915; CHECK-NEXT:    call i32 @d()3916; CHECK-NEXT:    br label %d.latch3917 3918d.latch:3919  ; Use values from other loops to check LCSSA form.3920  store i32 %x.a, ptr %ptr3921  store i32 %x.b, ptr %ptr3922  store i32 %x.c, ptr %ptr3923  %v2 = call i1 @cond()3924  br i1 %v2, label %d.header, label %a.latch3925; CHECK:       d.latch:3926; CHECK-NEXT:    store i32 %x.a, ptr %ptr3927; CHECK-NEXT:    store i32 %[[X_B_LCSSA]], ptr %ptr3928; CHECK-NEXT:    store i32 %[[X_C_LCSSA]], ptr %ptr3929; CHECK-NEXT:    %v2 = call i1 @cond()3930; CHECK-NEXT:    br i1 %v2, label %d.header, label %a.latch3931 3932c.latch:3933  %v3 = call i1 @cond()3934  br i1 %v3, label %c.header, label %b.latch3935; CHECK:       c.latch:3936; CHECK-NEXT:    %v3 = call i1 @cond()3937; CHECK-NEXT:    br i1 %v3, label %c.header, label %b.latch3938 3939b.latch:3940  br label %b.header3941; CHECK:       b.latch:3942; CHECK-NEXT:    br label %b.header3943 3944a.latch:3945  br label %a.header3946; CHECK:       a.latch:3947; CHECK-NEXT:    br label %a.header3948 3949exit:3950  ret void3951; CHECK:       exit:3952; CHECK-NEXT:    ret void3953}3954 3955define void @hoist_inner_loop_switch(ptr %ptr) {3956; CHECK-LABEL: define void @hoist_inner_loop_switch(3957entry:3958  br label %a.header3959; CHECK:       entry:3960; CHECK-NEXT:    br label %a.header3961 3962a.header:3963  %x.a = load i32, ptr %ptr3964  br label %b.header3965; CHECK:       a.header:3966; CHECK-NEXT:    %x.a = load i32, ptr %ptr3967; CHECK-NEXT:    br label %b.header3968 3969b.header:3970  %x.b = load i32, ptr %ptr3971  %v1 = call i32 @cond.i32()3972  br label %c.header3973; CHECK:       b.header:3974; CHECK-NEXT:    %x.b = load i32, ptr %ptr3975; CHECK-NEXT:    %v1 = call i32 @cond.i32()3976; CHECK-NEXT:    [[FROZEN:%.+]] = freeze i32 %v13977; CHECK-NEXT:    switch i32 [[FROZEN]], label %[[B_HEADER_SPLIT:.*]] [3978; CHECK-NEXT:      i32 1, label %[[B_HEADER_SPLIT_US:.*]]3979; CHECK-NEXT:      i32 2, label %[[B_HEADER_SPLIT_US]]3980; CHECK-NEXT:      i32 3, label %[[B_HEADER_SPLIT_US]]3981; CHECK-NEXT:    ]3982;3983; CHECK:       [[B_HEADER_SPLIT_US]]:3984; CHECK-NEXT:    br label %[[C_HEADER_US:.*]]3985;3986; CHECK:       [[C_HEADER_US]]:3987; CHECK-NEXT:    call i32 @c()3988; CHECK-NEXT:    br label %[[B_LATCH_US:.*]]3989;3990; CHECK:       [[B_LATCH_US]]:3991; CHECK-NEXT:    br label %b.latch3992;3993; CHECK:       [[B_HEADER_SPLIT]]:3994; CHECK-NEXT:    %[[X_A_LCSSA:.*]] = phi i32 [ %x.a, %b.header ]3995; CHECK-NEXT:    %[[X_B_LCSSA:.*]] = phi i32 [ %x.b, %b.header ]3996; CHECK-NEXT:    br label %c.header3997 3998c.header:3999  call i32 @c()4000  switch i32 %v1, label %c.latch [4001    i32 1, label %b.latch4002    i32 2, label %b.latch4003    i32 3, label %b.latch4004  ]4005; CHECK:       c.header:4006; CHECK-NEXT:    call i32 @c()4007; CHECK-NEXT:    br label %c.latch4008 4009c.latch:4010  ; Use values from other loops to check LCSSA form.4011  store i32 %x.a, ptr %ptr4012  store i32 %x.b, ptr %ptr4013  %v2 = call i1 @cond()4014  br i1 %v2, label %c.header, label %exit4015; CHECK:       c.latch:4016; CHECK-NEXT:    store i32 %[[X_A_LCSSA]], ptr %ptr4017; CHECK-NEXT:    store i32 %[[X_B_LCSSA]], ptr %ptr4018; CHECK-NEXT:    %v2 = call i1 @cond()4019; CHECK-NEXT:    br i1 %v2, label %c.header, label %exit4020 4021b.latch:4022  %v3 = call i1 @cond()4023  br i1 %v3, label %b.header, label %a.latch4024; CHECK:       b.latch:4025; CHECK-NEXT:    %v3 = call i1 @cond()4026; CHECK-NEXT:    br i1 %v3, label %b.header, label %a.latch4027 4028a.latch:4029  br label %a.header4030; CHECK:       a.latch:4031; CHECK-NEXT:    br label %a.header4032 4033exit:4034  ret void4035; CHECK:       exit:4036; CHECK-NEXT:    ret void4037}4038 4039; A devilish pattern. This is a crafty, crafty test case designed to risk4040; creating indirect cycles with trivial and non-trivial unswitching. The inner4041; loop has a switch with a trivial exit edge that can be unswitched, but the4042; rest of the switch cannot be unswitched because its cost is too high.4043; However, the unswitching of the trivial edge creates a new switch in the4044; outer loop. *This* switch isn't trivial, but has a low cost to unswitch. When4045; we unswitch this switch from the outer loop, we will remove it completely and4046; create a clone of the inner loop on one side. This clone will then again be4047; viable for unswitching the inner-most loop. This lets us check that the4048; unswitching doesn't end up cycling infinitely even when the cycle is4049; indirect and due to revisiting a loop after cloning.4050define void @test31(i32 %arg) {4051; CHECK-LABEL: define void @test31(4052entry:4053  br label %outer.header4054; CHECK-NEXT:  entry:4055; CHECK-NEXT:    switch i32 %arg, label %[[ENTRY_SPLIT:.*]] [4056; CHECK-NEXT:      i32 1, label %[[ENTRY_SPLIT_US:.*]]4057; CHECK-NEXT:      i32 2, label %[[ENTRY_SPLIT_US]]4058; CHECK-NEXT:    ]4059;4060; CHECK:       [[ENTRY_SPLIT_US]]:4061; CHECK-NEXT:    switch i32 %arg, label %[[ENTRY_SPLIT_US_SPLIT:.*]] [4062; CHECK-NEXT:      i32 1, label %[[ENTRY_SPLIT_US_SPLIT_US:.*]]4063; CHECK-NEXT:    ]4064 4065outer.header:4066  br label %inner.header4067 4068inner.header:4069  switch i32 %arg, label %inner.loopexit1 [4070    i32 1, label %inner.body14071    i32 2, label %inner.body24072  ]4073 4074inner.body1:4075  %a = call i32 @a()4076  br label %inner.latch4077; The (super convoluted) fully unswitched loop around `@a`.4078;4079; CHECK:       [[ENTRY_SPLIT_US_SPLIT_US]]:4080; CHECK-NEXT:    br label %[[OUTER_HEADER_US_US:.*]]4081;4082; CHECK:       [[OUTER_HEADER_US_US]]:4083; CHECK-NEXT:    br label %[[OUTER_HEADER_SPLIT_US_US:.*]]4084;4085; CHECK:       [[OUTER_LATCH_US_US:.*]]:4086; CHECK-NEXT:    %[[OUTER_COND_US_US:.*]] = call i1 @cond()4087; CHECK-NEXT:    br i1 %[[OUTER_COND_US_US]], label %[[OUTER_HEADER_US_US]], label %[[EXIT_SPLIT_US_SPLIT_US:.*]]4088;4089; CHECK:       [[OUTER_HEADER_SPLIT_US_US]]:4090; CHECK-NEXT:    br label %[[OUTER_HEADER_SPLIT_SPLIT_US_US_US:.*]]4091;4092; CHECK:       [[INNER_LOOPEXIT2_US_US:.*]]:4093; CHECK-NEXT:    br label %[[OUTER_LATCH_US_US]]4094;4095; CHECK:       [[OUTER_HEADER_SPLIT_SPLIT_US_US_US]]:4096; CHECK-NEXT:    br label %[[INNER_HEADER_US_US_US:.*]]4097;4098; CHECK:       [[INNER_HEADER_US_US_US]]:4099; CHECK-NEXT:    br label %[[INNER_BODY1_US_US_US:.*]]4100;4101; CHECK:       [[INNER_BODY1_US_US_US]]:4102; CHECK-NEXT:    %[[A:.*]] = call i32 @a()4103; CHECK-NEXT:    br label %[[INNER_LATCH_US_US_US:.*]]4104;4105; CHECK:       [[INNER_LATCH_US_US_US]]:4106; CHECK-NEXT:    %[[PHI_A:.*]] = phi i32 [ %[[A]], %[[INNER_BODY1_US_US_US]] ]4107; CHECK-NEXT:    call void @sink1(i32 0)4108; CHECK-NEXT:    call void @sink1(i32 0)4109; CHECK-NEXT:    call void @sink1(i32 0)4110; CHECK-NEXT:    call void @sink1(i32 0)4111; CHECK-NEXT:    call void @sink1(i32 0)4112; CHECK-NEXT:    call void @sink1(i32 0)4113; CHECK-NEXT:    call void @sink1(i32 0)4114; CHECK-NEXT:    call void @sink1(i32 0)4115; CHECK-NEXT:    call void @sink1(i32 0)4116; CHECK-NEXT:    call void @sink1(i32 0)4117; CHECK-NEXT:    call void @sink1(i32 %[[PHI_A]])4118; CHECK-NEXT:    %[[INNER_COND_US_US_US:.*]] = call i1 @cond()4119; CHECK-NEXT:    br i1 %[[INNER_COND_US_US_US]], label %[[INNER_HEADER_US_US_US]], label %[[INNER_LOOPEXIT2_SPLIT_US_US_US:.*]]4120;4121; CHECK:       [[INNER_LOOPEXIT2_SPLIT_US_US_US]]:4122; CHECK-NEXT:    br label %[[INNER_LOOPEXIT2_US_US]]4123;4124; CHECK:       [[EXIT_SPLIT_US_SPLIT_US]]:4125; CHECK-NEXT:    br label %[[EXIT_SPLIT_US:.*]]4126 4127 4128inner.body2:4129  %b = call i32 @b()4130  br label %inner.latch4131; The fully unswitched loop around `@b`.4132;4133; CHECK:       [[ENTRY_SPLIT_US_SPLIT]]:4134; CHECK-NEXT:    br label %[[OUTER_HEADER_US:.*]]4135;4136; CHECK:       [[OUTER_HEADER_US]]:4137; CHECK-NEXT:    br label %[[OUTER_HEADER_SPLIT_US:.*]]4138;4139; CHECK:       [[INNER_HEADER_US:.*]]:4140; CHECK-NEXT:    br label %[[INNER_BODY2_US:.*]]4141;4142; CHECK:       [[INNER_BODY2_US]]:4143; CHECK-NEXT:    %[[B:.*]] = call i32 @b()4144; CHECK-NEXT:    br label %[[INNER_LATCH_US:.*]]4145;4146; CHECK:       [[INNER_LATCH_US]]:4147; CHECK-NEXT:    call void @sink1(i32 0)4148; CHECK-NEXT:    call void @sink1(i32 0)4149; CHECK-NEXT:    call void @sink1(i32 0)4150; CHECK-NEXT:    call void @sink1(i32 0)4151; CHECK-NEXT:    call void @sink1(i32 0)4152; CHECK-NEXT:    call void @sink1(i32 0)4153; CHECK-NEXT:    call void @sink1(i32 0)4154; CHECK-NEXT:    call void @sink1(i32 0)4155; CHECK-NEXT:    call void @sink1(i32 0)4156; CHECK-NEXT:    call void @sink1(i32 0)4157; CHECK-NEXT:    call void @sink1(i32 %[[B]])4158; CHECK-NEXT:    %[[INNER_COND_US:.*]] = call i1 @cond()4159; CHECK-NEXT:    br i1 %[[INNER_COND_US]], label %[[INNER_HEADER_US]], label %[[INNER_LOOPEXIT2_SPLIT_US:.*]]4160;4161; CHECK:       [[INNER_LOOPEXIT2_SPLIT_US]]:4162; CHECK-NEXT:    br label %[[INNER_LOOPEXIT2_US:.*]]4163;4164; CHECK:       [[OUTER_LATCH_US:.*]]:4165; CHECK-NEXT:    %[[OUTER_COND_US:.*]] = call i1 @cond()4166; CHECK-NEXT:    br i1 %[[OUTER_COND_US]], label %[[OUTER_HEADER_US]], label %[[EXIT_SPLIT_US_SPLIT:.*]]4167;4168; CHECK:       [[OUTER_HEADER_SPLIT_US]]:4169; CHECK-NEXT:    br label %[[OUTER_HEADER_SPLIT_SPLIT_US:.*]]4170;4171; CHECK:       [[OUTER_HEADER_SPLIT_SPLIT_US]]:4172; CHECK-NEXT:    br label %[[INNER_HEADER_US]]4173;4174; CHECK:       [[INNER_LOOPEXIT2_US]]:4175; CHECK-NEXT:    br label %[[OUTER_LATCH_US]]4176;4177; CHECK:       [[EXIT_SPLIT_US]]:4178; CHECK-NEXT:    br label %exit4179 4180inner.latch:4181  %phi = phi i32 [ %a, %inner.body1 ], [ %b, %inner.body2 ]4182  ; Make 10 junk calls here to ensure we're over the "50" cost threshold of4183  ; non-trivial unswitching for this inner switch.4184  call void @sink1(i32 0)4185  call void @sink1(i32 0)4186  call void @sink1(i32 0)4187  call void @sink1(i32 0)4188  call void @sink1(i32 0)4189  call void @sink1(i32 0)4190  call void @sink1(i32 0)4191  call void @sink1(i32 0)4192  call void @sink1(i32 0)4193  call void @sink1(i32 0)4194  call void @sink1(i32 %phi)4195  %inner.cond = call i1 @cond()4196  br i1 %inner.cond, label %inner.header, label %inner.loopexit24197 4198inner.loopexit1:4199  br label %outer.latch4200; The unswitched `loopexit1` path.4201;4202; CHECK:       [[ENTRY_SPLIT]]:4203; CHECK-NEXT:    br label %[[OUTER_HEADER:.*]]4204;4205; CHECK:       outer.header:4206; CHECK-NEXT:    br label %inner.loopexit14207;4208; CHECK:       inner.loopexit1:4209; CHECK-NEXT:    br label %outer.latch4210;4211; CHECK:       outer.latch:4212; CHECK-NEXT:    %outer.cond = call i1 @cond()4213; CHECK-NEXT:    br i1 %outer.cond, label %outer.header, label %[[EXIT_SPLIT:.*]]4214;4215; CHECK:       [[EXIT_SPLIT]]:4216; CHECK-NEXT:    br label %exit4217 4218inner.loopexit2:4219  br label %outer.latch4220 4221outer.latch:4222  %outer.cond = call i1 @cond()4223  br i1 %outer.cond, label %outer.header, label %exit4224 4225exit:4226  ret void4227; CHECK:       exit:4228; CHECK-NEXT:    ret void4229}4230 4231; Non-trivial partial loop unswitching of multiple invariant inputs to an `and`4232; chain (select version).4233define i32 @test32(ptr %ptr1, ptr %ptr2, ptr %ptr3, i1 %cond1, i1 %cond2) {4234; CHECK-LABEL: @test32(4235entry:4236  br label %loop_begin4237; CHECK-NEXT:  entry:4238; CHECK-NEXT:    [[C2_FR:%.+]] = freeze i1 %cond24239; CHECK-NEXT:    [[C1_FR:%.+]] = freeze i1 %cond14240; CHECK-NEXT:    %[[INV_AND:.*]] = and i1 [[C2_FR]], [[C1_FR]]4241; CHECK-NEXT:    br i1 %[[INV_AND]], label %entry.split, label %entry.split.us4242 4243loop_begin:4244  %v1 = load i1, ptr %ptr14245  %v2 = load i1, ptr %ptr24246  %cond_and1 = select i1 %v1, i1 %cond1, i1 false4247  %cond_and2 = select i1 %cond_and1, i1 %cond2, i1 false4248  br i1 %cond_and2, label %loop_a, label %loop_b4249; The 'loop_b' unswitched loop.4250;4251; CHECK:       entry.split.us:4252; CHECK-NEXT:    br label %loop_begin.us4253;4254; CHECK:       loop_begin.us:4255; CHECK-NEXT:    %[[V2_US]] = load i1, ptr %ptr2, align 14256; CHECK-NEXT:    br label %loop_b.us4257;4258; CHECK:       loop_b.us:4259; CHECK-NEXT:    call i32 @b()4260; CHECK-NEXT:    br label %latch.us4261;4262; CHECK:       latch.us:4263; CHECK-NEXT:    %[[V3_US:.*]] = load i1, ptr %ptr3, align 14264; CHECK-NEXT:    br i1 %[[V3_US]], label %loop_begin.us, label %loop_exit.split.us4265;4266; CHECK:       loop_exit.split.us:4267; CHECK-NEXT:    br label %loop_exit4268 4269; The original loop.4270;4271; CHECK:       entry.split:4272; CHECK-NEXT:    br label %loop_begin4273;4274; CHECK:       loop_begin:4275; CHECK-NEXT:    %[[V1:.*]] = load i1, ptr %ptr14276; CHECK-NEXT:    %[[V2:.*]] = load i1, ptr %ptr24277; CHECK-NEXT:    %[[AND1:.*]] = select i1 %[[V1]], i1 true, i1 false4278; CHECK-NEXT:    %[[AND2:.*]] = select i1 %[[AND1]], i1 true, i1 false4279; CHECK-NEXT:    br i1 %[[AND2]], label %loop_a, label %loop_b4280 4281loop_a:4282  call i32 @a()4283  br label %latch4284; CHECK:       loop_a:4285; CHECK-NEXT:    call i32 @a()4286; CHECK-NEXT:    br label %latch4287 4288loop_b:4289  call i32 @b()4290  br label %latch4291; CHECK:       loop_b:4292; CHECK-NEXT:    call i32 @b()4293; CHECK-NEXT:    br label %latch4294 4295latch:4296  %v3 = load i1, ptr %ptr34297  br i1 %v3, label %loop_begin, label %loop_exit4298; CHECK:       latch:4299; CHECK-NEXT:    %[[V3:.*]] = load i1, ptr %ptr3, align 14300; CHECK-NEXT:    br i1 %[[V3]], label %loop_begin, label %loop_exit.split4301 4302loop_exit:4303  ret i32 04304; CHECK:       loop_exit.split:4305; CHECK-NEXT:    br label %loop_exit4306;4307; CHECK:       loop_exit:4308; CHECK-NEXT:    ret4309}4310 4311; Non-trivial partial loop unswitching of multiple invariant inputs to an `or`4312; chain (select version).4313define i32 @test33(ptr %ptr1, ptr %ptr2, ptr %ptr3, i1 %cond1, i1 %cond2) {4314; CHECK-LABEL: @test33(4315entry:4316  br label %loop_begin4317; CHECK-NEXT:  entry:4318; CHECK-NEXT:    [[C2_FR:%.+]] = freeze i1 %cond24319; CHECK-NEXT:    [[C1_FR:%.+]] = freeze i1 %cond14320; CHECK-NEXT:    %[[INV_OR:.*]] = or i1 [[C2_FR]], [[C1_FR]]4321; CHECK-NEXT:    br i1 %[[INV_OR]], label %entry.split.us, label %entry.split4322 4323loop_begin:4324  %v1 = load i1, ptr %ptr14325  %v2 = load i1, ptr %ptr24326  %cond_and1 = select i1 %v1, i1 true, i1 %cond14327  %cond_and2 = select i1 %cond_and1, i1 true, i1 %cond24328  br i1 %cond_and2, label %loop_b, label %loop_a4329; The 'loop_b' unswitched loop.4330;4331; CHECK:       entry.split.us:4332; CHECK-NEXT:    br label %loop_begin.us4333;4334; CHECK:       loop_begin.us:4335; CHECK-NEXT:    %[[V2_US]] = load i1, ptr %ptr2, align 14336; CHECK-NEXT:    br label %loop_b.us4337;4338; CHECK:       loop_b.us:4339; CHECK-NEXT:    call i32 @b()4340; CHECK-NEXT:    br label %latch.us4341;4342; CHECK:       latch.us:4343; CHECK-NEXT:    %[[V3_US:.*]] = load i1, ptr %ptr3, align 14344; CHECK-NEXT:    br i1 %[[V3_US]], label %loop_begin.us, label %loop_exit.split.us4345;4346; CHECK:       loop_exit.split.us:4347; CHECK-NEXT:    br label %loop_exit4348 4349; The original loop.4350;4351; CHECK:       entry.split:4352; CHECK-NEXT:    br label %loop_begin4353;4354; CHECK:       loop_begin:4355; CHECK-NEXT:    %[[V1:.*]] = load i1, ptr %ptr14356; CHECK-NEXT:    %[[V2:.*]] = load i1, ptr %ptr24357; CHECK-NEXT:    %[[AND1:.*]] = select i1 %[[V1]], i1 true, i1 false4358; CHECK-NEXT:    %[[AND2:.*]] = select i1 %[[AND1]], i1 true, i1 false4359; CHECK-NEXT:    br i1 %[[AND2]], label %loop_b, label %loop_a4360 4361loop_a:4362  call i32 @a()4363  br label %latch4364; CHECK:       loop_a:4365; CHECK-NEXT:    call i32 @a()4366; CHECK-NEXT:    br label %latch4367 4368loop_b:4369  call i32 @b()4370  br label %latch4371; CHECK:       loop_b:4372; CHECK-NEXT:    call i32 @b()4373; CHECK-NEXT:    br label %latch4374 4375latch:4376  %v3 = load i1, ptr %ptr34377  br i1 %v3, label %loop_begin, label %loop_exit4378; CHECK:       latch:4379; CHECK-NEXT:    %[[V3:.*]] = load i1, ptr %ptr3, align 14380; CHECK-NEXT:    br i1 %[[V3]], label %loop_begin, label %loop_exit.split4381 4382loop_exit:4383  ret i32 04384; CHECK:       loop_exit.split:4385; CHECK-NEXT:    br label %loop_exit4386;4387; CHECK:       loop_exit:4388; CHECK-NEXT:    ret4389}4390