brintos

brintos / llvm-project-archived public Read only

0
0
Text · 90.9 KiB · 8e97cb5 Raw
2365 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -freeze-loop-unswitch-cond -passes='loop(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s3; RUN: opt -freeze-loop-unswitch-cond -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S -verify-memoryssa < %s | FileCheck %s4 5declare i32 @a()6declare i32 @b()7declare i32 @c()8declare i32 @d()9 10declare void @sink1(i32)11declare void @sink2(i32)12declare void @sink3(i1)13declare void @sink4(i1)14 15declare i1 @cond()16declare i32 @cond.i32()17 18declare i32 @__CxxFrameHandler3(...)19 20define i32 @test1_freeze(ptr %ptr0, ptr %ptr1, ptr %ptr2) {21; CHECK-LABEL: @test1_freeze(22; CHECK-NEXT:  entry:23; CHECK-NEXT:    [[COND1:%.*]] = load i1, ptr [[PTR1:%.*]], align 124; CHECK-NEXT:    [[COND2:%.*]] = load i1, ptr [[PTR2:%.*]], align 125; CHECK-NEXT:    br i1 [[COND1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]26; CHECK:       entry.split.us:27; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]28; CHECK:       loop_begin.us:29; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]30; CHECK:       loop_a.us:31; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @a()32; CHECK-NEXT:    br label [[LATCH_US:%.*]]33; CHECK:       latch.us:34; CHECK-NEXT:    [[V_US:%.*]] = load i1, ptr [[PTR0:%.*]], align 135; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]36; CHECK:       loop_exit.split.us:37; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]38; CHECK:       entry.split:39; CHECK-NEXT:    [[COND2_FR:%.*]] = freeze i1 [[COND2]]40; CHECK-NEXT:    br i1 [[COND2_FR]], label [[ENTRY_SPLIT_SPLIT_US:%.*]], label [[ENTRY_SPLIT_SPLIT:%.*]]41; CHECK:       entry.split.split.us:42; CHECK-NEXT:    br label [[LOOP_BEGIN_US1:%.*]]43; CHECK:       loop_begin.us1:44; CHECK-NEXT:    br label [[LOOP_B_US:%.*]]45; CHECK:       loop_b.us:46; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @b()47; CHECK-NEXT:    br label [[LOOP_B_A_US:%.*]]48; CHECK:       loop_b_a.us:49; CHECK-NEXT:    call void @sink3(i1 true)50; CHECK-NEXT:    br label [[LATCH_US2:%.*]]51; CHECK:       latch.us2:52; CHECK-NEXT:    [[V_US3:%.*]] = load i1, ptr [[PTR0]], align 153; CHECK-NEXT:    br i1 [[V_US3]], label [[LOOP_BEGIN_US1]], label [[LOOP_EXIT_SPLIT_SPLIT_US:%.*]]54; CHECK:       loop_exit.split.split.us:55; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT:%.*]]56; CHECK:       entry.split.split:57; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]58; CHECK:       loop_begin:59; CHECK-NEXT:    br label [[LOOP_B:%.*]]60; CHECK:       loop_b:61; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @b()62; CHECK-NEXT:    br label [[LOOP_B_B:%.*]]63; CHECK:       loop_b_b:64; CHECK-NEXT:    call void @sink4(i1 false)65; CHECK-NEXT:    br label [[LATCH:%.*]]66; CHECK:       latch:67; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR0]], align 168; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT_SPLIT:%.*]]69; CHECK:       loop_exit.split.split:70; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]71; CHECK:       loop_exit.split:72; CHECK-NEXT:    br label [[LOOP_EXIT]]73; CHECK:       loop_exit:74; CHECK-NEXT:    ret i32 075;76entry:77  %cond1 = load i1, ptr %ptr178  %cond2 = load i1, ptr %ptr279  br label %loop_begin80 81loop_begin:82  br i1 %cond1, label %loop_a, label %loop_b83 84loop_a:85  call i32 @a()86  br label %latch87; The 'loop_a' unswitched loop.88 89loop_b:90  call i32 @b()91  br i1 %cond2, label %loop_b_a, label %loop_b_b92; The second unswitched condition.93 94loop_b_a:95  call void @sink3(i1 %cond2)96  br label %latch97; The 'loop_b_a' unswitched loop.98; %cond2 is replaced to true99 100loop_b_b:101  call void @sink4(i1 %cond2)102  br label %latch103; The 'loop_b_b' unswitched loop.104; %cond2 is replaced to false105 106latch:107  %v = load i1, ptr %ptr0108  br i1 %v, label %loop_begin, label %loop_exit109 110loop_exit:111  ret i32 0112}113 114; Test that when unswitching a deeply nested loop condition in a way that115; produces a non-loop clone that can reach multiple exit blocks which are part116; of different outer loops we correctly divide the cloned loop blocks between117; the outer loops based on reachability.118define i32 @test7a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {119; CHECK-LABEL: @test7a(120; CHECK-NEXT:  entry:121; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]122; CHECK:       loop_begin:123; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4124; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]125; CHECK:       inner_loop_begin:126; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]127; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 1128; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 4129; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]130; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]131; CHECK:       inner_loop_begin.split.us:132; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]133; CHECK:       inner_inner_loop_begin.us:134; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1135; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]136; CHECK:       inner_inner_loop_b.us:137; CHECK-NEXT:    [[V3_US:%.*]] = load i1, ptr [[PTR]], align 1138; CHECK-NEXT:    br i1 [[V3_US]], label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US_LOOPEXIT:%.*]]139; CHECK:       inner_inner_loop_a.us:140; CHECK-NEXT:    [[A_PHI_LCSSA10:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_BEGIN_US]] ]141; CHECK-NEXT:    [[B_LCSSA6:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_BEGIN_US]] ]142; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 1143; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US:%.*]]144; CHECK:       inner_inner_loop_c.us.loopexit:145; CHECK-NEXT:    br label [[INNER_INNER_LOOP_C_US]]146; CHECK:       inner_inner_loop_c.us:147; CHECK-NEXT:    [[V4_US:%.*]] = load i1, ptr [[PTR]], align 1148; CHECK-NEXT:    br i1 [[V4_US]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_D_US:%.*]]149; CHECK:       inner_inner_loop_d.us:150; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US]]151; CHECK:       inner_inner_loop_exit.split.us:152; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]153; CHECK:       loop_exit.split.us:154; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_PHI_LCSSA10]], [[INNER_INNER_LOOP_A_US]] ]155; CHECK-NEXT:    [[B_LCSSA_US:%.*]] = phi i32 [ [[B_LCSSA6]], [[INNER_INNER_LOOP_A_US]] ]156; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]157; CHECK:       inner_loop_exit.loopexit.split.us:158; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]159; CHECK:       inner_loop_begin.split:160; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]161; CHECK:       inner_inner_loop_begin:162; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 1163; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]164; CHECK:       inner_inner_loop_a:165; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1166; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C:%.*]]167; CHECK:       inner_inner_loop_b:168; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 1169; CHECK-NEXT:    br i1 [[V3]], label [[INNER_INNER_LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C]]170; CHECK:       inner_inner_loop_c:171; CHECK-NEXT:    [[V4:%.*]] = load i1, ptr [[PTR]], align 1172; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_D:%.*]]173; CHECK:       inner_inner_loop_d:174; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN]]175; CHECK:       inner_inner_loop_exit.split:176; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]177; CHECK:       inner_inner_loop_exit:178; CHECK-NEXT:    [[A2]] = load i32, ptr [[A_PTR]], align 4179; CHECK-NEXT:    [[V5:%.*]] = load i1, ptr [[PTR]], align 1180; CHECK-NEXT:    br i1 [[V5]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]181; CHECK:       inner_loop_exit.loopexit.split:182; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]183; CHECK:       inner_loop_exit.loopexit:184; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]185; CHECK:       inner_loop_exit.loopexit1:186; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]187; CHECK:       inner_loop_exit:188; CHECK-NEXT:    br label [[LOOP_BEGIN]]189; CHECK:       loop_exit.split:190; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A]] ]191; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_A]] ]192; CHECK-NEXT:    br label [[LOOP_EXIT]]193; CHECK:       loop_exit:194; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]195; CHECK-NEXT:    [[DOTUS_PHI2:%.*]] = phi i32 [ [[B_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[B_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]196; CHECK-NEXT:    [[RESULT:%.*]] = add i32 [[DOTUS_PHI]], [[DOTUS_PHI2]]197; CHECK-NEXT:    ret i32 [[RESULT]]198;199entry:200  br label %loop_begin201 202loop_begin:203  %a = load i32, ptr %a.ptr204  br label %inner_loop_begin205 206inner_loop_begin:207  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]208  %cond = load i1, ptr %cond.ptr209  %b = load i32, ptr %b.ptr210  br label %inner_inner_loop_begin211 212inner_inner_loop_begin:213  %v1 = load i1, ptr %ptr214  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b215 216inner_inner_loop_a:217  %v2 = load i1, ptr %ptr218  br i1 %v2, label %loop_exit, label %inner_inner_loop_c219 220inner_inner_loop_b:221  %v3 = load i1, ptr %ptr222  br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c223 224inner_inner_loop_c:225  %v4 = load i1, ptr %ptr226  br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d227 228inner_inner_loop_d:229  br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_begin230; The cloned copy that always exits with the adjustments required to fix up231; loop exits.232; The original copy that continues to loop.233 234inner_inner_loop_exit:235  %a2 = load i32, ptr %a.ptr236  %v5 = load i1, ptr %ptr237  br i1 %v5, label %inner_loop_exit, label %inner_loop_begin238 239inner_loop_exit:240  br label %loop_begin241 242loop_exit:243  %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ]244  %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ]245  %result = add i32 %a.lcssa, %b.lcssa246  ret i32 %result247}248 249; Same pattern as @test7a but here the original loop becomes a non-loop that250; can reach multiple exit blocks which are part of different outer loops.251define i32 @test7b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {252; CHECK-LABEL: @test7b(253; CHECK-NEXT:  entry:254; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]255; CHECK:       loop_begin:256; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4257; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]258; CHECK:       inner_loop_begin:259; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]260; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 1261; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 4262; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]263; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]264; CHECK:       inner_loop_begin.split.us:265; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]266; CHECK:       inner_inner_loop_begin.us:267; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1268; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]269; CHECK:       inner_inner_loop_b.us:270; CHECK-NEXT:    [[V3_US:%.*]] = load i1, ptr [[PTR]], align 1271; CHECK-NEXT:    br i1 [[V3_US]], label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US:%.*]]272; CHECK:       inner_inner_loop_a.us:273; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 1274; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_C_US]]275; CHECK:       inner_inner_loop_c.us:276; CHECK-NEXT:    [[V4_US:%.*]] = load i1, ptr [[PTR]], align 1277; CHECK-NEXT:    br i1 [[V4_US]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_D_US:%.*]]278; CHECK:       inner_inner_loop_d.us:279; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US]]280; CHECK:       inner_inner_loop_exit.split.us:281; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]282; CHECK:       loop_exit.split.us:283; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A_US]] ]284; CHECK-NEXT:    [[B_LCSSA_US:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_A_US]] ]285; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]286; CHECK:       inner_loop_exit.loopexit.split.us:287; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]288; CHECK:       inner_loop_begin.split:289; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]290; CHECK:       inner_inner_loop_begin:291; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 1292; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]293; CHECK:       inner_inner_loop_a:294; CHECK-NEXT:    [[A_PHI_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_BEGIN]] ]295; CHECK-NEXT:    [[B_LCSSA3:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_BEGIN]] ]296; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1297; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C:%.*]]298; CHECK:       inner_inner_loop_b:299; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 1300; CHECK-NEXT:    br i1 [[V3]], label [[INNER_INNER_LOOP_EXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_C_LOOPEXIT:%.*]]301; CHECK:       inner_inner_loop_c.loopexit:302; CHECK-NEXT:    br label [[INNER_INNER_LOOP_C]]303; CHECK:       inner_inner_loop_c:304; CHECK-NEXT:    [[V4:%.*]] = load i1, ptr [[PTR]], align 1305; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]], label [[INNER_INNER_LOOP_D:%.*]]306; CHECK:       inner_inner_loop_d:307; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT]]308; CHECK:       inner_inner_loop_exit.split:309; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]310; CHECK:       inner_inner_loop_exit:311; CHECK-NEXT:    [[A2]] = load i32, ptr [[A_PTR]], align 4312; CHECK-NEXT:    [[V5:%.*]] = load i1, ptr [[PTR]], align 1313; CHECK-NEXT:    br i1 [[V5]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]314; CHECK:       inner_loop_exit.loopexit.split:315; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]316; CHECK:       inner_loop_exit.loopexit:317; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]318; CHECK:       inner_loop_exit.loopexit1:319; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]320; CHECK:       inner_loop_exit:321; CHECK-NEXT:    br label [[LOOP_BEGIN]]322; CHECK:       loop_exit.split:323; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI_LCSSA]], [[INNER_INNER_LOOP_A]] ]324; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B_LCSSA3]], [[INNER_INNER_LOOP_A]] ]325; CHECK-NEXT:    br label [[LOOP_EXIT]]326; CHECK:       loop_exit:327; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]328; CHECK-NEXT:    [[DOTUS_PHI2:%.*]] = phi i32 [ [[B_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[B_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]329; CHECK-NEXT:    [[RESULT:%.*]] = add i32 [[DOTUS_PHI]], [[DOTUS_PHI2]]330; CHECK-NEXT:    ret i32 [[RESULT]]331;332entry:333  br label %loop_begin334 335loop_begin:336  %a = load i32, ptr %a.ptr337  br label %inner_loop_begin338 339inner_loop_begin:340  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]341  %cond = load i1, ptr %cond.ptr342  %b = load i32, ptr %b.ptr343  br label %inner_inner_loop_begin344 345inner_inner_loop_begin:346  %v1 = load i1, ptr %ptr347  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b348 349inner_inner_loop_a:350  %v2 = load i1, ptr %ptr351  br i1 %v2, label %loop_exit, label %inner_inner_loop_c352 353inner_inner_loop_b:354  %v3 = load i1, ptr %ptr355  br i1 %v3, label %inner_inner_loop_exit, label %inner_inner_loop_c356 357inner_inner_loop_c:358  %v4 = load i1, ptr %ptr359  br i1 %v4, label %inner_loop_exit, label %inner_inner_loop_d360 361inner_inner_loop_d:362  br i1 %cond, label %inner_inner_loop_begin, label %inner_loop_exit363; The cloned copy that continues looping.364; The original copy that now always exits and needs adjustments for exit365; blocks.366 367inner_inner_loop_exit:368  %a2 = load i32, ptr %a.ptr369  %v5 = load i1, ptr %ptr370  br i1 %v5, label %inner_loop_exit, label %inner_loop_begin371 372inner_loop_exit:373  br label %loop_begin374 375loop_exit:376  %a.lcssa = phi i32 [ %a.phi, %inner_inner_loop_a ]377  %b.lcssa = phi i32 [ %b, %inner_inner_loop_a ]378  %result = add i32 %a.lcssa, %b.lcssa379  ret i32 %result380}381 382; Test that when the exit block set of an inner loop changes to start at a less383; high level of the loop nest we correctly hoist the loop up the nest.384define i32 @test8a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {385; CHECK-LABEL: @test8a(386; CHECK-NEXT:  entry:387; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]388; CHECK:       loop_begin:389; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4390; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]391; CHECK:       inner_loop_begin:392; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]393; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 1394; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 4395; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]396; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]397; CHECK:       inner_loop_begin.split.us:398; CHECK-NEXT:    [[A_PHI_LCSSA4:%.*]] = phi i32 [ [[A_PHI]], [[INNER_LOOP_BEGIN]] ]399; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]400; CHECK:       inner_inner_loop_begin.us:401; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1402; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]403; CHECK:       inner_inner_loop_b.us:404; CHECK-NEXT:    br label [[INNER_INNER_LOOP_LATCH_US:%.*]]405; CHECK:       inner_inner_loop_a.us:406; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 1407; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_INNER_LOOP_LATCH_US]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]408; CHECK:       inner_inner_loop_latch.us:409; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US]]410; CHECK:       inner_loop_exit.loopexit.split.us:411; CHECK-NEXT:    [[A_PHI_LCSSA2_US:%.*]] = phi i32 [ [[A_PHI_LCSSA4]], [[INNER_INNER_LOOP_A_US]] ]412; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]413; CHECK:       inner_loop_begin.split:414; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]415; CHECK:       inner_inner_loop_begin:416; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 1417; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]418; CHECK:       inner_inner_loop_a:419; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1420; CHECK-NEXT:    br i1 [[V2]], label [[INNER_INNER_LOOP_LATCH:%.*]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]]421; CHECK:       inner_inner_loop_b:422; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]423; CHECK:       inner_inner_loop_latch:424; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN]]425; CHECK:       inner_inner_loop_exit:426; CHECK-NEXT:    [[A2]] = load i32, ptr [[A_PTR]], align 4427; CHECK-NEXT:    [[V4:%.*]] = load i1, ptr [[PTR]], align 1428; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]429; CHECK:       inner_loop_exit.loopexit.split:430; CHECK-NEXT:    [[A_PHI_LCSSA2:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A]] ]431; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]432; CHECK:       inner_loop_exit.loopexit:433; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_PHI_LCSSA2]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT]] ], [ [[A_PHI_LCSSA2_US]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US]] ]434; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]435; CHECK:       inner_loop_exit.loopexit1:436; CHECK-NEXT:    [[A_PHI_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_EXIT]] ]437; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]438; CHECK:       inner_loop_exit:439; CHECK-NEXT:    [[A_PHI3:%.*]] = phi i32 [ [[A_PHI_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ], [ [[DOTUS_PHI]], [[INNER_LOOP_EXIT_LOOPEXIT]] ]440; CHECK-NEXT:    [[V5:%.*]] = load i1, ptr [[PTR]], align 1441; CHECK-NEXT:    br i1 [[V5]], label [[LOOP_EXIT:%.*]], label [[LOOP_BEGIN]]442; CHECK:       loop_exit:443; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI3]], [[INNER_LOOP_EXIT]] ]444; CHECK-NEXT:    ret i32 [[A_LCSSA]]445;446entry:447  br label %loop_begin448 449loop_begin:450  %a = load i32, ptr %a.ptr451  br label %inner_loop_begin452 453inner_loop_begin:454  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]455  %cond = load i1, ptr %cond.ptr456  %b = load i32, ptr %b.ptr457  br label %inner_inner_loop_begin458 459inner_inner_loop_begin:460  %v1 = load i1, ptr %ptr461  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b462 463inner_inner_loop_a:464  %v2 = load i1, ptr %ptr465  br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit466 467inner_inner_loop_b:468  br i1 %cond, label %inner_inner_loop_latch, label %inner_inner_loop_exit469 470inner_inner_loop_latch:471  br label %inner_inner_loop_begin472; The cloned region is now an exit from the inner loop.473; The original region exits the loop earlier.474 475inner_inner_loop_exit:476  %a2 = load i32, ptr %a.ptr477  %v4 = load i1, ptr %ptr478  br i1 %v4, label %inner_loop_exit, label %inner_loop_begin479 480inner_loop_exit:481  %v5 = load i1, ptr %ptr482  br i1 %v5, label %loop_exit, label %loop_begin483 484loop_exit:485  %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ]486  ret i32 %a.lcssa487}488 489; Same pattern as @test8a but where the original loop looses an exit block and490; needs to be hoisted up the nest.491define i32 @test8b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {492; CHECK-LABEL: @test8b(493; CHECK-NEXT:  entry:494; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]495; CHECK:       loop_begin:496; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4497; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]498; CHECK:       inner_loop_begin:499; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ], [ [[A2:%.*]], [[INNER_INNER_LOOP_EXIT:%.*]] ]500; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 1501; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 4502; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]503; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_BEGIN_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_SPLIT:%.*]]504; CHECK:       inner_loop_begin.split.us:505; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]506; CHECK:       inner_inner_loop_begin.us:507; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1508; CHECK-NEXT:    br i1 [[V1_US]], label [[INNER_INNER_LOOP_A_US:%.*]], label [[INNER_INNER_LOOP_B_US:%.*]]509; CHECK:       inner_inner_loop_b.us:510; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]]511; CHECK:       inner_inner_loop_a.us:512; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 1513; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_INNER_LOOP_LATCH_US:%.*]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]514; CHECK:       inner_inner_loop_latch.us:515; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US]]516; CHECK:       inner_inner_loop_exit.split.us:517; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT]]518; CHECK:       inner_loop_exit.loopexit.split.us:519; CHECK-NEXT:    [[A_PHI_LCSSA2_US:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_A_US]] ]520; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]521; CHECK:       inner_loop_begin.split:522; CHECK-NEXT:    [[A_PHI_LCSSA4:%.*]] = phi i32 [ [[A_PHI]], [[INNER_LOOP_BEGIN]] ]523; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]524; CHECK:       inner_inner_loop_begin:525; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 1526; CHECK-NEXT:    br i1 [[V1]], label [[INNER_INNER_LOOP_A:%.*]], label [[INNER_INNER_LOOP_B:%.*]]527; CHECK:       inner_inner_loop_a:528; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1529; CHECK-NEXT:    br i1 [[V2]], label [[INNER_INNER_LOOP_LATCH:%.*]], label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT:%.*]]530; CHECK:       inner_inner_loop_b:531; CHECK-NEXT:    br label [[INNER_INNER_LOOP_LATCH]]532; CHECK:       inner_inner_loop_latch:533; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN]]534; CHECK:       inner_inner_loop_exit:535; CHECK-NEXT:    [[A2]] = load i32, ptr [[A_PTR]], align 4536; CHECK-NEXT:    [[V4:%.*]] = load i1, ptr [[PTR]], align 1537; CHECK-NEXT:    br i1 [[V4]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]], label [[INNER_LOOP_BEGIN]]538; CHECK:       inner_loop_exit.loopexit.split:539; CHECK-NEXT:    [[A_PHI_LCSSA2:%.*]] = phi i32 [ [[A_PHI_LCSSA4]], [[INNER_INNER_LOOP_A]] ]540; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT]]541; CHECK:       inner_loop_exit.loopexit:542; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_PHI_LCSSA2]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT]] ], [ [[A_PHI_LCSSA2_US]], [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US]] ]543; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]544; CHECK:       inner_loop_exit.loopexit1:545; CHECK-NEXT:    [[A_PHI_LCSSA:%.*]] = phi i32 [ [[A_PHI]], [[INNER_INNER_LOOP_EXIT]] ]546; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]547; CHECK:       inner_loop_exit:548; CHECK-NEXT:    [[A_PHI3:%.*]] = phi i32 [ [[A_PHI_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ], [ [[DOTUS_PHI]], [[INNER_LOOP_EXIT_LOOPEXIT]] ]549; CHECK-NEXT:    [[V5:%.*]] = load i1, ptr [[PTR]], align 1550; CHECK-NEXT:    br i1 [[V5]], label [[LOOP_EXIT:%.*]], label [[LOOP_BEGIN]]551; CHECK:       loop_exit:552; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_PHI3]], [[INNER_LOOP_EXIT]] ]553; CHECK-NEXT:    ret i32 [[A_LCSSA]]554;555entry:556  br label %loop_begin557 558loop_begin:559  %a = load i32, ptr %a.ptr560  br label %inner_loop_begin561 562inner_loop_begin:563  %a.phi = phi i32 [ %a, %loop_begin ], [ %a2, %inner_inner_loop_exit ]564  %cond = load i1, ptr %cond.ptr565  %b = load i32, ptr %b.ptr566  br label %inner_inner_loop_begin567 568inner_inner_loop_begin:569  %v1 = load i1, ptr %ptr570  br i1 %v1, label %inner_inner_loop_a, label %inner_inner_loop_b571 572inner_inner_loop_a:573  %v2 = load i1, ptr %ptr574  br i1 %v2, label %inner_inner_loop_latch, label %inner_loop_exit575 576inner_inner_loop_b:577  br i1 %cond, label %inner_inner_loop_exit, label %inner_inner_loop_latch578 579inner_inner_loop_latch:580  br label %inner_inner_loop_begin581; The cloned region is similar to before but with one earlier exit.582; The original region is now an exit in the preheader.583 584inner_inner_loop_exit:585  %a2 = load i32, ptr %a.ptr586  %v4 = load i1, ptr %ptr587  br i1 %v4, label %inner_loop_exit, label %inner_loop_begin588 589inner_loop_exit:590  %v5 = load i1, ptr %ptr591  br i1 %v5, label %loop_exit, label %loop_begin592 593loop_exit:594  %a.lcssa = phi i32 [ %a.phi, %inner_loop_exit ]595  ret i32 %a.lcssa596}597 598; Test that requires re-forming dedicated exits for the cloned loop.599define i32 @test10a(ptr %ptr, i1 %cond, ptr %a.ptr) {600; CHECK-LABEL: @test10a(601; CHECK-NEXT:  entry:602; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]603; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]604; CHECK:       entry.split.us:605; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]606; CHECK:       loop_begin.us:607; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4608; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1609; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]610; CHECK:       loop_b.us:611; CHECK-NEXT:    [[A_US_LCSSA:%.*]] = phi i32 [ [[A_US]], [[LOOP_BEGIN_US]] ]612; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US:%.*]]613; CHECK:       loop_a.us:614; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 1615; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US_LOOPEXIT:%.*]], label [[LOOP_BEGIN_BACKEDGE_US:%.*]]616; CHECK:       loop_begin.backedge.us:617; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]618; CHECK:       loop_exit.split.us.loopexit:619; CHECK-NEXT:    [[A_LCSSA_US_PH:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]620; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US]]621; CHECK:       loop_exit.split.us:622; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_US_LCSSA]], [[LOOP_B_US]] ], [ [[A_LCSSA_US_PH]], [[LOOP_EXIT_SPLIT_US_LOOPEXIT]] ]623; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]624; CHECK:       entry.split:625; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]626; CHECK:       loop_begin:627; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4628; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 1629; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]630; CHECK:       loop_a:631; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1632; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[LOOP_BEGIN_BACKEDGE:%.*]]633; CHECK:       loop_begin.backedge:634; CHECK-NEXT:    br label [[LOOP_BEGIN]]635; CHECK:       loop_b:636; CHECK-NEXT:    br label [[LOOP_BEGIN_BACKEDGE]]637; CHECK:       loop_exit.split:638; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]639; CHECK-NEXT:    br label [[LOOP_EXIT]]640; CHECK:       loop_exit:641; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]642; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]643;644entry:645  br label %loop_begin646 647loop_begin:648  %a = load i32, ptr %a.ptr649  %v1 = load i1, ptr %ptr650  br i1 %v1, label %loop_a, label %loop_b651 652loop_a:653  %v2 = load i1, ptr %ptr654  br i1 %v2, label %loop_exit, label %loop_begin655 656loop_b:657  br i1 %cond, label %loop_exit, label %loop_begin658; The cloned loop with one edge as a direct exit.659 660; The original loop without one 'loop_exit' edge.661 662loop_exit:663  %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ]664  ret i32 %a.lcssa665}666 667; Test that requires re-forming dedicated exits for the original loop.668define i32 @test10b(ptr %ptr, i1 %cond, ptr %a.ptr) {669; CHECK-LABEL: @test10b(670; CHECK-NEXT:  entry:671; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]672; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]673; CHECK:       entry.split.us:674; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]675; CHECK:       loop_begin.us:676; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4677; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1678; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]679; CHECK:       loop_b.us:680; CHECK-NEXT:    br label [[LOOP_BEGIN_BACKEDGE_US:%.*]]681; CHECK:       loop_a.us:682; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 1683; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_BEGIN_BACKEDGE_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]684; CHECK:       loop_begin.backedge.us:685; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]686; CHECK:       loop_exit.split.us:687; CHECK-NEXT:    [[A_LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]688; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]689; CHECK:       entry.split:690; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]691; CHECK:       loop_begin:692; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4693; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 1694; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]695; CHECK:       loop_a:696; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1697; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_BEGIN_BACKEDGE:%.*]], label [[LOOP_EXIT_SPLIT_LOOPEXIT:%.*]]698; CHECK:       loop_begin.backedge:699; CHECK-NEXT:    br label [[LOOP_BEGIN]]700; CHECK:       loop_b:701; CHECK-NEXT:    [[A_LCSSA1:%.*]] = phi i32 [ [[A]], [[LOOP_BEGIN]] ]702; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT:%.*]]703; CHECK:       loop_exit.split.loopexit:704; CHECK-NEXT:    [[A_LCSSA_PH:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]705; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]706; CHECK:       loop_exit.split:707; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_LCSSA1]], [[LOOP_B]] ], [ [[A_LCSSA_PH]], [[LOOP_EXIT_SPLIT_LOOPEXIT]] ]708; CHECK-NEXT:    br label [[LOOP_EXIT]]709; CHECK:       loop_exit:710; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[A_LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[A_LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]711; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]712;713entry:714  br label %loop_begin715 716loop_begin:717  %a = load i32, ptr %a.ptr718  %v1 = load i1, ptr %ptr719  br i1 %v1, label %loop_a, label %loop_b720 721loop_a:722  %v2 = load i1, ptr %ptr723  br i1 %v2, label %loop_begin, label %loop_exit724 725loop_b:726  br i1 %cond, label %loop_begin, label %loop_exit727; The cloned loop without one of the exits.728 729; The original loop without one 'loop_exit' edge.730 731loop_exit:732  %a.lcssa = phi i32 [ %a, %loop_a ], [ %a, %loop_b ]733  ret i32 %a.lcssa734}735 736; Check that if a cloned inner loop after unswitching doesn't loop and directly737; exits even an outer loop, we don't add the cloned preheader to the outer738; loop and do add the needed LCSSA phi nodes for the new exit block from the739; outer loop.740define i32 @test11a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {741; CHECK-LABEL: @test11a(742; CHECK-NEXT:  entry:743; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]744; CHECK:       loop_begin:745; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 4746; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 1747; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_LATCH:%.*]], label [[INNER_LOOP_PH:%.*]]748; CHECK:       inner_loop_ph:749; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 1750; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]751; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_LOOP_PH_SPLIT:%.*]]752; CHECK:       inner_loop_ph.split.us:753; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_LOOP_PH]] ]754; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN_US:%.*]]755; CHECK:       inner_loop_begin.us:756; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])757; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4758; CHECK-NEXT:    br label [[LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]759; CHECK:       loop_exit.loopexit.split.us:760; CHECK-NEXT:    [[A_LCSSA2_US:%.*]] = phi i32 [ [[A_US]], [[INNER_LOOP_BEGIN_US]] ]761; CHECK-NEXT:    br label [[LOOP_EXIT_LOOPEXIT:%.*]]762; CHECK:       inner_loop_ph.split:763; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]764; CHECK:       inner_loop_begin:765; CHECK-NEXT:    call void @sink1(i32 [[B]])766; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4767; CHECK-NEXT:    br label [[INNER_LOOP_A:%.*]]768; CHECK:       inner_loop_a:769; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1770; CHECK-NEXT:    br i1 [[V2]], label [[INNER_LOOP_EXIT:%.*]], label [[INNER_LOOP_BEGIN]]771; CHECK:       inner_loop_exit:772; CHECK-NEXT:    [[A_INNER_LCSSA:%.*]] = phi i32 [ [[A]], [[INNER_LOOP_A]] ]773; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 1774; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_LATCH]], label [[LOOP_EXIT_LOOPEXIT1:%.*]]775; CHECK:       loop_latch:776; CHECK-NEXT:    br label [[LOOP_BEGIN]]777; CHECK:       loop_exit.loopexit:778; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]779; CHECK:       loop_exit.loopexit1:780; CHECK-NEXT:    [[A_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA]], [[INNER_LOOP_EXIT]] ]781; CHECK-NEXT:    br label [[LOOP_EXIT]]782; CHECK:       loop_exit:783; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2_US]], [[LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_LCSSA_LCSSA]], [[LOOP_EXIT_LOOPEXIT1]] ]784; CHECK-NEXT:    ret i32 [[A_LCSSA]]785;786entry:787  br label %loop_begin788 789loop_begin:790  %b = load i32, ptr %b.ptr791  %v1 = load i1, ptr %ptr792  br i1 %v1, label %loop_latch, label %inner_loop_ph793 794inner_loop_ph:795  %cond = load i1, ptr %cond.ptr796  br label %inner_loop_begin797 798inner_loop_begin:799  call void @sink1(i32 %b)800  %a = load i32, ptr %a.ptr801  br i1 %cond, label %loop_exit, label %inner_loop_a802 803inner_loop_a:804  %v2 = load i1, ptr %ptr805  br i1 %v2, label %inner_loop_exit, label %inner_loop_begin806; The cloned path doesn't actually loop and is an exit from the outer loop as807; well.808; The original remains a loop losing the exit edge.809 810inner_loop_exit:811  %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ]812  %v3 = load i1, ptr %ptr813  br i1 %v3, label %loop_latch, label %loop_exit814 815loop_latch:816  br label %loop_begin817 818loop_exit:819  %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ]820  ret i32 %a.lcssa821}822 823; Check that if the original inner loop after unswitching doesn't loop and824; directly exits even an outer loop, we remove the original preheader from the825; outer loop and add needed LCSSA phi nodes for the new exit block from the826; outer loop.827define i32 @test11b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {828; CHECK-LABEL: @test11b(829; CHECK-NEXT:  entry:830; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]831; CHECK:       loop_begin:832; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 4833; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 1834; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_LATCH:%.*]], label [[INNER_LOOP_PH:%.*]]835; CHECK:       inner_loop_ph:836; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 1837; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]838; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_LOOP_PH_SPLIT:%.*]]839; CHECK:       inner_loop_ph.split.us:840; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN_US:%.*]]841; CHECK:       inner_loop_begin.us:842; CHECK-NEXT:    call void @sink1(i32 [[B]])843; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4844; CHECK-NEXT:    br label [[INNER_LOOP_A_US:%.*]]845; CHECK:       inner_loop_a.us:846; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 1847; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_LOOP_BEGIN_US]]848; CHECK:       inner_loop_exit.split.us:849; CHECK-NEXT:    [[A_INNER_LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[INNER_LOOP_A_US]] ]850; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]851; CHECK:       inner_loop_ph.split:852; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_LOOP_PH]] ]853; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]854; CHECK:       inner_loop_begin:855; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])856; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4857; CHECK-NEXT:    br label [[LOOP_EXIT_LOOPEXIT:%.*]]858; CHECK:       inner_loop_exit:859; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 1860; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_LATCH]], label [[LOOP_EXIT_LOOPEXIT1:%.*]]861; CHECK:       loop_latch:862; CHECK-NEXT:    br label [[LOOP_BEGIN]]863; CHECK:       loop_exit.loopexit:864; CHECK-NEXT:    [[A_LCSSA2:%.*]] = phi i32 [ [[A]], [[INNER_LOOP_BEGIN]] ]865; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]866; CHECK:       loop_exit.loopexit1:867; CHECK-NEXT:    [[A_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA_US]], [[INNER_LOOP_EXIT]] ]868; CHECK-NEXT:    br label [[LOOP_EXIT]]869; CHECK:       loop_exit:870; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2]], [[LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_LCSSA_LCSSA]], [[LOOP_EXIT_LOOPEXIT1]] ]871; CHECK-NEXT:    ret i32 [[A_LCSSA]]872;873entry:874  br label %loop_begin875 876loop_begin:877  %b = load i32, ptr %b.ptr878  %v1 = load i1, ptr %ptr879  br i1 %v1, label %loop_latch, label %inner_loop_ph880 881inner_loop_ph:882  %cond = load i1, ptr %cond.ptr883  br label %inner_loop_begin884 885inner_loop_begin:886  call void @sink1(i32 %b)887  %a = load i32, ptr %a.ptr888  br i1 %cond, label %inner_loop_a, label %loop_exit889 890inner_loop_a:891  %v2 = load i1, ptr %ptr892  br i1 %v2, label %inner_loop_exit, label %inner_loop_begin893; The cloned path continues to loop without the exit out of the entire nest.894; The original remains a loop losing the exit edge.895 896inner_loop_exit:897  %a.inner_lcssa = phi i32 [ %a, %inner_loop_a ]898  %v3 = load i1, ptr %ptr899  br i1 %v3, label %loop_latch, label %loop_exit900 901loop_latch:902  br label %loop_begin903 904loop_exit:905  %a.lcssa = phi i32 [ %a, %inner_loop_begin ], [ %a.inner_lcssa, %inner_loop_exit ]906  ret i32 %a.lcssa907}908 909; Like test11a, but checking that when the whole thing is wrapped in yet910; another loop, we correctly attribute the cloned preheader to that outermost911; loop rather than only handling the case where the preheader is not in any loop912; at all.913define i32 @test12a(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {914; CHECK-LABEL: @test12a(915; CHECK-NEXT:  entry:916; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]917; CHECK:       loop_begin:918; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]919; CHECK:       inner_loop_begin:920; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 4921; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 1922; CHECK-NEXT:    br i1 [[V1]], label [[INNER_LOOP_LATCH:%.*]], label [[INNER_INNER_LOOP_PH:%.*]]923; CHECK:       inner_inner_loop_ph:924; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 1925; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]926; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_PH_SPLIT:%.*]]927; CHECK:       inner_inner_loop_ph.split.us:928; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_PH]] ]929; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]930; CHECK:       inner_inner_loop_begin.us:931; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])932; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 4933; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT_SPLIT_US:%.*]]934; CHECK:       inner_loop_exit.loopexit.split.us:935; CHECK-NEXT:    [[A_LCSSA2_US:%.*]] = phi i32 [ [[A_US]], [[INNER_INNER_LOOP_BEGIN_US]] ]936; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]937; CHECK:       inner_inner_loop_ph.split:938; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]939; CHECK:       inner_inner_loop_begin:940; CHECK-NEXT:    call void @sink1(i32 [[B]])941; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 4942; CHECK-NEXT:    br label [[INNER_INNER_LOOP_A:%.*]]943; CHECK:       inner_inner_loop_a:944; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1945; CHECK-NEXT:    br i1 [[V2]], label [[INNER_INNER_LOOP_EXIT:%.*]], label [[INNER_INNER_LOOP_BEGIN]]946; CHECK:       inner_inner_loop_exit:947; CHECK-NEXT:    [[A_INNER_INNER_LCSSA:%.*]] = phi i32 [ [[A]], [[INNER_INNER_LOOP_A]] ]948; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 1949; CHECK-NEXT:    br i1 [[V3]], label [[INNER_LOOP_LATCH]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]]950; CHECK:       inner_loop_latch:951; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN]]952; CHECK:       inner_loop_exit.loopexit:953; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]954; CHECK:       inner_loop_exit.loopexit1:955; CHECK-NEXT:    [[A_INNER_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_INNER_LCSSA]], [[INNER_INNER_LOOP_EXIT]] ]956; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]957; CHECK:       inner_loop_exit:958; CHECK-NEXT:    [[A_INNER_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2_US]], [[INNER_LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_INNER_LCSSA_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ]959; CHECK-NEXT:    [[V4:%.*]] = load i1, ptr [[PTR]], align 1960; CHECK-NEXT:    br i1 [[V4]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]961; CHECK:       loop_exit:962; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA]], [[INNER_LOOP_EXIT]] ]963; CHECK-NEXT:    ret i32 [[A_LCSSA]]964;965entry:966  br label %loop_begin967 968loop_begin:969  br label %inner_loop_begin970 971inner_loop_begin:972  %b = load i32, ptr %b.ptr973  %v1 = load i1, ptr %ptr974  br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph975 976inner_inner_loop_ph:977  %cond = load i1, ptr %cond.ptr978  br label %inner_inner_loop_begin979 980inner_inner_loop_begin:981  call void @sink1(i32 %b)982  %a = load i32, ptr %a.ptr983  br i1 %cond, label %inner_loop_exit, label %inner_inner_loop_a984 985inner_inner_loop_a:986  %v2 = load i1, ptr %ptr987  br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin988; The cloned path doesn't actually loop and is an exit from the outer loop as989; well.990; The original remains a loop losing the exit edge.991 992inner_inner_loop_exit:993  %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ]994  %v3 = load i1, ptr %ptr995  br i1 %v3, label %inner_loop_latch, label %inner_loop_exit996 997inner_loop_latch:998  br label %inner_loop_begin999 1000inner_loop_exit:1001  %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ]1002  %v4 = load i1, ptr %ptr1003  br i1 %v4, label %loop_begin, label %loop_exit1004 1005loop_exit:1006  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]1007  ret i32 %a.lcssa1008}1009 1010; Like test11b, but checking that when the whole thing is wrapped in yet1011; another loop, we correctly sink the preheader to the outermost loop rather1012; than only handling the case where the preheader is completely removed from1013; a loop.1014define i32 @test12b(ptr %ptr, ptr %cond.ptr, ptr %a.ptr, ptr %b.ptr) {1015; CHECK-LABEL: @test12b(1016; CHECK-NEXT:  entry:1017; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]1018; CHECK:       loop_begin:1019; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN:%.*]]1020; CHECK:       inner_loop_begin:1021; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 41022; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 11023; CHECK-NEXT:    br i1 [[V1]], label [[INNER_LOOP_LATCH:%.*]], label [[INNER_INNER_LOOP_PH:%.*]]1024; CHECK:       inner_inner_loop_ph:1025; CHECK-NEXT:    [[COND:%.*]] = load i1, ptr [[COND_PTR:%.*]], align 11026; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND]]1027; CHECK-NEXT:    br i1 [[COND_FR]], label [[INNER_INNER_LOOP_PH_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_PH_SPLIT:%.*]]1028; CHECK:       inner_inner_loop_ph.split.us:1029; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN_US:%.*]]1030; CHECK:       inner_inner_loop_begin.us:1031; CHECK-NEXT:    call void @sink1(i32 [[B]])1032; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 41033; CHECK-NEXT:    br label [[INNER_INNER_LOOP_A_US:%.*]]1034; CHECK:       inner_inner_loop_a.us:1035; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 11036; CHECK-NEXT:    br i1 [[V2_US]], label [[INNER_INNER_LOOP_EXIT_SPLIT_US:%.*]], label [[INNER_INNER_LOOP_BEGIN_US]]1037; CHECK:       inner_inner_loop_exit.split.us:1038; CHECK-NEXT:    [[A_INNER_INNER_LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[INNER_INNER_LOOP_A_US]] ]1039; CHECK-NEXT:    br label [[INNER_INNER_LOOP_EXIT:%.*]]1040; CHECK:       inner_inner_loop_ph.split:1041; CHECK-NEXT:    [[B_LCSSA:%.*]] = phi i32 [ [[B]], [[INNER_INNER_LOOP_PH]] ]1042; CHECK-NEXT:    br label [[INNER_INNER_LOOP_BEGIN:%.*]]1043; CHECK:       inner_inner_loop_begin:1044; CHECK-NEXT:    call void @sink1(i32 [[B_LCSSA]])1045; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 41046; CHECK-NEXT:    br label [[INNER_LOOP_EXIT_LOOPEXIT:%.*]]1047; CHECK:       inner_inner_loop_exit:1048; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 11049; CHECK-NEXT:    br i1 [[V3]], label [[INNER_LOOP_LATCH]], label [[INNER_LOOP_EXIT_LOOPEXIT1:%.*]]1050; CHECK:       inner_loop_latch:1051; CHECK-NEXT:    br label [[INNER_LOOP_BEGIN]]1052; CHECK:       inner_loop_exit.loopexit:1053; CHECK-NEXT:    [[A_LCSSA2:%.*]] = phi i32 [ [[A]], [[INNER_INNER_LOOP_BEGIN]] ]1054; CHECK-NEXT:    br label [[INNER_LOOP_EXIT:%.*]]1055; CHECK:       inner_loop_exit.loopexit1:1056; CHECK-NEXT:    [[A_INNER_INNER_LCSSA_LCSSA:%.*]] = phi i32 [ [[A_INNER_INNER_LCSSA_US]], [[INNER_INNER_LOOP_EXIT]] ]1057; CHECK-NEXT:    br label [[INNER_LOOP_EXIT]]1058; CHECK:       inner_loop_exit:1059; CHECK-NEXT:    [[A_INNER_LCSSA:%.*]] = phi i32 [ [[A_LCSSA2]], [[INNER_LOOP_EXIT_LOOPEXIT]] ], [ [[A_INNER_INNER_LCSSA_LCSSA]], [[INNER_LOOP_EXIT_LOOPEXIT1]] ]1060; CHECK-NEXT:    [[V4:%.*]] = load i1, ptr [[PTR]], align 11061; CHECK-NEXT:    br i1 [[V4]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]1062; CHECK:       loop_exit:1063; CHECK-NEXT:    [[A_LCSSA:%.*]] = phi i32 [ [[A_INNER_LCSSA]], [[INNER_LOOP_EXIT]] ]1064; CHECK-NEXT:    ret i32 [[A_LCSSA]]1065;1066entry:1067  br label %loop_begin1068 1069loop_begin:1070  br label %inner_loop_begin1071 1072inner_loop_begin:1073  %b = load i32, ptr %b.ptr1074  %v1 = load i1, ptr %ptr1075  br i1 %v1, label %inner_loop_latch, label %inner_inner_loop_ph1076 1077inner_inner_loop_ph:1078  %cond = load i1, ptr %cond.ptr1079  br label %inner_inner_loop_begin1080 1081inner_inner_loop_begin:1082  call void @sink1(i32 %b)1083  %a = load i32, ptr %a.ptr1084  br i1 %cond, label %inner_inner_loop_a, label %inner_loop_exit1085 1086inner_inner_loop_a:1087  %v2 = load i1, ptr %ptr1088  br i1 %v2, label %inner_inner_loop_exit, label %inner_inner_loop_begin1089; The cloned path continues to loop without the exit out of the entire nest.1090; The original remains a loop losing the exit edge.1091 1092inner_inner_loop_exit:1093  %a.inner_inner_lcssa = phi i32 [ %a, %inner_inner_loop_a ]1094  %v3 = load i1, ptr %ptr1095  br i1 %v3, label %inner_loop_latch, label %inner_loop_exit1096 1097inner_loop_latch:1098  br label %inner_loop_begin1099 1100inner_loop_exit:1101  %a.inner_lcssa = phi i32 [ %a, %inner_inner_loop_begin ], [ %a.inner_inner_lcssa, %inner_inner_loop_exit ]1102  %v4 = load i1, ptr %ptr1103  br i1 %v4, label %loop_begin, label %loop_exit1104 1105loop_exit:1106  %a.lcssa = phi i32 [ %a.inner_lcssa, %inner_loop_exit ]1107  ret i32 %a.lcssa1108}1109 1110; Test where the cloned loop has an inner loop that has to be traversed to form1111; the cloned loop, and where this inner loop has multiple blocks, and where the1112; exiting block that connects the inner loop to the cloned loop is not the header1113; block. This ensures that we correctly handle interesting corner cases of1114; traversing back to the header when establishing the cloned loop.1115define i32 @test13a(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) {1116; CHECK-LABEL: @test13a(1117; CHECK-NEXT:  entry:1118; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]1119; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]1120; CHECK:       entry.split.us:1121; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]1122; CHECK:       loop_begin.us:1123; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 41124; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 11125; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]1126; CHECK:       loop_b.us:1127; CHECK-NEXT:    [[B_US:%.*]] = load i32, ptr [[B_PTR:%.*]], align 41128; CHECK-NEXT:    br label [[LOOP_B_INNER_PH_US:%.*]]1129; CHECK:       loop_b_inner_ph.us:1130; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER_US:%.*]]1131; CHECK:       loop_b_inner_header.us:1132; CHECK-NEXT:    [[V3_US:%.*]] = load i1, ptr [[PTR]], align 11133; CHECK-NEXT:    br i1 [[V3_US]], label [[LOOP_B_INNER_LATCH_US:%.*]], label [[LOOP_B_INNER_BODY_US:%.*]]1134; CHECK:       loop_b_inner_body.us:1135; CHECK-NEXT:    [[V4_US:%.*]] = load i1, ptr [[PTR]], align 11136; CHECK-NEXT:    br i1 [[V4_US]], label [[LOOP_B_INNER_LATCH_US]], label [[LOOP_B_INNER_EXIT_US:%.*]]1137; CHECK:       loop_b_inner_exit.us:1138; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]1139; CHECK:       loop_b_inner_latch.us:1140; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER_US]]1141; CHECK:       loop_a.us:1142; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 11143; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US:%.*]], label [[LOOP_LATCH_US]]1144; CHECK:       loop_latch.us:1145; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]1146; CHECK:       loop_exit.split.us:1147; CHECK-NEXT:    [[LCSSA_US:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]1148; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]1149; CHECK:       entry.split:1150; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]1151; CHECK:       loop_begin:1152; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 41153; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 11154; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]1155; CHECK:       loop_a:1156; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 11157; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT_LOOPEXIT:%.*]], label [[LOOP_LATCH:%.*]]1158; CHECK:       loop_b:1159; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR]], align 41160; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT:%.*]]1161; CHECK:       loop_latch:1162; CHECK-NEXT:    br label [[LOOP_BEGIN]]1163; CHECK:       loop_exit.split.loopexit:1164; CHECK-NEXT:    [[LCSSA_PH:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]1165; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]1166; CHECK:       loop_exit.split:1167; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ [[B]], [[LOOP_B]] ], [ [[LCSSA_PH]], [[LOOP_EXIT_SPLIT_LOOPEXIT]] ]1168; CHECK-NEXT:    br label [[LOOP_EXIT]]1169; CHECK:       loop_exit:1170; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]1171; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]1172;1173entry:1174  br label %loop_begin1175 1176loop_begin:1177  %a = load i32, ptr %a.ptr1178  %v1 = load i1, ptr %ptr1179  br i1 %v1, label %loop_a, label %loop_b1180 1181loop_a:1182  %v2 = load i1, ptr %ptr1183  br i1 %v2, label %loop_exit, label %loop_latch1184 1185loop_b:1186  %b = load i32, ptr %b.ptr1187  br i1 %cond, label %loop_b_inner_ph, label %loop_exit1188 1189loop_b_inner_ph:1190  br label %loop_b_inner_header1191 1192loop_b_inner_header:1193  %v3 = load i1, ptr %ptr1194  br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body1195 1196loop_b_inner_body:1197  %v4 = load i1, ptr %ptr1198  br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit1199 1200loop_b_inner_latch:1201  br label %loop_b_inner_header1202 1203loop_b_inner_exit:1204  br label %loop_latch1205 1206loop_latch:1207  br label %loop_begin1208; The cloned loop contains an inner loop within it.1209; And the original loop no longer contains an inner loop.1210 1211loop_exit:1212  %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ]1213  ret i32 %lcssa1214}1215 1216; Test where the original loop has an inner loop that has to be traversed to1217; rebuild the loop, and where this inner loop has multiple blocks, and where1218; the exiting block that connects the inner loop to the original loop is not1219; the header block. This ensures that we correctly handle interesting corner1220; cases of traversing back to the header when re-establishing the original loop1221; still exists after unswitching.1222define i32 @test13b(ptr %ptr, i1 %cond, ptr %a.ptr, ptr %b.ptr) {1223; CHECK-LABEL: @test13b(1224; CHECK-NEXT:  entry:1225; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]1226; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]1227; CHECK:       entry.split.us:1228; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]1229; CHECK:       loop_begin.us:1230; CHECK-NEXT:    [[A_US:%.*]] = load i32, ptr [[A_PTR:%.*]], align 41231; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 11232; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_US:%.*]], label [[LOOP_B_US:%.*]]1233; CHECK:       loop_b.us:1234; CHECK-NEXT:    [[B_US:%.*]] = load i32, ptr [[B_PTR:%.*]], align 41235; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US:%.*]]1236; CHECK:       loop_a.us:1237; CHECK-NEXT:    [[V2_US:%.*]] = load i1, ptr [[PTR]], align 11238; CHECK-NEXT:    br i1 [[V2_US]], label [[LOOP_EXIT_SPLIT_US_LOOPEXIT:%.*]], label [[LOOP_LATCH_US:%.*]]1239; CHECK:       loop_latch.us:1240; CHECK-NEXT:    br label [[LOOP_BEGIN_US]]1241; CHECK:       loop_exit.split.us.loopexit:1242; CHECK-NEXT:    [[LCSSA_US_PH:%.*]] = phi i32 [ [[A_US]], [[LOOP_A_US]] ]1243; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT_US]]1244; CHECK:       loop_exit.split.us:1245; CHECK-NEXT:    [[LCSSA_US:%.*]] = phi i32 [ [[B_US]], [[LOOP_B_US]] ], [ [[LCSSA_US_PH]], [[LOOP_EXIT_SPLIT_US_LOOPEXIT]] ]1246; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]1247; CHECK:       entry.split:1248; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]1249; CHECK:       loop_begin:1250; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[A_PTR]], align 41251; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR]], align 11252; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]1253; CHECK:       loop_a:1254; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 11255; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[LOOP_LATCH:%.*]]1256; CHECK:       loop_b:1257; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[B_PTR]], align 41258; CHECK-NEXT:    br label [[LOOP_B_INNER_PH:%.*]]1259; CHECK:       loop_b_inner_ph:1260; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER:%.*]]1261; CHECK:       loop_b_inner_header:1262; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 11263; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_B_INNER_LATCH:%.*]], label [[LOOP_B_INNER_BODY:%.*]]1264; CHECK:       loop_b_inner_body:1265; CHECK-NEXT:    [[V4:%.*]] = load i1, ptr [[PTR]], align 11266; CHECK-NEXT:    br i1 [[V4]], label [[LOOP_B_INNER_LATCH]], label [[LOOP_B_INNER_EXIT:%.*]]1267; CHECK:       loop_b_inner_latch:1268; CHECK-NEXT:    br label [[LOOP_B_INNER_HEADER]]1269; CHECK:       loop_b_inner_exit:1270; CHECK-NEXT:    br label [[LOOP_LATCH]]1271; CHECK:       loop_latch:1272; CHECK-NEXT:    br label [[LOOP_BEGIN]]1273; CHECK:       loop_exit.split:1274; CHECK-NEXT:    [[LCSSA:%.*]] = phi i32 [ [[A]], [[LOOP_A]] ]1275; CHECK-NEXT:    br label [[LOOP_EXIT]]1276; CHECK:       loop_exit:1277; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[LCSSA]], [[LOOP_EXIT_SPLIT]] ], [ [[LCSSA_US]], [[LOOP_EXIT_SPLIT_US]] ]1278; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]1279;1280entry:1281  br label %loop_begin1282 1283loop_begin:1284  %a = load i32, ptr %a.ptr1285  %v1 = load i1, ptr %ptr1286  br i1 %v1, label %loop_a, label %loop_b1287 1288loop_a:1289  %v2 = load i1, ptr %ptr1290  br i1 %v2, label %loop_exit, label %loop_latch1291 1292loop_b:1293  %b = load i32, ptr %b.ptr1294  br i1 %cond, label %loop_exit, label %loop_b_inner_ph1295 1296loop_b_inner_ph:1297  br label %loop_b_inner_header1298 1299loop_b_inner_header:1300  %v3 = load i1, ptr %ptr1301  br i1 %v3, label %loop_b_inner_latch, label %loop_b_inner_body1302 1303loop_b_inner_body:1304  %v4 = load i1, ptr %ptr1305  br i1 %v4, label %loop_b_inner_latch, label %loop_b_inner_exit1306 1307loop_b_inner_latch:1308  br label %loop_b_inner_header1309 1310loop_b_inner_exit:1311  br label %loop_latch1312 1313loop_latch:1314  br label %loop_begin1315; The cloned loop doesn't contain an inner loop.1316; But the original loop contains an inner loop that must be traversed.;1317 1318loop_exit:1319  %lcssa = phi i32 [ %a, %loop_a ], [ %b, %loop_b ]1320  ret i32 %lcssa1321}1322 1323; A test reduced out of 400.perlbench that when unswitching the `%stop`1324; condition clones a loop nest outside of a containing loop. This excercises a1325; different cloning path from our other test cases and in turn verifying the1326; resulting structure can catch any failures to correctly clone these nested1327; loops.1328declare void @f()1329declare void @g()1330declare i32 @h(i32 %arg)1331 1332; Test that when we are unswitching and need to rebuild the loop block set we1333; correctly skip past inner loops. We want to use the inner loop to efficiently1334; skip whole subregions of the outer loop blocks but just because the header of1335; the outer loop is also the preheader of an inner loop shouldn't confuse this1336; walk.1337define void @test23(i1 %arg, ptr %ptr) {1338; CHECK-LABEL: @test23(1339; CHECK-NEXT:  entry:1340; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze i1 [[ARG:%.*]]1341; CHECK-NEXT:    br i1 [[ARG_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]1342; CHECK:       entry.split.us:1343; CHECK-NEXT:    br label [[OUTER_HEADER_US:%.*]]1344; CHECK:       outer.header.us:1345; CHECK-NEXT:    br label [[INNER_HEADER_US:%.*]]1346; CHECK:       inner.header.us:1347; CHECK-NEXT:    call void @f()1348; CHECK-NEXT:    br label [[INNER_LATCH_US:%.*]]1349; CHECK:       inner.latch.us:1350; CHECK-NEXT:    [[INNER_COND_US:%.*]] = load i1, ptr [[PTR:%.*]], align 11351; CHECK-NEXT:    br i1 [[INNER_COND_US]], label [[INNER_HEADER_US]], label [[OUTER_BODY_US:%.*]]1352; CHECK:       outer.body.us:1353; CHECK-NEXT:    br label [[OUTER_BODY_LEFT_US:%.*]]1354; CHECK:       outer.body.left.us:1355; CHECK-NEXT:    call void @f()1356; CHECK-NEXT:    br label [[OUTER_LATCH_US:%.*]]1357; CHECK:       outer.latch.us:1358; CHECK-NEXT:    [[OUTER_COND_US:%.*]] = load i1, ptr [[PTR]], align 11359; CHECK-NEXT:    br i1 [[OUTER_COND_US]], label [[OUTER_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]1360; CHECK:       exit.split.us:1361; CHECK-NEXT:    br label [[EXIT:%.*]]1362; CHECK:       entry.split:1363; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]1364; CHECK:       outer.header:1365; CHECK-NEXT:    br label [[INNER_HEADER:%.*]]1366; CHECK:       inner.header:1367; CHECK-NEXT:    call void @f()1368; CHECK-NEXT:    br label [[INNER_LATCH:%.*]]1369; CHECK:       inner.latch:1370; CHECK-NEXT:    [[INNER_COND:%.*]] = load i1, ptr [[PTR]], align 11371; CHECK-NEXT:    br i1 [[INNER_COND]], label [[INNER_HEADER]], label [[OUTER_BODY:%.*]]1372; CHECK:       outer.body:1373; CHECK-NEXT:    br label [[OUTER_BODY_RIGHT:%.*]]1374; CHECK:       outer.body.right:1375; CHECK-NEXT:    call void @g()1376; CHECK-NEXT:    br label [[OUTER_LATCH:%.*]]1377; CHECK:       outer.latch:1378; CHECK-NEXT:    [[OUTER_COND:%.*]] = load i1, ptr [[PTR]], align 11379; CHECK-NEXT:    br i1 [[OUTER_COND]], label [[OUTER_HEADER]], label [[EXIT_SPLIT:%.*]]1380; CHECK:       exit.split:1381; CHECK-NEXT:    br label [[EXIT]]1382; CHECK:       exit:1383; CHECK-NEXT:    ret void1384;1385entry:1386  br label %outer.header1387; Just verify that we unswitched the correct bits. We should call `@f` twice in1388; one unswitch and `@f` and then `@g` in the other.1389 1390outer.header:1391  br label %inner.header1392 1393inner.header:1394  call void @f()1395  br label %inner.latch1396 1397inner.latch:1398  %inner.cond = load i1, ptr %ptr1399  br i1 %inner.cond, label %inner.header, label %outer.body1400 1401outer.body:1402  br i1 %arg, label %outer.body.left, label %outer.body.right1403 1404outer.body.left:1405  call void @f()1406  br label %outer.latch1407 1408outer.body.right:1409  call void @g()1410  br label %outer.latch1411 1412outer.latch:1413  %outer.cond = load i1, ptr %ptr1414  br i1 %outer.cond, label %outer.header, label %exit1415 1416exit:1417  ret void1418}1419 1420; A test case designed to exercise unusual properties of switches: they1421; can introduce multiple edges to successors. These need lots of special case1422; handling as they get collapsed in many cases (domtree, the unswitch itself)1423; but not in all cases (the PHI node operands).1424define i32 @test29(i32 %arg) {1425; CHECK-LABEL: @test29(1426; CHECK-NEXT:  entry:1427; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze i32 [[ARG:%.*]]1428; CHECK-NEXT:    switch i32 [[ARG_FR]], label [[ENTRY_SPLIT:%.*]] [1429; CHECK-NEXT:    i32 0, label [[ENTRY_SPLIT_US:%.*]]1430; CHECK-NEXT:    i32 1, label [[ENTRY_SPLIT_US]]1431; CHECK-NEXT:    i32 2, label [[ENTRY_SPLIT_US1:%.*]]1432; CHECK-NEXT:    i32 3, label [[ENTRY_SPLIT]]1433; CHECK-NEXT:    ]1434; CHECK:       entry.split.us:1435; CHECK-NEXT:    br label [[HEADER_US:%.*]]1436; CHECK:       header.us:1437; CHECK-NEXT:    [[TMP_US:%.*]] = call i32 @d()1438; CHECK-NEXT:    [[CMP1_US:%.*]] = icmp eq i32 [[TMP_US]], 01439; CHECK-NEXT:    br i1 [[CMP1_US]], label [[BODY_A_US:%.*]], label [[DISPATCH_US:%.*]]1440; CHECK:       dispatch.us:1441; CHECK-NEXT:    br label [[BODY_A_US]]1442; CHECK:       body.a.us:1443; CHECK-NEXT:    [[TMP_A_PHI_US:%.*]] = phi i32 [ 0, [[HEADER_US]] ], [ [[TMP_US]], [[DISPATCH_US]] ]1444; CHECK-NEXT:    [[TMP_A_US:%.*]] = call i32 @a()1445; CHECK-NEXT:    [[TMP_A_SUM_US:%.*]] = add i32 [[TMP_A_PHI_US]], [[TMP_A_US]]1446; CHECK-NEXT:    br label [[BODY_B_US:%.*]]1447; CHECK:       body.b.us:1448; CHECK-NEXT:    [[TMP_B_PHI_US:%.*]] = phi i32 [ [[TMP_A_SUM_US]], [[BODY_A_US]] ]1449; CHECK-NEXT:    [[TMP_B_US:%.*]] = call i32 @b()1450; CHECK-NEXT:    [[TMP_B_SUM_US:%.*]] = add i32 [[TMP_B_PHI_US]], [[TMP_B_US]]1451; CHECK-NEXT:    br label [[BODY_C_US:%.*]]1452; CHECK:       body.c.us:1453; CHECK-NEXT:    [[TMP_C_PHI_US:%.*]] = phi i32 [ [[TMP_B_SUM_US]], [[BODY_B_US]] ]1454; CHECK-NEXT:    [[TMP_C_US:%.*]] = call i32 @c()1455; CHECK-NEXT:    [[TMP_C_SUM_US:%.*]] = add i32 [[TMP_C_PHI_US]], [[TMP_C_US]]1456; CHECK-NEXT:    br label [[LATCH_US:%.*]]1457; CHECK:       latch.us:1458; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp slt i32 [[TMP_C_SUM_US]], 421459; CHECK-NEXT:    br i1 [[CMP2_US]], label [[HEADER_US]], label [[EXIT_SPLIT_US:%.*]]1460; CHECK:       exit.split.us:1461; CHECK-NEXT:    [[LCSSA_PHI_US:%.*]] = phi i32 [ [[TMP_C_SUM_US]], [[LATCH_US]] ]1462; CHECK-NEXT:    br label [[EXIT:%.*]]1463; CHECK:       entry.split.us1:1464; CHECK-NEXT:    br label [[HEADER_US2:%.*]]1465; CHECK:       header.us2:1466; CHECK-NEXT:    [[TMP_US3:%.*]] = call i32 @d()1467; CHECK-NEXT:    [[CMP1_US4:%.*]] = icmp eq i32 [[TMP_US3]], 01468; CHECK-NEXT:    br i1 [[CMP1_US4]], label [[BODY_A_US6:%.*]], label [[DISPATCH_US5:%.*]]1469; CHECK:       dispatch.us5:1470; CHECK-NEXT:    br label [[BODY_B_US10:%.*]]1471; CHECK:       body.a.us6:1472; CHECK-NEXT:    [[TMP_A_PHI_US7:%.*]] = phi i32 [ 0, [[HEADER_US2]] ]1473; CHECK-NEXT:    [[TMP_A_US8:%.*]] = call i32 @a()1474; CHECK-NEXT:    [[TMP_A_SUM_US9:%.*]] = add i32 [[TMP_A_PHI_US7]], [[TMP_A_US8]]1475; CHECK-NEXT:    br label [[BODY_B_US10]]1476; CHECK:       body.b.us10:1477; CHECK-NEXT:    [[TMP_B_PHI_US11:%.*]] = phi i32 [ [[TMP_US3]], [[DISPATCH_US5]] ], [ [[TMP_A_SUM_US9]], [[BODY_A_US6]] ]1478; CHECK-NEXT:    [[TMP_B_US12:%.*]] = call i32 @b()1479; CHECK-NEXT:    [[TMP_B_SUM_US13:%.*]] = add i32 [[TMP_B_PHI_US11]], [[TMP_B_US12]]1480; CHECK-NEXT:    br label [[BODY_C_US14:%.*]]1481; CHECK:       body.c.us14:1482; CHECK-NEXT:    [[TMP_C_PHI_US15:%.*]] = phi i32 [ [[TMP_B_SUM_US13]], [[BODY_B_US10]] ]1483; CHECK-NEXT:    [[TMP_C_US16:%.*]] = call i32 @c()1484; CHECK-NEXT:    [[TMP_C_SUM_US17:%.*]] = add i32 [[TMP_C_PHI_US15]], [[TMP_C_US16]]1485; CHECK-NEXT:    br label [[LATCH_US18:%.*]]1486; CHECK:       latch.us18:1487; CHECK-NEXT:    [[CMP2_US19:%.*]] = icmp slt i32 [[TMP_C_SUM_US17]], 421488; CHECK-NEXT:    br i1 [[CMP2_US19]], label [[HEADER_US2]], label [[EXIT_SPLIT_SPLIT_US:%.*]]1489; CHECK:       exit.split.split.us:1490; CHECK-NEXT:    [[LCSSA_PHI_US20:%.*]] = phi i32 [ [[TMP_C_SUM_US17]], [[LATCH_US18]] ]1491; CHECK-NEXT:    br label [[EXIT_SPLIT:%.*]]1492; CHECK:       entry.split:1493; CHECK-NEXT:    br label [[HEADER:%.*]]1494; CHECK:       header:1495; CHECK-NEXT:    [[TMP:%.*]] = call i32 @d()1496; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP]], 01497; CHECK-NEXT:    br i1 [[CMP1]], label [[BODY_A:%.*]], label [[DISPATCH:%.*]]1498; CHECK:       dispatch:1499; CHECK-NEXT:    br label [[BODY_C:%.*]]1500; CHECK:       body.a:1501; CHECK-NEXT:    [[TMP_A_PHI:%.*]] = phi i32 [ 0, [[HEADER]] ]1502; CHECK-NEXT:    [[TMP_A:%.*]] = call i32 @a()1503; CHECK-NEXT:    [[TMP_A_SUM:%.*]] = add i32 [[TMP_A_PHI]], [[TMP_A]]1504; CHECK-NEXT:    br label [[BODY_B:%.*]]1505; CHECK:       body.b:1506; CHECK-NEXT:    [[TMP_B_PHI:%.*]] = phi i32 [ [[TMP_A_SUM]], [[BODY_A]] ]1507; CHECK-NEXT:    [[TMP_B:%.*]] = call i32 @b()1508; CHECK-NEXT:    [[TMP_B_SUM:%.*]] = add i32 [[TMP_B_PHI]], [[TMP_B]]1509; CHECK-NEXT:    br label [[BODY_C]]1510; CHECK:       body.c:1511; CHECK-NEXT:    [[TMP_C_PHI:%.*]] = phi i32 [ [[TMP]], [[DISPATCH]] ], [ [[TMP_B_SUM]], [[BODY_B]] ]1512; CHECK-NEXT:    [[TMP_C:%.*]] = call i32 @c()1513; CHECK-NEXT:    [[TMP_C_SUM:%.*]] = add i32 [[TMP_C_PHI]], [[TMP_C]]1514; CHECK-NEXT:    br label [[LATCH:%.*]]1515; CHECK:       latch:1516; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP_C_SUM]], 421517; CHECK-NEXT:    br i1 [[CMP2]], label [[HEADER]], label [[EXIT_SPLIT_SPLIT:%.*]]1518; CHECK:       exit.split.split:1519; CHECK-NEXT:    [[LCSSA_PHI:%.*]] = phi i32 [ [[TMP_C_SUM]], [[LATCH]] ]1520; CHECK-NEXT:    br label [[EXIT_SPLIT]]1521; CHECK:       exit.split:1522; CHECK-NEXT:    [[DOTUS_PHI21:%.*]] = phi i32 [ [[LCSSA_PHI]], [[EXIT_SPLIT_SPLIT]] ], [ [[LCSSA_PHI_US20]], [[EXIT_SPLIT_SPLIT_US]] ]1523; CHECK-NEXT:    br label [[EXIT]]1524; CHECK:       exit:1525; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[DOTUS_PHI21]], [[EXIT_SPLIT]] ], [ [[LCSSA_PHI_US]], [[EXIT_SPLIT_US]] ]1526; CHECK-NEXT:    ret i32 [[DOTUS_PHI]]1527;1528entry:1529  br label %header1530 1531header:1532  %tmp = call i32 @d()1533  %cmp1 = icmp eq i32 %tmp, 01534  ; We set up a chain through all the successors of the switch that doesn't1535  ; involve the switch so that we can have interesting PHI nodes in them.1536  br i1 %cmp1, label %body.a, label %dispatch1537 1538dispatch:1539  ; Switch with multiple successors. We arrange the last successor to be the1540  ; default to make the test case easier to read. This has a duplicate edge1541  ; both to the default destination (which is completely superfluous but1542  ; technically valid IR) and to a regular successor.1543  switch i32 %arg, label %body.c [1544  i32 0, label %body.a1545  i32 1, label %body.a1546  i32 2, label %body.b1547  i32 3, label %body.c1548  ]1549 1550body.a:1551  %tmp.a.phi = phi i32 [ 0, %header ], [ %tmp, %dispatch ], [ %tmp, %dispatch ]1552  %tmp.a = call i32 @a()1553  %tmp.a.sum = add i32 %tmp.a.phi, %tmp.a1554  br label %body.b1555; Unswitched 'a' loop.1556 1557body.b:1558  %tmp.b.phi = phi i32 [ %tmp, %dispatch ], [ %tmp.a.sum, %body.a ]1559  %tmp.b = call i32 @b()1560  %tmp.b.sum = add i32 %tmp.b.phi, %tmp.b1561  br label %body.c1562; Unswitched 'b' loop.1563 1564body.c:1565  %tmp.c.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ], [ %tmp.b.sum, %body.b ]1566  %tmp.c = call i32 @c()1567  %tmp.c.sum = add i32 %tmp.c.phi, %tmp.c1568  br label %latch1569; Unswitched 'c' loop.1570 1571latch:1572  %cmp2 = icmp slt i32 %tmp.c.sum, 421573  br i1 %cmp2, label %header, label %exit1574 1575exit:1576  %lcssa.phi = phi i32 [ %tmp.c.sum, %latch ]1577  ret i32 %lcssa.phi1578 1579}1580 1581; Similar to @test29 but designed to have one of the duplicate edges be1582; a loop exit edge as those can in some cases be special. Among other things,1583; this includes an LCSSA phi with multiple entries despite being a dedicated1584; exit block.1585define i32 @test30(i32 %arg) {1586; CHECK-LABEL: @test30(1587; CHECK-NEXT:  entry:1588; CHECK-NEXT:    [[ARG_FR:%.*]] = freeze i32 [[ARG:%.*]]1589; CHECK-NEXT:    switch i32 [[ARG_FR]], label [[ENTRY_SPLIT:%.*]] [1590; CHECK-NEXT:    i32 -1, label [[ENTRY_SPLIT]]1591; CHECK-NEXT:    i32 0, label [[ENTRY_SPLIT_US:%.*]]1592; CHECK-NEXT:    i32 1, label [[ENTRY_SPLIT_US1:%.*]]1593; CHECK-NEXT:    i32 2, label [[ENTRY_SPLIT_US1]]1594; CHECK-NEXT:    ]1595; CHECK:       entry.split.us:1596; CHECK-NEXT:    br label [[HEADER_US:%.*]]1597; CHECK:       header.us:1598; CHECK-NEXT:    [[TMP_US:%.*]] = call i32 @d()1599; CHECK-NEXT:    [[CMP1_US:%.*]] = icmp eq i32 [[TMP_US]], 01600; CHECK-NEXT:    br i1 [[CMP1_US]], label [[BODY_A_US:%.*]], label [[DISPATCH_US:%.*]]1601; CHECK:       dispatch.us:1602; CHECK-NEXT:    br label [[BODY_A_US]]1603; CHECK:       body.a.us:1604; CHECK-NEXT:    [[TMP_A_PHI_US:%.*]] = phi i32 [ 0, [[HEADER_US]] ], [ [[TMP_US]], [[DISPATCH_US]] ]1605; CHECK-NEXT:    [[TMP_A_US:%.*]] = call i32 @a()1606; CHECK-NEXT:    [[TMP_A_SUM_US:%.*]] = add i32 [[TMP_A_PHI_US]], [[TMP_A_US]]1607; CHECK-NEXT:    br label [[BODY_B_US:%.*]]1608; CHECK:       body.b.us:1609; CHECK-NEXT:    [[TMP_B_PHI_US:%.*]] = phi i32 [ [[TMP_A_SUM_US]], [[BODY_A_US]] ]1610; CHECK-NEXT:    [[TMP_B_US:%.*]] = call i32 @b()1611; CHECK-NEXT:    [[TMP_B_SUM_US:%.*]] = add i32 [[TMP_B_PHI_US]], [[TMP_B_US]]1612; CHECK-NEXT:    br label [[LATCH_US:%.*]]1613; CHECK:       latch.us:1614; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp slt i32 [[TMP_B_SUM_US]], 421615; CHECK-NEXT:    br i1 [[CMP2_US]], label [[HEADER_US]], label [[LOOP_EXIT2_SPLIT_US:%.*]]1616; CHECK:       loop.exit2.split.us:1617; CHECK-NEXT:    [[L2_PHI_US:%.*]] = phi i32 [ [[TMP_B_SUM_US]], [[LATCH_US]] ]1618; CHECK-NEXT:    br label [[LOOP_EXIT2:%.*]]1619; CHECK:       entry.split.us1:1620; CHECK-NEXT:    br label [[HEADER_US2:%.*]]1621; CHECK:       header.us2:1622; CHECK-NEXT:    [[TMP_US3:%.*]] = call i32 @d()1623; CHECK-NEXT:    [[CMP1_US4:%.*]] = icmp eq i32 [[TMP_US3]], 01624; CHECK-NEXT:    br i1 [[CMP1_US4]], label [[BODY_A_US6:%.*]], label [[DISPATCH_US5:%.*]]1625; CHECK:       dispatch.us5:1626; CHECK-NEXT:    br label [[BODY_B_US10:%.*]]1627; CHECK:       body.a.us6:1628; CHECK-NEXT:    [[TMP_A_PHI_US7:%.*]] = phi i32 [ 0, [[HEADER_US2]] ]1629; CHECK-NEXT:    [[TMP_A_US8:%.*]] = call i32 @a()1630; CHECK-NEXT:    [[TMP_A_SUM_US9:%.*]] = add i32 [[TMP_A_PHI_US7]], [[TMP_A_US8]]1631; CHECK-NEXT:    br label [[BODY_B_US10]]1632; CHECK:       body.b.us10:1633; CHECK-NEXT:    [[TMP_B_PHI_US11:%.*]] = phi i32 [ [[TMP_US3]], [[DISPATCH_US5]] ], [ [[TMP_A_SUM_US9]], [[BODY_A_US6]] ]1634; CHECK-NEXT:    [[TMP_B_US12:%.*]] = call i32 @b()1635; CHECK-NEXT:    [[TMP_B_SUM_US13:%.*]] = add i32 [[TMP_B_PHI_US11]], [[TMP_B_US12]]1636; CHECK-NEXT:    br label [[LATCH_US14:%.*]]1637; CHECK:       latch.us14:1638; CHECK-NEXT:    [[CMP2_US15:%.*]] = icmp slt i32 [[TMP_B_SUM_US13]], 421639; CHECK-NEXT:    br i1 [[CMP2_US15]], label [[HEADER_US2]], label [[LOOP_EXIT2_SPLIT_SPLIT_US:%.*]]1640; CHECK:       loop.exit2.split.split.us:1641; CHECK-NEXT:    [[L2_PHI_US16:%.*]] = phi i32 [ [[TMP_B_SUM_US13]], [[LATCH_US14]] ]1642; CHECK-NEXT:    br label [[LOOP_EXIT2_SPLIT:%.*]]1643; CHECK:       entry.split:1644; CHECK-NEXT:    br label [[HEADER:%.*]]1645; CHECK:       header:1646; CHECK-NEXT:    [[TMP:%.*]] = call i32 @d()1647; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[TMP]], 01648; CHECK-NEXT:    br i1 [[CMP1]], label [[BODY_A:%.*]], label [[DISPATCH:%.*]]1649; CHECK:       dispatch:1650; CHECK-NEXT:    [[TMP_LCSSA:%.*]] = phi i32 [ [[TMP]], [[HEADER]] ]1651; CHECK-NEXT:    br label [[LOOP_EXIT1:%.*]]1652; CHECK:       body.a:1653; CHECK-NEXT:    [[TMP_A_PHI:%.*]] = phi i32 [ 0, [[HEADER]] ]1654; CHECK-NEXT:    [[TMP_A:%.*]] = call i32 @a()1655; CHECK-NEXT:    [[TMP_A_SUM:%.*]] = add i32 [[TMP_A_PHI]], [[TMP_A]]1656; CHECK-NEXT:    br label [[BODY_B:%.*]]1657; CHECK:       body.b:1658; CHECK-NEXT:    [[TMP_B_PHI:%.*]] = phi i32 [ [[TMP_A_SUM]], [[BODY_A]] ]1659; CHECK-NEXT:    [[TMP_B:%.*]] = call i32 @b()1660; CHECK-NEXT:    [[TMP_B_SUM:%.*]] = add i32 [[TMP_B_PHI]], [[TMP_B]]1661; CHECK-NEXT:    br label [[LATCH:%.*]]1662; CHECK:       latch:1663; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[TMP_B_SUM]], 421664; CHECK-NEXT:    br i1 [[CMP2]], label [[HEADER]], label [[LOOP_EXIT2_SPLIT_SPLIT:%.*]]1665; CHECK:       loop.exit1:1666; CHECK-NEXT:    [[L1_PHI:%.*]] = phi i32 [ [[TMP_LCSSA]], [[DISPATCH]] ]1667; CHECK-NEXT:    br label [[EXIT:%.*]]1668; CHECK:       loop.exit2.split.split:1669; CHECK-NEXT:    [[L2_PHI:%.*]] = phi i32 [ [[TMP_B_SUM]], [[LATCH]] ]1670; CHECK-NEXT:    br label [[LOOP_EXIT2_SPLIT]]1671; CHECK:       loop.exit2.split:1672; CHECK-NEXT:    [[DOTUS_PHI17:%.*]] = phi i32 [ [[L2_PHI]], [[LOOP_EXIT2_SPLIT_SPLIT]] ], [ [[L2_PHI_US16]], [[LOOP_EXIT2_SPLIT_SPLIT_US]] ]1673; CHECK-NEXT:    br label [[LOOP_EXIT2]]1674; CHECK:       loop.exit2:1675; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi i32 [ [[DOTUS_PHI17]], [[LOOP_EXIT2_SPLIT]] ], [ [[L2_PHI_US]], [[LOOP_EXIT2_SPLIT_US]] ]1676; CHECK-NEXT:    br label [[EXIT]]1677; CHECK:       exit:1678; CHECK-NEXT:    [[L_PHI:%.*]] = phi i32 [ [[L1_PHI]], [[LOOP_EXIT1]] ], [ [[DOTUS_PHI]], [[LOOP_EXIT2]] ]1679; CHECK-NEXT:    ret i32 [[L_PHI]]1680;1681entry:1682  br label %header1683 1684header:1685  %tmp = call i32 @d()1686  %cmp1 = icmp eq i32 %tmp, 01687  br i1 %cmp1, label %body.a, label %dispatch1688 1689dispatch:1690  switch i32 %arg, label %loop.exit1 [1691  i32 -1, label %loop.exit11692  i32 0, label %body.a1693  i32 1, label %body.b1694  i32 2, label %body.b1695  ]1696 1697body.a:1698  %tmp.a.phi = phi i32 [ 0, %header ], [ %tmp, %dispatch ]1699  %tmp.a = call i32 @a()1700  %tmp.a.sum = add i32 %tmp.a.phi, %tmp.a1701  br label %body.b1702; Unswitched 'a' loop.1703 1704body.b:1705  %tmp.b.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ], [ %tmp.a.sum, %body.a ]1706  %tmp.b = call i32 @b()1707  %tmp.b.sum = add i32 %tmp.b.phi, %tmp.b1708  br label %latch1709; Unswitched 'b' loop.1710 1711latch:1712  %cmp2 = icmp slt i32 %tmp.b.sum, 421713  br i1 %cmp2, label %header, label %loop.exit21714 1715loop.exit1:1716  %l1.phi = phi i32 [ %tmp, %dispatch ], [ %tmp, %dispatch ]1717  br label %exit1718; Unswitched 'exit' loop.1719 1720loop.exit2:1721  %l2.phi = phi i32 [ %tmp.b.sum, %latch ]1722  br label %exit1723 1724exit:1725  %l.phi = phi i32 [ %l1.phi, %loop.exit1 ], [ %l2.phi, %loop.exit2 ]1726  ret i32 %l.phi1727}1728 1729; Unswitch will not actually change the loop nest from:1730;   A < B < C1731define void @hoist_inner_loop0() {1732; CHECK-LABEL: @hoist_inner_loop0(1733; CHECK-NEXT:  entry:1734; CHECK-NEXT:    br label [[A_HEADER:%.*]]1735; CHECK:       a.header:1736; CHECK-NEXT:    br label [[B_HEADER:%.*]]1737; CHECK:       b.header:1738; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()1739; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]1740; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]1741; CHECK:       b.header.split.us:1742; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]1743; CHECK:       c.header.us:1744; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()1745; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]1746; CHECK:       b.latch.split.us:1747; CHECK-NEXT:    br label [[B_LATCH:%.*]]1748; CHECK:       b.header.split:1749; CHECK-NEXT:    br label [[C_HEADER:%.*]]1750; CHECK:       c.header:1751; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()1752; CHECK-NEXT:    br label [[C_LATCH:%.*]]1753; CHECK:       c.latch:1754; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()1755; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[B_LATCH_SPLIT:%.*]]1756; CHECK:       b.latch.split:1757; CHECK-NEXT:    br label [[B_LATCH]]1758; CHECK:       b.latch:1759; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()1760; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_LATCH:%.*]]1761; CHECK:       a.latch:1762; CHECK-NEXT:    br label [[A_HEADER]]1763; CHECK:       exit:1764; CHECK-NEXT:    ret void1765;1766entry:1767  br label %a.header1768 1769a.header:1770  br label %b.header1771 1772b.header:1773  %v1 = call i1 @cond()1774  br label %c.header1775 1776c.header:1777  call i32 @c()1778  br i1 %v1, label %b.latch, label %c.latch1779 1780c.latch:1781  %v2 = call i1 @cond()1782  br i1 %v2, label %c.header, label %b.latch1783 1784b.latch:1785  %v3 = call i1 @cond()1786  br i1 %v3, label %b.header, label %a.latch1787 1788a.latch:1789  br label %a.header1790 1791exit:1792  ret void1793}1794 1795; Unswitch will transform the loop nest from:1796;   A < B < C1797; into1798;   A < (B, C)1799define void @hoist_inner_loop1(ptr %ptr) {1800; CHECK-LABEL: @hoist_inner_loop1(1801; CHECK-NEXT:  entry:1802; CHECK-NEXT:    br label [[A_HEADER:%.*]]1803; CHECK:       a.header:1804; CHECK-NEXT:    [[X_A:%.*]] = load i32, ptr [[PTR:%.*]], align 41805; CHECK-NEXT:    br label [[B_HEADER:%.*]]1806; CHECK:       b.header:1807; CHECK-NEXT:    [[X_B:%.*]] = load i32, ptr [[PTR]], align 41808; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()1809; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]1810; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]1811; CHECK:       b.header.split.us:1812; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]1813; CHECK:       c.header.us:1814; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()1815; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]1816; CHECK:       b.latch.split.us:1817; CHECK-NEXT:    br label [[B_LATCH:%.*]]1818; CHECK:       b.header.split:1819; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]1820; CHECK-NEXT:    br label [[C_HEADER:%.*]]1821; CHECK:       c.header:1822; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()1823; CHECK-NEXT:    br label [[C_LATCH:%.*]]1824; CHECK:       c.latch:1825; CHECK-NEXT:    store i32 [[X_A]], ptr [[PTR]], align 41826; CHECK-NEXT:    store i32 [[X_B_LCSSA]], ptr [[PTR]], align 41827; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()1828; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[A_EXIT_C:%.*]]1829; CHECK:       b.latch:1830; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()1831; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_EXIT_B:%.*]]1832; CHECK:       a.exit.c:1833; CHECK-NEXT:    br label [[A_LATCH:%.*]]1834; CHECK:       a.exit.b:1835; CHECK-NEXT:    br label [[A_LATCH]]1836; CHECK:       a.latch:1837; CHECK-NEXT:    br label [[A_HEADER]]1838; CHECK:       exit:1839; CHECK-NEXT:    ret void1840;1841entry:1842  br label %a.header1843 1844a.header:1845  %x.a = load i32, ptr %ptr1846  br label %b.header1847 1848b.header:1849  %x.b = load i32, ptr %ptr1850  %v1 = call i1 @cond()1851  br label %c.header1852 1853c.header:1854  call i32 @c()1855  br i1 %v1, label %b.latch, label %c.latch1856 1857c.latch:1858  ; Use values from other loops to check LCSSA form.1859  store i32 %x.a, ptr %ptr1860  store i32 %x.b, ptr %ptr1861  %v2 = call i1 @cond()1862  br i1 %v2, label %c.header, label %a.exit.c1863 1864b.latch:1865  %v3 = call i1 @cond()1866  br i1 %v3, label %b.header, label %a.exit.b1867 1868a.exit.c:1869  br label %a.latch1870 1871a.exit.b:1872  br label %a.latch1873 1874a.latch:1875  br label %a.header1876 1877exit:1878  ret void1879}1880 1881; Unswitch will transform the loop nest from:1882;   A < B < C1883; into1884;   (A < B), C1885define void @hoist_inner_loop2(ptr %ptr) {1886; CHECK-LABEL: @hoist_inner_loop2(1887; CHECK-NEXT:  entry:1888; CHECK-NEXT:    br label [[A_HEADER:%.*]]1889; CHECK:       a.header:1890; CHECK-NEXT:    [[X_A:%.*]] = load i32, ptr [[PTR:%.*]], align 41891; CHECK-NEXT:    br label [[B_HEADER:%.*]]1892; CHECK:       b.header:1893; CHECK-NEXT:    [[X_B:%.*]] = load i32, ptr [[PTR]], align 41894; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()1895; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]1896; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]1897; CHECK:       b.header.split.us:1898; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]1899; CHECK:       c.header.us:1900; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()1901; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]1902; CHECK:       b.latch.split.us:1903; CHECK-NEXT:    br label [[B_LATCH:%.*]]1904; CHECK:       b.header.split:1905; CHECK-NEXT:    [[X_A_LCSSA:%.*]] = phi i32 [ [[X_A]], [[B_HEADER]] ]1906; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]1907; CHECK-NEXT:    br label [[C_HEADER:%.*]]1908; CHECK:       c.header:1909; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()1910; CHECK-NEXT:    br label [[C_LATCH:%.*]]1911; CHECK:       c.latch:1912; CHECK-NEXT:    store i32 [[X_A_LCSSA]], ptr [[PTR]], align 41913; CHECK-NEXT:    store i32 [[X_B_LCSSA]], ptr [[PTR]], align 41914; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()1915; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[EXIT:%.*]]1916; CHECK:       b.latch:1917; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()1918; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_LATCH:%.*]]1919; CHECK:       a.latch:1920; CHECK-NEXT:    br label [[A_HEADER]]1921; CHECK:       exit:1922; CHECK-NEXT:    ret void1923;1924entry:1925  br label %a.header1926 1927a.header:1928  %x.a = load i32, ptr %ptr1929  br label %b.header1930 1931b.header:1932  %x.b = load i32, ptr %ptr1933  %v1 = call i1 @cond()1934  br label %c.header1935 1936c.header:1937  call i32 @c()1938  br i1 %v1, label %b.latch, label %c.latch1939 1940c.latch:1941  ; Use values from other loops to check LCSSA form.1942  store i32 %x.a, ptr %ptr1943  store i32 %x.b, ptr %ptr1944  %v2 = call i1 @cond()1945  br i1 %v2, label %c.header, label %exit1946 1947b.latch:1948  %v3 = call i1 @cond()1949  br i1 %v3, label %b.header, label %a.latch1950 1951a.latch:1952  br label %a.header1953 1954exit:1955  ret void1956}1957 1958; Same as @hoist_inner_loop2 but with a nested loop inside the hoisted loop.1959; Unswitch will transform the loop nest from:1960;   A < B < C < D1961; into1962;   (A < B), (C < D)1963define void @hoist_inner_loop3(ptr %ptr) {1964; CHECK-LABEL: @hoist_inner_loop3(1965; CHECK-NEXT:  entry:1966; CHECK-NEXT:    br label [[A_HEADER:%.*]]1967; CHECK:       a.header:1968; CHECK-NEXT:    [[X_A:%.*]] = load i32, ptr [[PTR:%.*]], align 41969; CHECK-NEXT:    br label [[B_HEADER:%.*]]1970; CHECK:       b.header:1971; CHECK-NEXT:    [[X_B:%.*]] = load i32, ptr [[PTR]], align 41972; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()1973; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]1974; CHECK-NEXT:    br i1 [[V1_FR]], label [[B_HEADER_SPLIT_US:%.*]], label [[B_HEADER_SPLIT:%.*]]1975; CHECK:       b.header.split.us:1976; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]1977; CHECK:       c.header.us:1978; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()1979; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]1980; CHECK:       b.latch.split.us:1981; CHECK-NEXT:    br label [[B_LATCH:%.*]]1982; CHECK:       b.header.split:1983; CHECK-NEXT:    [[X_A_LCSSA:%.*]] = phi i32 [ [[X_A]], [[B_HEADER]] ]1984; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]1985; CHECK-NEXT:    br label [[C_HEADER:%.*]]1986; CHECK:       c.header:1987; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()1988; CHECK-NEXT:    br label [[C_BODY:%.*]]1989; CHECK:       c.body:1990; CHECK-NEXT:    [[X_C:%.*]] = load i32, ptr [[PTR]], align 41991; CHECK-NEXT:    br label [[D_HEADER:%.*]]1992; CHECK:       d.header:1993; CHECK-NEXT:    store i32 [[X_A_LCSSA]], ptr [[PTR]], align 41994; CHECK-NEXT:    store i32 [[X_B_LCSSA]], ptr [[PTR]], align 41995; CHECK-NEXT:    store i32 [[X_C]], ptr [[PTR]], align 41996; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()1997; CHECK-NEXT:    br i1 [[V2]], label [[D_HEADER]], label [[C_LATCH:%.*]]1998; CHECK:       c.latch:1999; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()2000; CHECK-NEXT:    br i1 [[V3]], label [[C_HEADER]], label [[EXIT:%.*]]2001; CHECK:       b.latch:2002; CHECK-NEXT:    [[V4:%.*]] = call i1 @cond()2003; CHECK-NEXT:    br i1 [[V4]], label [[B_HEADER]], label [[A_LATCH:%.*]]2004; CHECK:       a.latch:2005; CHECK-NEXT:    br label [[A_HEADER]]2006; CHECK:       exit:2007; CHECK-NEXT:    ret void2008;2009entry:2010  br label %a.header2011 2012a.header:2013  %x.a = load i32, ptr %ptr2014  br label %b.header2015 2016b.header:2017  %x.b = load i32, ptr %ptr2018  %v1 = call i1 @cond()2019  br label %c.header2020 2021c.header:2022  call i32 @c()2023  br i1 %v1, label %b.latch, label %c.body2024 2025c.body:2026  %x.c = load i32, ptr %ptr2027  br label %d.header2028 2029d.header:2030  ; Use values from other loops to check LCSSA form.2031  store i32 %x.a, ptr %ptr2032  store i32 %x.b, ptr %ptr2033  store i32 %x.c, ptr %ptr2034  %v2 = call i1 @cond()2035  br i1 %v2, label %d.header, label %c.latch2036 2037c.latch:2038  %v3 = call i1 @cond()2039  br i1 %v3, label %c.header, label %exit2040 2041b.latch:2042  %v4 = call i1 @cond()2043  br i1 %v4, label %b.header, label %a.latch2044 2045a.latch:2046  br label %a.header2047 2048exit:2049  ret void2050}2051 2052; This test is designed to exercise checking multiple remaining exits from the2053; loop being unswitched.2054; Unswitch will transform the loop nest from:2055;   A < B < C < D2056; into2057;   A < B < (C, D)2058define void @hoist_inner_loop4() {2059; CHECK-LABEL: @hoist_inner_loop4(2060; CHECK-NEXT:  entry:2061; CHECK-NEXT:    br label [[A_HEADER:%.*]]2062; CHECK:       a.header:2063; CHECK-NEXT:    br label [[B_HEADER:%.*]]2064; CHECK:       b.header:2065; CHECK-NEXT:    br label [[C_HEADER:%.*]]2066; CHECK:       c.header:2067; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()2068; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]2069; CHECK-NEXT:    br i1 [[V1_FR]], label [[C_HEADER_SPLIT_US:%.*]], label [[C_HEADER_SPLIT:%.*]]2070; CHECK:       c.header.split.us:2071; CHECK-NEXT:    br label [[D_HEADER_US:%.*]]2072; CHECK:       d.header.us:2073; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @d()2074; CHECK-NEXT:    br label [[C_LATCH_SPLIT_US:%.*]]2075; CHECK:       c.latch.split.us:2076; CHECK-NEXT:    br label [[C_LATCH:%.*]]2077; CHECK:       c.header.split:2078; CHECK-NEXT:    br label [[D_HEADER:%.*]]2079; CHECK:       d.header:2080; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @d()2081; CHECK-NEXT:    br label [[D_EXITING1:%.*]]2082; CHECK:       d.exiting1:2083; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()2084; CHECK-NEXT:    br i1 [[V2]], label [[D_EXITING2:%.*]], label [[A_LATCH:%.*]]2085; CHECK:       d.exiting2:2086; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()2087; CHECK-NEXT:    br i1 [[V3]], label [[D_EXITING3:%.*]], label [[LOOPEXIT_D:%.*]]2088; CHECK:       d.exiting3:2089; CHECK-NEXT:    [[V4:%.*]] = call i1 @cond()2090; CHECK-NEXT:    br i1 [[V4]], label [[D_LATCH:%.*]], label [[B_LATCH:%.*]]2091; CHECK:       d.latch:2092; CHECK-NEXT:    br label [[D_HEADER]]2093; CHECK:       c.latch:2094; CHECK-NEXT:    [[V5:%.*]] = call i1 @cond()2095; CHECK-NEXT:    br i1 [[V5]], label [[C_HEADER]], label [[LOOPEXIT_C:%.*]]2096; CHECK:       b.latch:2097; CHECK-NEXT:    br label [[B_HEADER]]2098; CHECK:       a.latch:2099; CHECK-NEXT:    br label [[A_HEADER]]2100; CHECK:       loopexit.d:2101; CHECK-NEXT:    br label [[EXIT:%.*]]2102; CHECK:       loopexit.c:2103; CHECK-NEXT:    br label [[EXIT]]2104; CHECK:       exit:2105; CHECK-NEXT:    ret void2106;2107entry:2108  br label %a.header2109 2110a.header:2111  br label %b.header2112 2113b.header:2114  br label %c.header2115 2116c.header:2117  %v1 = call i1 @cond()2118  br label %d.header2119 2120d.header:2121  call i32 @d()2122  br i1 %v1, label %c.latch, label %d.exiting12123 2124d.exiting1:2125  %v2 = call i1 @cond()2126  br i1 %v2, label %d.exiting2, label %a.latch2127 2128d.exiting2:2129  %v3 = call i1 @cond()2130  br i1 %v3, label %d.exiting3, label %loopexit.d2131 2132d.exiting3:2133  %v4 = call i1 @cond()2134  br i1 %v4, label %d.latch, label %b.latch2135 2136d.latch:2137  br label %d.header2138 2139c.latch:2140  %v5 = call i1 @cond()2141  br i1 %v5, label %c.header, label %loopexit.c2142 2143b.latch:2144  br label %b.header2145 2146a.latch:2147  br label %a.header2148 2149loopexit.d:2150  br label %exit2151 2152loopexit.c:2153  br label %exit2154 2155exit:2156  ret void2157}2158 2159; Unswitch will transform the loop nest from:2160;   A < B < C < D2161; into2162;   A < ((B < C), D)2163define void @hoist_inner_loop5(ptr %ptr) {2164; CHECK-LABEL: @hoist_inner_loop5(2165; CHECK-NEXT:  entry:2166; CHECK-NEXT:    br label [[A_HEADER:%.*]]2167; CHECK:       a.header:2168; CHECK-NEXT:    [[X_A:%.*]] = load i32, ptr [[PTR:%.*]], align 42169; CHECK-NEXT:    br label [[B_HEADER:%.*]]2170; CHECK:       b.header:2171; CHECK-NEXT:    [[X_B:%.*]] = load i32, ptr [[PTR]], align 42172; CHECK-NEXT:    br label [[C_HEADER:%.*]]2173; CHECK:       c.header:2174; CHECK-NEXT:    [[X_C:%.*]] = load i32, ptr [[PTR]], align 42175; CHECK-NEXT:    [[V1:%.*]] = call i1 @cond()2176; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i1 [[V1]]2177; CHECK-NEXT:    br i1 [[V1_FR]], label [[C_HEADER_SPLIT_US:%.*]], label [[C_HEADER_SPLIT:%.*]]2178; CHECK:       c.header.split.us:2179; CHECK-NEXT:    br label [[D_HEADER_US:%.*]]2180; CHECK:       d.header.us:2181; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @d()2182; CHECK-NEXT:    br label [[C_LATCH_SPLIT_US:%.*]]2183; CHECK:       c.latch.split.us:2184; CHECK-NEXT:    br label [[C_LATCH:%.*]]2185; CHECK:       c.header.split:2186; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[C_HEADER]] ]2187; CHECK-NEXT:    [[X_C_LCSSA:%.*]] = phi i32 [ [[X_C]], [[C_HEADER]] ]2188; CHECK-NEXT:    br label [[D_HEADER:%.*]]2189; CHECK:       d.header:2190; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @d()2191; CHECK-NEXT:    br label [[D_LATCH:%.*]]2192; CHECK:       d.latch:2193; CHECK-NEXT:    store i32 [[X_A]], ptr [[PTR]], align 42194; CHECK-NEXT:    store i32 [[X_B_LCSSA]], ptr [[PTR]], align 42195; CHECK-NEXT:    store i32 [[X_C_LCSSA]], ptr [[PTR]], align 42196; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()2197; CHECK-NEXT:    br i1 [[V2]], label [[D_HEADER]], label [[A_LATCH:%.*]]2198; CHECK:       c.latch:2199; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()2200; CHECK-NEXT:    br i1 [[V3]], label [[C_HEADER]], label [[B_LATCH:%.*]]2201; CHECK:       b.latch:2202; CHECK-NEXT:    br label [[B_HEADER]]2203; CHECK:       a.latch:2204; CHECK-NEXT:    br label [[A_HEADER]]2205; CHECK:       exit:2206; CHECK-NEXT:    ret void2207;2208entry:2209  br label %a.header2210 2211a.header:2212  %x.a = load i32, ptr %ptr2213  br label %b.header2214 2215b.header:2216  %x.b = load i32, ptr %ptr2217  br label %c.header2218 2219c.header:2220  %x.c = load i32, ptr %ptr2221  %v1 = call i1 @cond()2222  br label %d.header2223 2224d.header:2225  call i32 @d()2226  br i1 %v1, label %c.latch, label %d.latch2227 2228d.latch:2229  ; Use values from other loops to check LCSSA form.2230  store i32 %x.a, ptr %ptr2231  store i32 %x.b, ptr %ptr2232  store i32 %x.c, ptr %ptr2233  %v2 = call i1 @cond()2234  br i1 %v2, label %d.header, label %a.latch2235 2236c.latch:2237  %v3 = call i1 @cond()2238  br i1 %v3, label %c.header, label %b.latch2239 2240b.latch:2241  br label %b.header2242 2243a.latch:2244  br label %a.header2245 2246exit:2247  ret void2248}2249 2250define void @hoist_inner_loop_switch(ptr %ptr) {2251; CHECK-LABEL: @hoist_inner_loop_switch(2252; CHECK-NEXT:  entry:2253; CHECK-NEXT:    br label [[A_HEADER:%.*]]2254; CHECK:       a.header:2255; CHECK-NEXT:    [[X_A:%.*]] = load i32, ptr [[PTR:%.*]], align 42256; CHECK-NEXT:    br label [[B_HEADER:%.*]]2257; CHECK:       b.header:2258; CHECK-NEXT:    [[X_B:%.*]] = load i32, ptr [[PTR]], align 42259; CHECK-NEXT:    [[V1:%.*]] = call i32 @cond.i32()2260; CHECK-NEXT:    [[V1_FR:%.*]] = freeze i32 [[V1]]2261; CHECK-NEXT:    switch i32 [[V1_FR]], label [[B_HEADER_SPLIT:%.*]] [2262; CHECK-NEXT:    i32 1, label [[B_HEADER_SPLIT_US:%.*]]2263; CHECK-NEXT:    i32 2, label [[B_HEADER_SPLIT_US]]2264; CHECK-NEXT:    i32 3, label [[B_HEADER_SPLIT_US]]2265; CHECK-NEXT:    ]2266; CHECK:       b.header.split.us:2267; CHECK-NEXT:    br label [[C_HEADER_US:%.*]]2268; CHECK:       c.header.us:2269; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @c()2270; CHECK-NEXT:    br label [[B_LATCH_SPLIT_US:%.*]]2271; CHECK:       b.latch.split.us:2272; CHECK-NEXT:    br label [[B_LATCH:%.*]]2273; CHECK:       b.header.split:2274; CHECK-NEXT:    [[X_A_LCSSA:%.*]] = phi i32 [ [[X_A]], [[B_HEADER]] ]2275; CHECK-NEXT:    [[X_B_LCSSA:%.*]] = phi i32 [ [[X_B]], [[B_HEADER]] ]2276; CHECK-NEXT:    br label [[C_HEADER:%.*]]2277; CHECK:       c.header:2278; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @c()2279; CHECK-NEXT:    br label [[C_LATCH:%.*]]2280; CHECK:       c.latch:2281; CHECK-NEXT:    store i32 [[X_A_LCSSA]], ptr [[PTR]], align 42282; CHECK-NEXT:    store i32 [[X_B_LCSSA]], ptr [[PTR]], align 42283; CHECK-NEXT:    [[V2:%.*]] = call i1 @cond()2284; CHECK-NEXT:    br i1 [[V2]], label [[C_HEADER]], label [[EXIT:%.*]]2285; CHECK:       b.latch:2286; CHECK-NEXT:    [[V3:%.*]] = call i1 @cond()2287; CHECK-NEXT:    br i1 [[V3]], label [[B_HEADER]], label [[A_LATCH:%.*]]2288; CHECK:       a.latch:2289; CHECK-NEXT:    br label [[A_HEADER]]2290; CHECK:       exit:2291; CHECK-NEXT:    ret void2292;2293entry:2294  br label %a.header2295 2296a.header:2297  %x.a = load i32, ptr %ptr2298  br label %b.header2299 2300b.header:2301  %x.b = load i32, ptr %ptr2302  %v1 = call i32 @cond.i32()2303  br label %c.header2304 2305c.header:2306  call i32 @c()2307  switch i32 %v1, label %c.latch [2308  i32 1, label %b.latch2309  i32 2, label %b.latch2310  i32 3, label %b.latch2311  ]2312 2313c.latch:2314  ; Use values from other loops to check LCSSA form.2315  store i32 %x.a, ptr %ptr2316  store i32 %x.b, ptr %ptr2317  %v2 = call i1 @cond()2318  br i1 %v2, label %c.header, label %exit2319 2320b.latch:2321  %v3 = call i1 @cond()2322  br i1 %v3, label %b.header, label %a.latch2323 2324a.latch:2325  br label %a.header2326 2327exit:2328  ret void2329}2330 2331define i32 @test_partial_unswitch_all_conds_guaranteed_non_poison(i1 noundef %c.1, i1 noundef %c.2) {2332; CHECK-LABEL: @test_partial_unswitch_all_conds_guaranteed_non_poison(2333; CHECK-NEXT:  entry:2334; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[C_1:%.*]], [[C_2:%.*]]2335; CHECK-NEXT:    br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]2336; CHECK:       entry.split.us:2337; CHECK-NEXT:    br label [[LOOP_US:%.*]]2338; CHECK:       loop.us:2339; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @a()2340; CHECK-NEXT:    br label [[EXIT_SPLIT_US:%.*]]2341; CHECK:       exit.split.us:2342; CHECK-NEXT:    br label [[EXIT:%.*]]2343; CHECK:       entry.split:2344; CHECK-NEXT:    br label [[LOOP:%.*]]2345; CHECK:       loop:2346; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @a()2347; CHECK-NEXT:    [[SEL:%.*]] = select i1 true, i1 true, i1 false2348; CHECK-NEXT:    br i1 [[SEL]], label [[LOOP]], label [[EXIT_SPLIT:%.*]]2349; CHECK:       exit.split:2350; CHECK-NEXT:    br label [[EXIT]]2351; CHECK:       exit:2352; CHECK-NEXT:    ret i32 02353;2354entry:2355  br label %loop2356 2357loop:2358  call i32 @a()2359  %sel = select i1 %c.1, i1 %c.2, i1 false2360  br i1 %sel, label %loop, label %exit2361 2362exit:2363  ret i32 02364}2365