1482 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals2; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s3 4declare void @clobber()5 6define i32 @partial_unswitch_true_successor(ptr %ptr, i32 %N) !prof !0 {7; CHECK-LABEL: @partial_unswitch_true_successor(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 410; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 10011; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]], !prof [[PROF1:![0-9]+]]12; CHECK: entry.split.us:13; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]14; CHECK: loop.header.us:15; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]16; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]17; CHECK: noclobber.us:18; CHECK-NEXT: br label [[LOOP_LATCH_US]]19; CHECK: loop.latch.us:20; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]21; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 122; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]], !prof [[PROF2:![0-9]+]]23; CHECK: exit.split.us:24; CHECK-NEXT: br label [[EXIT:%.*]]25; CHECK: entry.split:26; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]27; CHECK: loop.header:28; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]29; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 430; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 10031; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]], !prof [[PROF1]]32; CHECK: noclobber:33; CHECK-NEXT: br label [[LOOP_LATCH]]34; CHECK: clobber:35; CHECK-NEXT: call void @clobber()36; CHECK-NEXT: br label [[LOOP_LATCH]]37; CHECK: loop.latch:38; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]39; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 140; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !prof [[PROF2]], !llvm.loop [[LOOP3:![0-9]+]]41; CHECK: exit.split:42; CHECK-NEXT: br label [[EXIT]]43; CHECK: exit:44; CHECK-NEXT: ret i32 1045;46entry:47 br label %loop.header48 49loop.header:50 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]51 %lv = load i32, ptr %ptr52 %sc = icmp eq i32 %lv, 10053 br i1 %sc, label %noclobber, label %clobber, !prof !154 55noclobber:56 br label %loop.latch57 58clobber:59 call void @clobber()60 br label %loop.latch61 62loop.latch:63 %c = icmp ult i32 %iv, %N64 %iv.next = add i32 %iv, 165 br i1 %c, label %loop.header, label %exit, !prof !266 67exit:68 ret i32 1069}70 71define i32 @partial_unswitch_false_successor(ptr %ptr, i32 %N) {72; CHECK-LABEL: @partial_unswitch_false_successor(73; CHECK-NEXT: entry:74; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 475; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 10076; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]77; CHECK: entry.split.us:78; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]79; CHECK: loop.header.us:80; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]81; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]82; CHECK: noclobber.us:83; CHECK-NEXT: br label [[LOOP_LATCH_US]]84; CHECK: loop.latch.us:85; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]86; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 187; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]88; CHECK: exit.split.us:89; CHECK-NEXT: br label [[EXIT:%.*]]90; CHECK: entry.split:91; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]92; CHECK: loop.header:93; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]94; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 495; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 10096; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]97; CHECK: clobber:98; CHECK-NEXT: call void @clobber()99; CHECK-NEXT: br label [[LOOP_LATCH]]100; CHECK: noclobber:101; CHECK-NEXT: br label [[LOOP_LATCH]]102; CHECK: loop.latch:103; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]104; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1105; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP5:![0-9]+]]106; CHECK: exit.split:107; CHECK-NEXT: br label [[EXIT]]108; CHECK: exit:109; CHECK-NEXT: ret i32 10110;111entry:112 br label %loop.header113 114loop.header:115 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]116 %lv = load i32, ptr %ptr117 %sc = icmp eq i32 %lv, 100118 br i1 %sc, label %clobber, label %noclobber119 120clobber:121 call void @clobber()122 br label %loop.latch123 124noclobber:125 br label %loop.latch126 127loop.latch:128 %c = icmp ult i32 %iv, %N129 %iv.next = add i32 %iv, 1130 br i1 %c, label %loop.header, label %exit131 132exit:133 ret i32 10134}135 136define i32 @partial_unswtich_gep_load_icmp(ptr %ptr, i32 %N) {137; CHECK-LABEL: @partial_unswtich_gep_load_icmp(138; CHECK-NEXT: entry:139; CHECK-NEXT: [[TMP0:%.*]] = getelementptr ptr, ptr [[PTR:%.*]], i32 1140; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8141; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4142; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 100143; CHECK-NEXT: br i1 [[TMP3]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]144; CHECK: entry.split.us:145; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]146; CHECK: loop.header.us:147; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]148; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]149; CHECK: noclobber.us:150; CHECK-NEXT: br label [[LOOP_LATCH_US]]151; CHECK: loop.latch.us:152; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]153; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1154; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]155; CHECK: exit.split.us:156; CHECK-NEXT: br label [[EXIT:%.*]]157; CHECK: entry.split:158; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]159; CHECK: loop.header:160; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]161; CHECK-NEXT: [[GEP:%.*]] = getelementptr ptr, ptr [[PTR]], i32 1162; CHECK-NEXT: [[LV_1:%.*]] = load ptr, ptr [[GEP]], align 8163; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[LV_1]], align 4164; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100165; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]166; CHECK: noclobber:167; CHECK-NEXT: br label [[LOOP_LATCH]]168; CHECK: clobber:169; CHECK-NEXT: call void @clobber()170; CHECK-NEXT: br label [[LOOP_LATCH]]171; CHECK: loop.latch:172; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]173; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1174; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]]175; CHECK: exit.split:176; CHECK-NEXT: br label [[EXIT]]177; CHECK: exit:178; CHECK-NEXT: ret i32 10179;180entry:181 br label %loop.header182 183loop.header:184 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]185 %gep = getelementptr ptr, ptr %ptr, i32 1186 %lv.1 = load ptr, ptr %gep187 %lv = load i32, ptr %lv.1188 %sc = icmp eq i32 %lv, 100189 br i1 %sc, label %noclobber, label %clobber190 191noclobber:192 br label %loop.latch193 194clobber:195 call void @clobber()196 br label %loop.latch197 198loop.latch:199 %c = icmp ult i32 %iv, %N200 %iv.next = add i32 %iv, 1201 br i1 %c, label %loop.header, label %exit202 203exit:204 ret i32 10205}206 207define i32 @partial_unswitch_reduction_phi(ptr %ptr, i32 %N) {208; CHECK-LABEL: @partial_unswitch_reduction_phi(209; CHECK-NEXT: entry:210; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4211; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100212; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]213; CHECK: entry.split.us:214; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]215; CHECK: loop.header.us:216; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]217; CHECK-NEXT: [[RED_US:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT_US]] ], [ [[RED_NEXT_US:%.*]], [[LOOP_LATCH_US]] ]218; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]219; CHECK: noclobber.us:220; CHECK-NEXT: [[ADD_10_US:%.*]] = add i32 [[RED_US]], 10221; CHECK-NEXT: br label [[LOOP_LATCH_US]]222; CHECK: loop.latch.us:223; CHECK-NEXT: [[RED_NEXT_US]] = phi i32 [ [[ADD_10_US]], [[NOCLOBBER_US]] ]224; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]225; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1226; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]227; CHECK: exit.split.us:228; CHECK-NEXT: [[RED_NEXT_LCSSA_US:%.*]] = phi i32 [ [[RED_NEXT_US]], [[LOOP_LATCH_US]] ]229; CHECK-NEXT: br label [[EXIT:%.*]]230; CHECK: entry.split:231; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]232; CHECK: loop.header:233; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]234; CHECK-NEXT: [[RED:%.*]] = phi i32 [ 20, [[ENTRY_SPLIT]] ], [ [[RED_NEXT:%.*]], [[LOOP_LATCH]] ]235; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4236; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100237; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]238; CHECK: clobber:239; CHECK-NEXT: call void @clobber()240; CHECK-NEXT: [[ADD_5:%.*]] = add i32 [[RED]], 5241; CHECK-NEXT: br label [[LOOP_LATCH]]242; CHECK: noclobber:243; CHECK-NEXT: [[ADD_10:%.*]] = add i32 [[RED]], 10244; CHECK-NEXT: br label [[LOOP_LATCH]]245; CHECK: loop.latch:246; CHECK-NEXT: [[RED_NEXT]] = phi i32 [ [[ADD_5]], [[CLOBBER]] ], [ [[ADD_10]], [[NOCLOBBER]] ]247; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]248; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1249; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]]250; CHECK: exit.split:251; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP_LATCH]] ]252; CHECK-NEXT: br label [[EXIT]]253; CHECK: exit:254; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RED_NEXT_LCSSA]], [[EXIT_SPLIT]] ], [ [[RED_NEXT_LCSSA_US]], [[EXIT_SPLIT_US]] ]255; CHECK-NEXT: ret i32 [[DOTUS_PHI]]256;257entry:258 br label %loop.header259 260loop.header:261 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]262 %red = phi i32 [ 20, %entry ], [ %red.next, %loop.latch ]263 %lv = load i32, ptr %ptr264 %sc = icmp eq i32 %lv, 100265 br i1 %sc, label %clobber, label %noclobber266 267clobber:268 call void @clobber()269 %add.5 = add i32 %red, 5270 br label %loop.latch271 272noclobber:273 %add.10 = add i32 %red, 10274 br label %loop.latch275 276loop.latch:277 %red.next = phi i32 [ %add.5, %clobber ], [ %add.10, %noclobber ]278 %c = icmp ult i32 %iv, %N279 %iv.next = add i32 %iv, 1280 br i1 %c, label %loop.header, label %exit281 282exit:283 %red.next.lcssa = phi i32 [ %red.next, %loop.latch ]284 ret i32 %red.next.lcssa285}286 287; Partial unswitching is possible, because the store in %noclobber does not288; alias the load of the condition.289define i32 @partial_unswitch_true_successor_noclobber(ptr noalias %ptr.1, ptr noalias %ptr.2, i32 %N) {290; CHECK-LABEL: @partial_unswitch_true_successor_noclobber(291; CHECK-NEXT: entry:292; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR_1:%.*]], align 4293; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100294; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]295; CHECK: entry.split.us:296; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]297; CHECK: loop.header.us:298; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]299; CHECK-NEXT: [[LV_US:%.*]] = load i32, ptr [[PTR_1]], align 4300; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]301; CHECK: noclobber.us:302; CHECK-NEXT: [[GEP_1_US:%.*]] = getelementptr i32, ptr [[PTR_2:%.*]], i32 [[IV_US]]303; CHECK-NEXT: store i32 [[LV_US]], ptr [[GEP_1_US]], align 4304; CHECK-NEXT: br label [[LOOP_LATCH_US]]305; CHECK: loop.latch.us:306; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]307; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1308; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]309; CHECK: exit.split.us:310; CHECK-NEXT: br label [[EXIT:%.*]]311; CHECK: entry.split:312; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]313; CHECK: loop.header:314; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]315; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR_1]], align 4316; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100317; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]318; CHECK: noclobber:319; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[PTR_2]], i32 [[IV]]320; CHECK-NEXT: store i32 [[LV]], ptr [[GEP_1]], align 4321; CHECK-NEXT: br label [[LOOP_LATCH]]322; CHECK: clobber:323; CHECK-NEXT: call void @clobber()324; CHECK-NEXT: br label [[LOOP_LATCH]]325; CHECK: loop.latch:326; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]327; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1328; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]]329; CHECK: exit.split:330; CHECK-NEXT: br label [[EXIT]]331; CHECK: exit:332; CHECK-NEXT: ret i32 10333;334entry:335 br label %loop.header336 337loop.header:338 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]339 %lv = load i32, ptr %ptr.1340 %sc = icmp eq i32 %lv, 100341 br i1 %sc, label %noclobber, label %clobber342 343noclobber:344 %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv345 store i32 %lv, ptr %gep.1346 br label %loop.latch347 348clobber:349 call void @clobber()350 br label %loop.latch351 352loop.latch:353 %c = icmp ult i32 %iv, %N354 %iv.next = add i32 %iv, 1355 br i1 %c, label %loop.header, label %exit356 357exit:358 ret i32 10359}360 361define void @no_partial_unswitch_phi_cond(i1 %lc, i32 %N) {362; CHECK-LABEL: @no_partial_unswitch_phi_cond(363; CHECK-NEXT: entry:364; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]365; CHECK: loop.header:366; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]367; CHECK-NEXT: [[SC:%.*]] = phi i1 [ [[LC:%.*]], [[ENTRY]] ], [ true, [[LOOP_LATCH]] ]368; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]369; CHECK: clobber:370; CHECK-NEXT: call void @clobber()371; CHECK-NEXT: br label [[LOOP_LATCH]]372; CHECK: noclobber:373; CHECK-NEXT: br label [[LOOP_LATCH]]374; CHECK: loop.latch:375; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]376; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1377; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]378; CHECK: exit:379; CHECK-NEXT: ret void380;381entry:382 br label %loop.header383 384loop.header:385 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]386 %sc = phi i1 [ %lc, %entry ], [ true, %loop.latch ]387 br i1 %sc, label %clobber, label %noclobber388 389clobber:390 call void @clobber()391 br label %loop.latch392 393noclobber:394 br label %loop.latch395 396loop.latch:397 %c = icmp ult i32 %iv, %N398 %iv.next = add i32 %iv, 1399 br i1 %c, label %loop.header, label %exit400 401exit:402 ret void403}404 405define void @no_partial_unswitch_clobber_latch(ptr %ptr, i32 %N) {406; CHECK-LABEL: @no_partial_unswitch_clobber_latch(407; CHECK-NEXT: entry:408; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]409; CHECK: loop.header:410; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]411; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4412; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100413; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]414; CHECK: noclobber:415; CHECK-NEXT: br label [[LOOP_LATCH]]416; CHECK: clobber:417; CHECK-NEXT: call void @clobber()418; CHECK-NEXT: br label [[LOOP_LATCH]]419; CHECK: loop.latch:420; CHECK-NEXT: call void @clobber()421; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]422; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1423; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]424; CHECK: exit:425; CHECK-NEXT: ret void426;427entry:428 br label %loop.header429 430loop.header:431 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]432 %lv = load i32, ptr %ptr433 %sc = icmp eq i32 %lv, 100434 br i1 %sc, label %noclobber, label %clobber435 436noclobber:437 br label %loop.latch438 439clobber:440 call void @clobber()441 br label %loop.latch442 443loop.latch:444 call void @clobber()445 %c = icmp ult i32 %iv, %N446 %iv.next = add i32 %iv, 1447 br i1 %c, label %loop.header, label %exit448 449exit:450 ret void451}452 453define void @no_partial_unswitch_clobber_header(ptr %ptr, i32 %N) {454; CHECK-LABEL: @no_partial_unswitch_clobber_header(455; CHECK-NEXT: entry:456; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]457; CHECK: loop.header:458; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]459; CHECK-NEXT: call void @clobber()460; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4461; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100462; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]463; CHECK: noclobber:464; CHECK-NEXT: br label [[LOOP_LATCH]]465; CHECK: clobber:466; CHECK-NEXT: call void @clobber()467; CHECK-NEXT: br label [[LOOP_LATCH]]468; CHECK: loop.latch:469; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]470; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1471; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]472; CHECK: exit:473; CHECK-NEXT: ret void474;475entry:476 br label %loop.header477 478loop.header:479 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]480 call void @clobber()481 %lv = load i32, ptr %ptr482 %sc = icmp eq i32 %lv, 100483 br i1 %sc, label %noclobber, label %clobber484 485noclobber:486 br label %loop.latch487 488clobber:489 call void @clobber()490 br label %loop.latch491 492loop.latch:493 %c = icmp ult i32 %iv, %N494 %iv.next = add i32 %iv, 1495 br i1 %c, label %loop.header, label %exit496 497exit:498 ret void499}500 501define void @no_partial_unswitch_clobber_both(ptr %ptr, i32 %N) {502; CHECK-LABEL: @no_partial_unswitch_clobber_both(503; CHECK-NEXT: entry:504; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]505; CHECK: loop.header:506; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]507; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4508; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100509; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]510; CHECK: noclobber:511; CHECK-NEXT: call void @clobber()512; CHECK-NEXT: br label [[LOOP_LATCH]]513; CHECK: clobber:514; CHECK-NEXT: call void @clobber()515; CHECK-NEXT: br label [[LOOP_LATCH]]516; CHECK: loop.latch:517; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]518; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1519; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]520; CHECK: exit:521; CHECK-NEXT: ret void522;523entry:524 br label %loop.header525 526loop.header:527 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]528 %lv = load i32, ptr %ptr529 %sc = icmp eq i32 %lv, 100530 br i1 %sc, label %noclobber, label %clobber531 532noclobber:533 call void @clobber()534 br label %loop.latch535 536clobber:537 call void @clobber()538 br label %loop.latch539 540loop.latch:541 %c = icmp ult i32 %iv, %N542 %iv.next = add i32 %iv, 1543 br i1 %c, label %loop.header, label %exit544 545exit:546 ret void547}548 549define i32 @no_partial_unswitch_true_successor_storeclobber(ptr %ptr.1, ptr %ptr.2, i32 %N) {550; CHECK-LABEL: @no_partial_unswitch_true_successor_storeclobber(551; CHECK-NEXT: entry:552; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]553; CHECK: loop.header:554; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]555; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR_1:%.*]], align 4556; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100557; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]558; CHECK: noclobber:559; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i32, ptr [[PTR_2:%.*]], i32 [[IV]]560; CHECK-NEXT: store i32 [[LV]], ptr [[GEP_1]], align 4561; CHECK-NEXT: br label [[LOOP_LATCH]]562; CHECK: clobber:563; CHECK-NEXT: call void @clobber()564; CHECK-NEXT: br label [[LOOP_LATCH]]565; CHECK: loop.latch:566; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]567; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1568; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]569; CHECK: exit:570; CHECK-NEXT: ret i32 10571;572entry:573 br label %loop.header574 575loop.header:576 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]577 %lv = load i32, ptr %ptr.1578 %sc = icmp eq i32 %lv, 100579 br i1 %sc, label %noclobber, label %clobber580 581noclobber:582 %gep.1 = getelementptr i32, ptr %ptr.2, i32 %iv583 store i32 %lv, ptr %gep.1584 br label %loop.latch585 586clobber:587 call void @clobber()588 br label %loop.latch589 590loop.latch:591 %c = icmp ult i32 %iv, %N592 %iv.next = add i32 %iv, 1593 br i1 %c, label %loop.header, label %exit594 595exit:596 ret i32 10597}598 599; Make sure the duplicated instructions are moved to a preheader that always600; executes when the loop body also executes. Do not check the unswitched code,601; because it is already checked in the @partial_unswitch_true_successor test602; case.603define i32 @partial_unswitch_true_successor_preheader_insertion(ptr %ptr, i32 %N) {604; CHECK-LABEL: @partial_unswitch_true_successor_preheader_insertion(605; CHECK-NEXT: entry:606; CHECK-NEXT: [[EC:%.*]] = icmp ne ptr [[PTR:%.*]], null607; CHECK-NEXT: br i1 [[EC]], label [[LOOP_PH:%.*]], label [[EXIT:%.*]]608; CHECK: loop.ph:609; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR]], align 4610; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100611; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PH_SPLIT_US:%.*]], label [[LOOP_PH_SPLIT:%.*]]612; CHECK: loop.ph.split.us:613; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]614; CHECK: loop.header.us:615; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]616; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]617; CHECK: noclobber.us:618; CHECK-NEXT: br label [[LOOP_LATCH_US]]619; CHECK: loop.latch.us:620; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]621; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1622; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_LOOPEXIT_SPLIT_US:%.*]]623; CHECK: exit.loopexit.split.us:624; CHECK-NEXT: br label [[EXIT_LOOPEXIT:%.*]]625; CHECK: loop.ph.split:626; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]627; CHECK: loop.header:628; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]629; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4630; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100631; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]632; CHECK: noclobber:633; CHECK-NEXT: br label [[LOOP_LATCH]]634; CHECK: clobber:635; CHECK-NEXT: call void @clobber()636; CHECK-NEXT: br label [[LOOP_LATCH]]637; CHECK: loop.latch:638; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]639; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1640; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT_SPLIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]]641; CHECK: exit.loopexit.split:642; CHECK-NEXT: br label [[EXIT_LOOPEXIT]]643; CHECK: exit.loopexit:644; CHECK-NEXT: br label [[EXIT]]645; CHECK: exit:646; CHECK-NEXT: ret i32 10647;648 649entry:650 %ec = icmp ne ptr %ptr, null651 br i1 %ec, label %loop.ph, label %exit652 653loop.ph:654 br label %loop.header655 656loop.header:657 %iv = phi i32 [ 0, %loop.ph ], [ %iv.next, %loop.latch ]658 %lv = load i32, ptr %ptr659 %sc = icmp eq i32 %lv, 100660 br i1 %sc, label %noclobber, label %clobber661 662noclobber:663 br label %loop.latch664 665clobber:666 call void @clobber()667 br label %loop.latch668 669loop.latch:670 %c = icmp ult i32 %iv, %N671 %iv.next = add i32 %iv, 1672 br i1 %c, label %loop.header, label %exit673 674exit:675 ret i32 10676}677 678; Make sure the duplicated instructions are hoisted just before the branch of679; the preheader. Do not check the unswitched code, because it is already checked680; in the @partial_unswitch_true_successor test case681define i32 @partial_unswitch_true_successor_insert_point(ptr %ptr, i32 %N) {682; CHECK-LABEL: @partial_unswitch_true_successor_insert_point(683; CHECK-NEXT: entry:684; CHECK-NEXT: call void @clobber()685; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4686; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100687; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]688; CHECK: entry.split.us:689; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]690; CHECK: loop.header.us:691; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]692; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]693; CHECK: noclobber.us:694; CHECK-NEXT: br label [[LOOP_LATCH_US]]695; CHECK: loop.latch.us:696; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]697; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1698; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]699; CHECK: exit.split.us:700; CHECK-NEXT: br label [[EXIT:%.*]]701; CHECK: entry.split:702; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]703; CHECK: loop.header:704; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]705; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4706; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100707; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]708; CHECK: noclobber:709; CHECK-NEXT: br label [[LOOP_LATCH]]710; CHECK: clobber:711; CHECK-NEXT: call void @clobber()712; CHECK-NEXT: br label [[LOOP_LATCH]]713; CHECK: loop.latch:714; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]715; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1716; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP10:![0-9]+]]717; CHECK: exit.split:718; CHECK-NEXT: br label [[EXIT]]719; CHECK: exit:720; CHECK-NEXT: ret i32 10721;722entry:723 call void @clobber()724 br label %loop.header725 726loop.header:727 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]728 %lv = load i32, ptr %ptr729 %sc = icmp eq i32 %lv, 100730 br i1 %sc, label %noclobber, label %clobber731 732noclobber:733 br label %loop.latch734 735clobber:736 call void @clobber()737 br label %loop.latch738 739loop.latch:740 %c = icmp ult i32 %iv, %N741 %iv.next = add i32 %iv, 1742 br i1 %c, label %loop.header, label %exit743 744exit:745 ret i32 10746}747 748; Make sure invariant instructions in the loop are also hoisted to the preheader.749; Do not check the unswitched code, because it is already checked in the750; @partial_unswitch_true_successor test case751define i32 @partial_unswitch_true_successor_hoist_invariant(ptr %ptr, i32 %N) {752; CHECK-LABEL: @partial_unswitch_true_successor_hoist_invariant(753; CHECK-NEXT: entry:754; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i64 1755; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4756; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 100757; CHECK-NEXT: br i1 [[TMP2]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]758; CHECK: entry.split.us:759; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]760; CHECK: loop.header.us:761; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]762; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]763; CHECK: noclobber.us:764; CHECK-NEXT: br label [[LOOP_LATCH_US]]765; CHECK: loop.latch.us:766; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]767; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1768; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]769; CHECK: exit.split.us:770; CHECK-NEXT: br label [[EXIT:%.*]]771; CHECK: entry.split:772; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]773; CHECK: loop.header:774; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]775; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i64 1776; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4777; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100778; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]779; CHECK: noclobber:780; CHECK-NEXT: br label [[LOOP_LATCH]]781; CHECK: clobber:782; CHECK-NEXT: call void @clobber()783; CHECK-NEXT: br label [[LOOP_LATCH]]784; CHECK: loop.latch:785; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]786; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1787; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]]788; CHECK: exit.split:789; CHECK-NEXT: br label [[EXIT]]790; CHECK: exit:791; CHECK-NEXT: ret i32 10792;793entry:794 br label %loop.header795 796loop.header:797 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]798 %gep = getelementptr i32, ptr %ptr, i64 1799 %lv = load i32, ptr %gep800 %sc = icmp eq i32 %lv, 100801 br i1 %sc, label %noclobber, label %clobber802 803noclobber:804 br label %loop.latch805 806clobber:807 call void @clobber()808 br label %loop.latch809 810loop.latch:811 %c = icmp ult i32 %iv, %N812 %iv.next = add i32 %iv, 1813 br i1 %c, label %loop.header, label %exit814 815exit:816 ret i32 10817}818 819; Do not unswitch if the condition depends on an atomic load. Duplicating such820; loads is not safe.821define i32 @no_partial_unswitch_atomic_load_unordered(ptr %ptr, i32 %N) {822; CHECK-LABEL: @no_partial_unswitch_atomic_load_unordered(823; CHECK-NEXT: entry:824; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]825; CHECK: loop.header:826; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]827; CHECK-NEXT: [[LV:%.*]] = load atomic i32, ptr [[PTR:%.*]] unordered, align 4828; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100829; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]830; CHECK: noclobber:831; CHECK-NEXT: br label [[LOOP_LATCH]]832; CHECK: clobber:833; CHECK-NEXT: call void @clobber()834; CHECK-NEXT: br label [[LOOP_LATCH]]835; CHECK: loop.latch:836; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]837; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1838; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]839; CHECK: exit:840; CHECK-NEXT: ret i32 10841;842entry:843 br label %loop.header844 845loop.header:846 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]847 %lv = load atomic i32, ptr %ptr unordered, align 4848 %sc = icmp eq i32 %lv, 100849 br i1 %sc, label %noclobber, label %clobber850 851noclobber:852 br label %loop.latch853 854clobber:855 call void @clobber()856 br label %loop.latch857 858loop.latch:859 %c = icmp ult i32 %iv, %N860 %iv.next = add i32 %iv, 1861 br i1 %c, label %loop.header, label %exit862 863exit:864 ret i32 10865}866 867; Do not unswitch if the condition depends on an atomic load. Duplicating such868; loads is not safe.869define i32 @no_partial_unswitch_atomic_load_monotonic(ptr %ptr, i32 %N) {870; CHECK-LABEL: @no_partial_unswitch_atomic_load_monotonic(871; CHECK-NEXT: entry:872; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]873; CHECK: loop.header:874; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]875; CHECK-NEXT: [[LV:%.*]] = load atomic i32, ptr [[PTR:%.*]] monotonic, align 4876; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100877; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]878; CHECK: noclobber:879; CHECK-NEXT: br label [[LOOP_LATCH]]880; CHECK: clobber:881; CHECK-NEXT: call void @clobber()882; CHECK-NEXT: br label [[LOOP_LATCH]]883; CHECK: loop.latch:884; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]885; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1886; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]887; CHECK: exit:888; CHECK-NEXT: ret i32 10889;890entry:891 br label %loop.header892 893loop.header:894 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]895 %lv = load atomic i32, ptr %ptr monotonic, align 4896 %sc = icmp eq i32 %lv, 100897 br i1 %sc, label %noclobber, label %clobber898 899noclobber:900 br label %loop.latch901 902clobber:903 call void @clobber()904 br label %loop.latch905 906loop.latch:907 %c = icmp ult i32 %iv, %N908 %iv.next = add i32 %iv, 1909 br i1 %c, label %loop.header, label %exit910 911exit:912 ret i32 10913}914 915 916declare i32 @get_value()917 918; Do not unswitch if the condition depends on a call, that may clobber memory.919; Duplicating such a call is not safe.920define i32 @no_partial_unswitch_cond_call(ptr %ptr, i32 %N) {921; CHECK-LABEL: @no_partial_unswitch_cond_call(922; CHECK-NEXT: entry:923; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]924; CHECK: loop.header:925; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]926; CHECK-NEXT: [[LV:%.*]] = call i32 @get_value()927; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100928; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]929; CHECK: noclobber:930; CHECK-NEXT: br label [[LOOP_LATCH]]931; CHECK: clobber:932; CHECK-NEXT: call void @clobber()933; CHECK-NEXT: br label [[LOOP_LATCH]]934; CHECK: loop.latch:935; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]936; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1937; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]938; CHECK: exit:939; CHECK-NEXT: ret i32 10940;941entry:942 br label %loop.header943 944loop.header:945 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]946 %lv = call i32 @get_value()947 %sc = icmp eq i32 %lv, 100948 br i1 %sc, label %noclobber, label %clobber949 950noclobber:951 br label %loop.latch952 953clobber:954 call void @clobber()955 br label %loop.latch956 957loop.latch:958 %c = icmp ult i32 %iv, %N959 %iv.next = add i32 %iv, 1960 br i1 %c, label %loop.header, label %exit961 962exit:963 ret i32 10964}965 966define i32 @no_partial_unswitch_true_successor_exit(ptr %ptr, i32 %N) {967; CHECK-LABEL: @no_partial_unswitch_true_successor_exit(968; CHECK-NEXT: entry:969; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]970; CHECK: loop.header:971; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]972; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 4973; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100974; CHECK-NEXT: br i1 [[SC]], label [[EXIT:%.*]], label [[CLOBBER:%.*]]975; CHECK: clobber:976; CHECK-NEXT: call void @clobber()977; CHECK-NEXT: br label [[LOOP_LATCH]]978; CHECK: loop.latch:979; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]980; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1981; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT]]982; CHECK: exit:983; CHECK-NEXT: ret i32 10984;985entry:986 br label %loop.header987 988loop.header:989 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]990 %lv = load i32, ptr %ptr991 %sc = icmp eq i32 %lv, 100992 br i1 %sc, label %exit, label %clobber993 994clobber:995 call void @clobber()996 br label %loop.latch997 998loop.latch:999 %c = icmp ult i32 %iv, %N1000 %iv.next = add i32 %iv, 11001 br i1 %c, label %loop.header, label %exit1002 1003exit:1004 ret i32 101005}1006 1007define i32 @no_partial_unswitch_true_same_successor(ptr %ptr, i32 %N) {1008; CHECK-LABEL: @no_partial_unswitch_true_same_successor(1009; CHECK-NEXT: entry:1010; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1011; CHECK: loop.header:1012; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1013; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR:%.*]], align 41014; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 1001015; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[NOCLOBBER]]1016; CHECK: noclobber:1017; CHECK-NEXT: br label [[LOOP_LATCH]]1018; CHECK: loop.latch:1019; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]1020; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 11021; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT:%.*]]1022; CHECK: exit:1023; CHECK-NEXT: ret i32 101024;1025entry:1026 br label %loop.header1027 1028loop.header:1029 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]1030 %lv = load i32, ptr %ptr1031 %sc = icmp eq i32 %lv, 1001032 br i1 %sc, label %noclobber, label %noclobber1033 1034noclobber:1035 br label %loop.latch1036 1037loop.latch:1038 %c = icmp ult i32 %iv, %N1039 %iv.next = add i32 %iv, 11040 br i1 %c, label %loop.header, label %exit1041 1042exit:1043 ret i32 101044}1045 1046define i32 @partial_unswitch_true_to_latch(ptr %ptr, i32 %N) {1047; CHECK-LABEL: @partial_unswitch_true_to_latch(1048; CHECK-NEXT: entry:1049; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 41050; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 1001051; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]1052; CHECK: entry.split.us:1053; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]1054; CHECK: loop.header.us:1055; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]1056; CHECK-NEXT: br label [[LOOP_LATCH_US]]1057; CHECK: loop.latch.us:1058; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]1059; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 11060; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]1061; CHECK: exit.split.us:1062; CHECK-NEXT: br label [[EXIT:%.*]]1063; CHECK: entry.split:1064; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1065; CHECK: loop.header:1066; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1067; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 41068; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 1001069; CHECK-NEXT: br i1 [[SC]], label [[LOOP_LATCH]], label [[CLOBBER:%.*]]1070; CHECK: clobber:1071; CHECK-NEXT: call void @clobber()1072; CHECK-NEXT: br label [[LOOP_LATCH]]1073; CHECK: loop.latch:1074; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]1075; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 11076; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]]1077; CHECK: exit.split:1078; CHECK-NEXT: br label [[EXIT]]1079; CHECK: exit:1080; CHECK-NEXT: ret i32 101081;1082entry:1083 br label %loop.header1084 1085loop.header:1086 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]1087 %lv = load i32, ptr %ptr1088 %sc = icmp eq i32 %lv, 1001089 br i1 %sc, label %loop.latch, label %clobber1090 1091clobber:1092 call void @clobber()1093 br label %loop.latch1094 1095loop.latch:1096 %c = icmp ult i32 %iv, %N1097 %iv.next = add i32 %iv, 11098 br i1 %c, label %loop.header, label %exit1099 1100exit:1101 ret i32 101102}1103 1104; There could be multiple unswitch candidates which include partially invariant1105; condition. When the exiting block is selected as best unswitch one, clone loop1106; blocks.1107define i32 @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(i32 %0, i32 %1, ptr %ptr) {1108; CHECK-LABEL: @partial_unswitch_exiting_block_with_multiple_unswitch_candidates(1109; CHECK-NEXT: entry:1110; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp ne i32 [[TMP0:%.*]], 01111; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[PTR:%.*]], align 161112; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[TMP2]], 411113; CHECK-NEXT: br i1 [[TMP3]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]1114; CHECK: entry.split.us:1115; CHECK-NEXT: br i1 [[EXIT_COND]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]]1116; CHECK: entry.split.us.split.us:1117; CHECK-NEXT: br label [[LOOP_US_US:%.*]]1118; CHECK: loop.us.us:1119; CHECK-NEXT: br label [[EXITING_US_US:%.*]]1120; CHECK: exiting.us.us:1121; CHECK-NEXT: br label [[LOOP_US_US]]1122; CHECK: entry.split.us.split:1123; CHECK-NEXT: br label [[LOOP_US:%.*]]1124; CHECK: loop.us:1125; CHECK-NEXT: br label [[EXITING_US:%.*]]1126; CHECK: exiting.us:1127; CHECK-NEXT: br label [[EXIT_SPLIT_US:%.*]]1128; CHECK: exit.split.us:1129; CHECK-NEXT: [[RET_VAL_US:%.*]] = phi i32 [ 1, [[EXITING_US]] ]1130; CHECK-NEXT: br label [[EXIT:%.*]]1131; CHECK: entry.split:1132; CHECK-NEXT: br label [[LOOP:%.*]]1133; CHECK: loop:1134; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[PTR]], align 161135; CHECK-NEXT: [[IF_COND:%.*]] = icmp ult i32 [[VAL]], 411136; CHECK-NEXT: br i1 [[IF_COND]], label [[IF_THEN:%.*]], label [[EXITING:%.*]]1137; CHECK: if.then:1138; CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[PTR]], align 161139; CHECK-NEXT: br label [[EXITING]]1140; CHECK: exiting:1141; CHECK-NEXT: br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP13:![0-9]+]]1142; CHECK: exit.split:1143; CHECK-NEXT: [[RET_VAL:%.*]] = phi i32 [ 1, [[EXITING]] ]1144; CHECK-NEXT: br label [[EXIT]]1145; CHECK: exit:1146; CHECK-NEXT: [[DOTUS_PHI:%.*]] = phi i32 [ [[RET_VAL]], [[EXIT_SPLIT]] ], [ [[RET_VAL_US]], [[EXIT_SPLIT_US]] ]1147; CHECK-NEXT: ret i32 [[DOTUS_PHI]]1148;1149entry:1150 %exit.cond = icmp ne i32 %0, 01151 br label %loop1152 1153loop:1154 %val = load i32, ptr %ptr, align 161155 %if.cond = icmp ult i32 %val, 411156 br i1 %if.cond, label %if.then, label %exiting1157 1158if.then:1159 store i32 %1, ptr %ptr, align 161160 br label %exiting1161 1162exiting:1163 br i1 %exit.cond, label %loop, label %exit1164 1165exit:1166 %ret.val = phi i32 [ 1, %exiting ]1167 ret i32 %ret.val1168}1169 1170; The path with noclobber block is only duplicated so we need to calculate only1171; the cost of the path with noclobber.1172define i32 @partial_unswitch_true_successor_for_cost_calculation(ptr %ptr, i32 %N) {1173; CHECK-LABEL: @partial_unswitch_true_successor_for_cost_calculation(1174; CHECK-NEXT: entry:1175; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 41176; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 1001177; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]1178; CHECK: entry.split.us:1179; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]1180; CHECK: loop.header.us:1181; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]1182; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]1183; CHECK: noclobber.us:1184; CHECK-NEXT: br label [[LOOP_LATCH_US]]1185; CHECK: loop.latch.us:1186; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]1187; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 11188; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]1189; CHECK: exit.split.us:1190; CHECK-NEXT: br label [[EXIT:%.*]]1191; CHECK: entry.split:1192; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1193; CHECK: loop.header:1194; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1195; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 41196; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 1001197; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]1198; CHECK: noclobber:1199; CHECK-NEXT: br label [[LOOP_LATCH]]1200; CHECK: clobber:1201; CHECK-NEXT: call void @clobber()1202; CHECK-NEXT: call void @clobber()1203; CHECK-NEXT: call void @clobber()1204; CHECK-NEXT: call void @clobber()1205; CHECK-NEXT: call void @clobber()1206; CHECK-NEXT: call void @clobber()1207; CHECK-NEXT: call void @clobber()1208; CHECK-NEXT: call void @clobber()1209; CHECK-NEXT: call void @clobber()1210; CHECK-NEXT: call void @clobber()1211; CHECK-NEXT: call void @clobber()1212; CHECK-NEXT: call void @clobber()1213; CHECK-NEXT: call void @clobber()1214; CHECK-NEXT: call void @clobber()1215; CHECK-NEXT: call void @clobber()1216; CHECK-NEXT: call void @clobber()1217; CHECK-NEXT: call void @clobber()1218; CHECK-NEXT: call void @clobber()1219; CHECK-NEXT: call void @clobber()1220; CHECK-NEXT: call void @clobber()1221; CHECK-NEXT: call void @clobber()1222; CHECK-NEXT: call void @clobber()1223; CHECK-NEXT: call void @clobber()1224; CHECK-NEXT: call void @clobber()1225; CHECK-NEXT: call void @clobber()1226; CHECK-NEXT: call void @clobber()1227; CHECK-NEXT: call void @clobber()1228; CHECK-NEXT: call void @clobber()1229; CHECK-NEXT: call void @clobber()1230; CHECK-NEXT: call void @clobber()1231; CHECK-NEXT: call void @clobber()1232; CHECK-NEXT: call void @clobber()1233; CHECK-NEXT: call void @clobber()1234; CHECK-NEXT: call void @clobber()1235; CHECK-NEXT: call void @clobber()1236; CHECK-NEXT: call void @clobber()1237; CHECK-NEXT: call void @clobber()1238; CHECK-NEXT: call void @clobber()1239; CHECK-NEXT: call void @clobber()1240; CHECK-NEXT: call void @clobber()1241; CHECK-NEXT: call void @clobber()1242; CHECK-NEXT: call void @clobber()1243; CHECK-NEXT: call void @clobber()1244; CHECK-NEXT: call void @clobber()1245; CHECK-NEXT: call void @clobber()1246; CHECK-NEXT: call void @clobber()1247; CHECK-NEXT: call void @clobber()1248; CHECK-NEXT: br label [[LOOP_LATCH]]1249; CHECK: loop.latch:1250; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]1251; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 11252; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP14:![0-9]+]]1253; CHECK: exit.split:1254; CHECK-NEXT: br label [[EXIT]]1255; CHECK: exit:1256; CHECK-NEXT: ret i32 101257;1258entry:1259 br label %loop.header1260 1261loop.header:1262 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]1263 %lv = load i32, ptr %ptr1264 %sc = icmp eq i32 %lv, 1001265 br i1 %sc, label %noclobber, label %clobber1266 1267noclobber:1268 br label %loop.latch1269 1270clobber:1271 call void @clobber()1272 call void @clobber()1273 call void @clobber()1274 call void @clobber()1275 call void @clobber()1276 call void @clobber()1277 call void @clobber()1278 call void @clobber()1279 call void @clobber()1280 call void @clobber()1281 call void @clobber()1282 call void @clobber()1283 call void @clobber()1284 call void @clobber()1285 call void @clobber()1286 call void @clobber()1287 call void @clobber()1288 call void @clobber()1289 call void @clobber()1290 call void @clobber()1291 call void @clobber()1292 call void @clobber()1293 call void @clobber()1294 call void @clobber()1295 call void @clobber()1296 call void @clobber()1297 call void @clobber()1298 call void @clobber()1299 call void @clobber()1300 call void @clobber()1301 call void @clobber()1302 call void @clobber()1303 call void @clobber()1304 call void @clobber()1305 call void @clobber()1306 call void @clobber()1307 call void @clobber()1308 call void @clobber()1309 call void @clobber()1310 call void @clobber()1311 call void @clobber()1312 call void @clobber()1313 call void @clobber()1314 call void @clobber()1315 call void @clobber()1316 call void @clobber()1317 call void @clobber()1318 br label %loop.latch1319 1320loop.latch:1321 %c = icmp ult i32 %iv, %N1322 %iv.next = add i32 %iv, 11323 br i1 %c, label %loop.header, label %exit1324 1325exit:1326 ret i32 101327}1328 1329define i32 @partial_unswitch_true_successor_trunc(ptr %ptr, i32 %N) {1330; CHECK-LABEL: @partial_unswitch_true_successor_trunc(1331; CHECK-NEXT: entry:1332; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 41333; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i11334; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]1335; CHECK: entry.split.us:1336; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]1337; CHECK: loop.header.us:1338; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]1339; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]1340; CHECK: noclobber.us:1341; CHECK-NEXT: br label [[LOOP_LATCH_US]]1342; CHECK: loop.latch.us:1343; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]1344; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 11345; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]1346; CHECK: exit.split.us:1347; CHECK-NEXT: br label [[EXIT:%.*]]1348; CHECK: entry.split:1349; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1350; CHECK: loop.header:1351; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1352; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 41353; CHECK-NEXT: [[SC:%.*]] = trunc i32 [[LV]] to i11354; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]]1355; CHECK: noclobber:1356; CHECK-NEXT: br label [[LOOP_LATCH]]1357; CHECK: clobber:1358; CHECK-NEXT: call void @clobber()1359; CHECK-NEXT: br label [[LOOP_LATCH]]1360; CHECK: loop.latch:1361; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]1362; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 11363; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP15:![0-9]+]]1364; CHECK: exit.split:1365; CHECK-NEXT: br label [[EXIT]]1366; CHECK: exit:1367; CHECK-NEXT: ret i32 101368;1369entry:1370 br label %loop.header1371 1372loop.header:1373 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]1374 %lv = load i32, ptr %ptr1375 %sc = trunc i32 %lv to i11376 br i1 %sc, label %noclobber, label %clobber1377 1378noclobber:1379 br label %loop.latch1380 1381clobber:1382 call void @clobber()1383 br label %loop.latch1384 1385loop.latch:1386 %c = icmp ult i32 %iv, %N1387 %iv.next = add i32 %iv, 11388 br i1 %c, label %loop.header, label %exit1389 1390exit:1391 ret i32 101392}1393 1394define i32 @partial_unswitch_false_successor_trunc(ptr %ptr, i32 %N) {1395; CHECK-LABEL: @partial_unswitch_false_successor_trunc(1396; CHECK-NEXT: entry:1397; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 41398; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i11399; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT:%.*]], label [[ENTRY_SPLIT_US:%.*]]1400; CHECK: entry.split.us:1401; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]]1402; CHECK: loop.header.us:1403; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ]1404; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]]1405; CHECK: noclobber.us:1406; CHECK-NEXT: br label [[LOOP_LATCH_US]]1407; CHECK: loop.latch.us:1408; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]]1409; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 11410; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]]1411; CHECK: exit.split.us:1412; CHECK-NEXT: br label [[EXIT:%.*]]1413; CHECK: entry.split:1414; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1415; CHECK: loop.header:1416; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1417; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 41418; CHECK-NEXT: [[SC:%.*]] = trunc i32 [[LV]] to i11419; CHECK-NEXT: br i1 [[SC]], label [[CLOBBER:%.*]], label [[NOCLOBBER:%.*]]1420; CHECK: clobber:1421; CHECK-NEXT: call void @clobber()1422; CHECK-NEXT: br label [[LOOP_LATCH]]1423; CHECK: noclobber:1424; CHECK-NEXT: br label [[LOOP_LATCH]]1425; CHECK: loop.latch:1426; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]]1427; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 11428; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP16:![0-9]+]]1429; CHECK: exit.split:1430; CHECK-NEXT: br label [[EXIT]]1431; CHECK: exit:1432; CHECK-NEXT: ret i32 101433;1434entry:1435 br label %loop.header1436 1437loop.header:1438 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]1439 %lv = load i32, ptr %ptr1440 %sc = trunc i32 %lv to i11441 br i1 %sc, label %clobber, label %noclobber1442 1443clobber:1444 call void @clobber()1445 br label %loop.latch1446 1447noclobber:1448 br label %loop.latch1449 1450loop.latch:1451 %c = icmp ult i32 %iv, %N1452 %iv.next = add i32 %iv, 11453 br i1 %c, label %loop.header, label %exit1454 1455exit:1456 ret i32 101457}1458 1459!0 = !{!"function_entry_count", i32 10}1460!1 = !{!"branch_weights", i32 1000, i32 1}1461!2 = !{!"branch_weights", i32 100, i32 3}1462 1463;.1464; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}1465; CHECK: [[PROF1]] = !{!"branch_weights", i32 1000, i32 1}1466; CHECK: [[PROF2]] = !{!"branch_weights", i32 100, i32 3}1467; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]]}1468; CHECK: [[META4]] = !{!"llvm.loop.unswitch.partial.disable"}1469; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META4]]}1470; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META4]]}1471; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META4]]}1472; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META4]]}1473; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META4]]}1474; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META4]]}1475; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META4]]}1476; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META4]]}1477; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META4]]}1478; CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META4]]}1479; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META4]]}1480; CHECK: [[LOOP16]] = distinct !{[[LOOP16]], [[META4]]}1481;.1482