625 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=loop-unroll -S %s | FileCheck %s3 4declare void @foo()5 6define i32 @peel_readonly_to_make_loads_derefenceable(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) {7; CHECK-LABEL: @peel_readonly_to_make_loads_derefenceable(8; CHECK-NEXT: entry:9; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_BEGIN:%.*]]10; CHECK: loop.header.peel.begin:11; CHECK-NEXT: br label [[LOOP_HEADER_PEEL:%.*]]12; CHECK: loop.header.peel:13; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN_PEEL:%.*]], label [[UNREACHABLE_EXIT:%.*]]14; CHECK: then.peel:15; CHECK-NEXT: [[I_PEEL:%.*]] = load i32, ptr [[INV:%.*]], align 416; CHECK-NEXT: [[C_2_PEEL:%.*]] = icmp ult i32 [[I_PEEL]], 217; CHECK-NEXT: br i1 [[C_2_PEEL]], label [[LOOP_LATCH_PEEL:%.*]], label [[UNREACHABLE_EXIT]]18; CHECK: loop.latch.peel:19; CHECK-NEXT: [[GEP_PEEL:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 120; CHECK-NEXT: [[LV_PEEL:%.*]] = load i32, ptr [[GEP_PEEL]], align 421; CHECK-NEXT: [[SUM_NEXT_PEEL:%.*]] = add i32 0, [[LV_PEEL]]22; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add nuw nsw i32 1, 123; CHECK-NEXT: [[C_3_PEEL:%.*]] = icmp ult i32 1, 100024; CHECK-NEXT: br i1 [[C_3_PEEL]], label [[LOOP_HEADER_PEEL_NEXT:%.*]], label [[EXIT:%.*]]25; CHECK: loop.header.peel.next:26; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_NEXT1:%.*]]27; CHECK: loop.header.peel.next1:28; CHECK-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]]29; CHECK: entry.peel.newph:30; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]31; CHECK: loop.header:32; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]33; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ [[SUM_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]34; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT_LOOPEXIT:%.*]]35; CHECK: then:36; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV]], align 437; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 238; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT_LOOPEXIT]]39; CHECK: loop.latch:40; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[IV]]41; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 442; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]43; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 144; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 100045; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]46; CHECK: exit.loopexit:47; CHECK-NEXT: [[SUM_NEXT_LCSSA_PH:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]48; CHECK-NEXT: br label [[EXIT]]49; CHECK: exit:50; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT_PEEL]], [[LOOP_LATCH_PEEL]] ], [ [[SUM_NEXT_LCSSA_PH]], [[EXIT_LOOPEXIT]] ]51; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]52; CHECK: unreachable.exit.loopexit:53; CHECK-NEXT: br label [[UNREACHABLE_EXIT]]54; CHECK: unreachable.exit:55; CHECK-NEXT: call void @foo()56; CHECK-NEXT: unreachable57;58entry:59 br label %loop.header60 61loop.header:62 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]63 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]64 br i1 %c.1, label %then, label %unreachable.exit65 66then:67 %i = load i32, ptr %inv68 %c.2 = icmp ult i32 %i, 269 br i1 %c.2, label %loop.latch, label %unreachable.exit70 71loop.latch:72 %gep = getelementptr i32, ptr %ptr, i32 %iv73 %lv = load i32, ptr %gep74 %sum.next = add i32 %sum, %lv75 %iv.next = add nuw nsw i32 %iv, 176 %c.3 = icmp ult i32 %iv, 100077 br i1 %c.3, label %loop.header, label %exit78 79exit:80 ret i32 %sum.next81 82unreachable.exit:83 call void @foo()84 unreachable85}86 87define i32 @peel_readonly_to_make_loads_derefenceable_exits_lead_to_unreachable(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) {88; CHECK-LABEL: @peel_readonly_to_make_loads_derefenceable_exits_lead_to_unreachable(89; CHECK-NEXT: entry:90; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]91; CHECK: loop.header:92; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]93; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]94; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT_2:%.*]]95; CHECK: then:96; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 497; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 298; CHECK-NEXT: br i1 [[C_2]], label [[THEN_2:%.*]], label [[EXIT_2]]99; CHECK: then.2:100; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[I]], 4101; CHECK-NEXT: br i1 [[C_4]], label [[LOOP_LATCH]], label [[EXIT_3:%.*]]102; CHECK: loop.latch:103; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]104; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4105; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]106; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1107; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000108; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]109; CHECK: exit:110; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]111; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]112; CHECK: exit.2:113; CHECK-NEXT: br label [[UNREACHABLE_BB:%.*]]114; CHECK: exit.3:115; CHECK-NEXT: br label [[UNREACHABLE_BB]]116; CHECK: unreachable.bb:117; CHECK-NEXT: call void @foo()118; CHECK-NEXT: unreachable119;120entry:121 br label %loop.header122 123loop.header:124 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]125 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]126 br i1 %c.1, label %then, label %exit.2127 128then:129 %i = load i32, ptr %inv130 %c.2 = icmp ult i32 %i, 2131 br i1 %c.2, label %then.2, label %exit.2132 133then.2:134 %c.4 = icmp ult i32 %i, 4135 br i1 %c.4, label %loop.latch, label %exit.3136 137loop.latch:138 %gep = getelementptr i32, ptr %ptr, i32 %iv139 %lv = load i32, ptr %gep140 %sum.next = add i32 %sum, %lv141 %iv.next = add nuw nsw i32 %iv, 1142 %c.3 = icmp ult i32 %iv, 1000143 br i1 %c.3, label %loop.header, label %exit144 145exit:146 ret i32 %sum.next147 148exit.2:149 br label %unreachable.bb150 151exit.3:152 br label %unreachable.bb153 154unreachable.bb:155 call void @foo()156 unreachable157}158 159define i32 @do_not_peel_readonly_load_in_header(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) {160; CHECK-LABEL: @do_not_peel_readonly_load_in_header(161; CHECK-NEXT: entry:162; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]163; CHECK: loop.header:164; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]165; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]166; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4167; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2168; CHECK-NEXT: br i1 [[C_2]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]]169; CHECK: then:170; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]171; CHECK: loop.latch:172; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]173; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4174; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]175; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1176; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000177; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]178; CHECK: exit:179; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]180; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]181; CHECK: unreachable.exit:182; CHECK-NEXT: call void @foo()183; CHECK-NEXT: unreachable184;185entry:186 br label %loop.header187 188loop.header:189 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]190 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]191 %i = load i32, ptr %inv192 %c.2 = icmp ult i32 %i, 2193 br i1 %c.2, label %then, label %unreachable.exit194 195then:196 br i1 %c.1, label %loop.latch, label %unreachable.exit197 198loop.latch:199 %gep = getelementptr i32, ptr %ptr, i32 %iv200 %lv = load i32, ptr %gep201 %sum.next = add i32 %sum, %lv202 %iv.next = add nuw nsw i32 %iv, 1203 %c.3 = icmp ult i32 %iv, 1000204 br i1 %c.3, label %loop.header, label %exit205 206exit:207 ret i32 %sum.next208 209unreachable.exit:210 call void @foo()211 unreachable212}213 214define i32 @do_not_peel_readonly_but_wont_turn_dereferenceable(ptr %ptr, i32 %N, i32 %x, ptr %inv) {215; CHECK-LABEL: @do_not_peel_readonly_but_wont_turn_dereferenceable(216; CHECK-NEXT: entry:217; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]218; CHECK: loop.header:219; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]220; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]221; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[IV]], [[X:%.*]]222; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]223; CHECK: then:224; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4225; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[I]], 20226; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH]]227; CHECK: else:228; CHECK-NEXT: br label [[LOOP_LATCH]]229; CHECK: loop.latch:230; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[I]], [[THEN]] ], [ 0, [[ELSE]] ]231; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]232; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4233; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[LV]], [[P]]234; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[ADD_1]]235; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1236; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000237; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]238; CHECK: exit:239; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]240; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]241; CHECK: unreachable.exit:242; CHECK-NEXT: call void @foo()243; CHECK-NEXT: unreachable244;245entry:246 br label %loop.header247 248loop.header:249 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]250 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]251 %c.1 = icmp eq i32 %iv, %x252 br i1 %c.1, label %then, label %else253 254then:255 %i = load i32, ptr %inv256 %c.2 = icmp eq i32 %i, 20257 br i1 %c.2, label %unreachable.exit, label %loop.latch258 259else:260 br label %loop.latch261 262loop.latch:263 %p = phi i32 [ %i, %then ], [ 0, %else ]264 %gep = getelementptr i32, ptr %ptr, i32 %iv265 %lv = load i32, ptr %gep266 %add.1 = add i32 %lv, %p267 %sum.next = add i32 %sum, %add.1268 %iv.next = add nuw nsw i32 %iv, 1269 %c.3 = icmp ult i32 %iv, 1000270 br i1 %c.3, label %loop.header, label %exit271 272exit:273 ret i32 %sum.next274 275unreachable.exit:276 call void @foo()277 unreachable278}279 280define i32 @do_not_peel_write1(ptr %ptr, i32 %N, i32 %x, ptr %inv, ptr %dst, i1 %c.1) {281; CHECK-LABEL: @do_not_peel_write1(282; CHECK-NEXT: entry:283; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]284; CHECK: loop.header:285; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]286; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]287; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]]288; CHECK: then:289; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4290; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2291; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]292; CHECK: loop.latch:293; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]294; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4295; CHECK-NEXT: store i32 [[LV]], ptr [[DST:%.*]], align 4296; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]297; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1298; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000299; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]300; CHECK: exit:301; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]302; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]303; CHECK: unreachable.exit:304; CHECK-NEXT: call void @foo()305; CHECK-NEXT: unreachable306;307entry:308 br label %loop.header309 310loop.header:311 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]312 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]313 br i1 %c.1, label %then, label %unreachable.exit314 315then:316 %i = load i32, ptr %inv317 %c.2 = icmp ult i32 %i, 2318 br i1 %c.2, label %loop.latch, label %unreachable.exit319 320loop.latch:321 %gep = getelementptr i32, ptr %ptr, i32 %iv322 %lv = load i32, ptr %gep323 store i32 %lv, ptr %dst324 %sum.next = add i32 %sum, %lv325 %iv.next = add nuw nsw i32 %iv, 1326 %c.3 = icmp ult i32 %iv, 1000327 br i1 %c.3, label %loop.header, label %exit328 329exit:330 ret i32 %sum.next331 332unreachable.exit:333 call void @foo()334 unreachable335}336 337define i32 @do_not_peel_write2(ptr %ptr, i32 %N, ptr %inv, ptr %dst) {338; CHECK-LABEL: @do_not_peel_write2(339; CHECK-NEXT: entry:340; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]341; CHECK: loop.header:342; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]343; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]344; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4345; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[I]], 20346; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]347; CHECK: then:348; CHECK-NEXT: store i32 [[I]], ptr [[DST:%.*]], align 4349; CHECK-NEXT: br label [[LOOP_LATCH]]350; CHECK: else:351; CHECK-NEXT: br label [[UNREACHABLE_EXIT:%.*]]352; CHECK: loop.latch:353; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]354; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4355; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[LV]], [[I]]356; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[ADD_1]]357; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1358; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000359; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]360; CHECK: exit:361; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]362; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]363; CHECK: unreachable.exit:364; CHECK-NEXT: call void @foo()365; CHECK-NEXT: unreachable366;367entry:368 br label %loop.header369 370loop.header:371 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]372 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]373 %i = load i32, ptr %inv374 %c.1 = icmp eq i32 %i, 20375 br i1 %c.1, label %then, label %else376 377then:378 store i32 %i, ptr %dst379 br label %loop.latch380 381else:382 br label %unreachable.exit383 384loop.latch:385 %gep = getelementptr i32, ptr %ptr, i32 %iv386 %lv = load i32, ptr %gep387 %add.1 = add i32 %lv, %i388 %sum.next = add i32 %sum, %add.1389 %iv.next = add nuw nsw i32 %iv, 1390 %c.3 = icmp ult i32 %iv, 1000391 br i1 %c.3, label %loop.header, label %exit392 393exit:394 ret i32 %sum.next395 396unreachable.exit:397 call void @foo()398 unreachable399}400 401declare i32 @llvm.experimental.deoptimize.i32(...)402 403define i32 @peel_with_deopt_exit(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) {404; CHECK-LABEL: @peel_with_deopt_exit(405; CHECK-NEXT: entry:406; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]407; CHECK: loop.header:408; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]409; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]410; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[DEOPT_EXIT:%.*]]411; CHECK: then:412; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4413; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2414; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[DEOPT_EXIT]]415; CHECK: loop.latch:416; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]417; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4418; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]419; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1420; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000421; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]422; CHECK: exit:423; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]424; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]425; CHECK: deopt.exit:426; CHECK-NEXT: [[SUM_LCSSA:%.*]] = phi i32 [ [[SUM]], [[THEN]] ], [ [[SUM]], [[LOOP_HEADER]] ]427; CHECK-NEXT: [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_LCSSA]]) ]428; CHECK-NEXT: ret i32 [[RVAL]]429;430entry:431 br label %loop.header432 433loop.header:434 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]435 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]436 br i1 %c.1, label %then, label %deopt.exit437 438then:439 %i = load i32, ptr %inv440 %c.2 = icmp ult i32 %i, 2441 br i1 %c.2, label %loop.latch, label %deopt.exit442 443loop.latch:444 %gep = getelementptr i32, ptr %ptr, i32 %iv445 %lv = load i32, ptr %gep446 %sum.next = add i32 %sum, %lv447 %iv.next = add nuw nsw i32 %iv, 1448 %c.3 = icmp ult i32 %iv, 1000449 br i1 %c.3, label %loop.header, label %exit450 451exit:452 ret i32 %sum.next453 454deopt.exit:455 %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum) ]456 ret i32 %rval457}458 459define i32 @do_not_peel_when_header_exiting(ptr %ptr, i32 %N, ptr %inv) {460; CHECK-LABEL: @do_not_peel_when_header_exiting(461; CHECK-NEXT: entry:462; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]463; CHECK: loop.header:464; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]465; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]466; CHECK-NEXT: [[C_1:%.*]] = icmp ult i32 [[IV]], 1000467; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT:%.*]]468; CHECK: then:469; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4470; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2471; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT:%.*]]472; CHECK: loop.latch:473; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]474; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4475; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]476; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1477; CHECK-NEXT: br label [[LOOP_HEADER]]478; CHECK: exit:479; CHECK-NEXT: [[SUM_LCSSA:%.*]] = phi i32 [ [[SUM]], [[LOOP_HEADER]] ]480; CHECK-NEXT: ret i32 [[SUM_LCSSA]]481; CHECK: unreachable.exit:482; CHECK-NEXT: call void @foo()483; CHECK-NEXT: unreachable484;485entry:486 br label %loop.header487 488loop.header:489 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]490 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]491 %c.1 = icmp ult i32 %iv, 1000492 br i1 %c.1, label %then, label %exit493 494then:495 %i = load i32, ptr %inv496 %c.2 = icmp ult i32 %i, 2497 br i1 %c.2, label %loop.latch, label %unreachable.exit498 499loop.latch:500 %gep = getelementptr i32, ptr %ptr, i32 %iv501 %lv = load i32, ptr %gep502 %sum.next = add i32 %sum, %lv503 %iv.next = add nuw nsw i32 %iv, 1504 br label %loop.header505 506exit:507 ret i32 %sum508 509unreachable.exit:510 call void @foo()511 unreachable512}513 514define i32 @do_not_peel_readonly_to_make_loads_derefenceable_but_does_not_control_exit(ptr %ptr, i32 %N, ptr %inv, i1 %c.1, i32 %N.2) {515; CHECK-LABEL: @do_not_peel_readonly_to_make_loads_derefenceable_but_does_not_control_exit(516; CHECK-NEXT: entry:517; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]518; CHECK: loop.header:519; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]520; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]521; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]]522; CHECK: then:523; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4524; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[IV]], [[N_2:%.*]]525; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]526; CHECK: loop.latch:527; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]528; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4529; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]530; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1531; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000532; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]533; CHECK: exit:534; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]535; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]536; CHECK: unreachable.exit:537; CHECK-NEXT: call void @foo()538; CHECK-NEXT: unreachable539;540entry:541 br label %loop.header542 543loop.header:544 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]545 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]546 br i1 %c.1, label %then, label %unreachable.exit547 548then:549 %i = load i32, ptr %inv550 %c.2 = icmp ult i32 %iv, %N.2551 br i1 %c.2, label %loop.latch, label %unreachable.exit552 553loop.latch:554 %gep = getelementptr i32, ptr %ptr, i32 %iv555 %lv = load i32, ptr %gep556 %sum.next = add i32 %sum, %lv557 %iv.next = add nuw nsw i32 %iv, 1558 %c.3 = icmp ult i32 %iv, 1000559 br i1 %c.3, label %loop.header, label %exit560 561exit:562 ret i32 %sum.next563 564unreachable.exit:565 call void @foo()566 unreachable567}568 569@glob = global i32 10570 571define i32 @do_not_peel_readonly_but_already_deref_glob(ptr %ptr, i32 %N, i1 %c.1) {572; CHECK-LABEL: @do_not_peel_readonly_but_already_deref_glob(573; CHECK-NEXT: entry:574; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]575; CHECK: loop.header:576; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]577; CHECK-NEXT: [[SUM:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_NEXT:%.*]], [[LOOP_LATCH]] ]578; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]]579; CHECK: then:580; CHECK-NEXT: [[I:%.*]] = load i32, ptr @glob, align 4581; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2582; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]583; CHECK: loop.latch:584; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]585; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4586; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]587; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1588; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000589; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]590; CHECK: exit:591; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]592; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]593; CHECK: unreachable.exit:594; CHECK-NEXT: call void @foo()595; CHECK-NEXT: unreachable596;597entry:598 br label %loop.header599 600loop.header:601 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]602 %sum = phi i32 [ 0, %entry ], [ %sum.next, %loop.latch ]603 br i1 %c.1, label %then, label %unreachable.exit604 605then:606 %i = load i32, ptr @glob607 %c.2 = icmp ult i32 %i, 2608 br i1 %c.2, label %loop.latch, label %unreachable.exit609 610loop.latch:611 %gep = getelementptr i32, ptr %ptr, i32 %iv612 %lv = load i32, ptr %gep613 %sum.next = add i32 %sum, %lv614 %iv.next = add nuw nsw i32 %iv, 1615 %c.3 = icmp ult i32 %iv, 1000616 br i1 %c.3, label %loop.header, label %exit617 618exit:619 ret i32 %sum.next620 621unreachable.exit:622 call void @foo()623 unreachable624}625