1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=loop-unroll -S %s | FileCheck %s
6 define 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(
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:%.*]]
15 ; CHECK-NEXT: [[I_PEEL:%.*]] = load i32, ptr [[INV:%.*]], align 4
16 ; CHECK-NEXT: [[C_2_PEEL:%.*]] = icmp ult i32 [[I_PEEL]], 2
17 ; 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 1
20 ; CHECK-NEXT: [[LV_PEEL:%.*]] = load i32, ptr [[GEP_PEEL]], align 4
21 ; CHECK-NEXT: [[SUM_NEXT_PEEL:%.*]] = add i32 0, [[LV_PEEL]]
22 ; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add nuw nsw i32 1, 1
23 ; CHECK-NEXT: [[C_3_PEEL:%.*]] = icmp ult i32 1, 1000
24 ; 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:%.*]]
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:%.*]]
36 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV]], align 4
37 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2
38 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT_LOOPEXIT]]
40 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[IV]]
41 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
42 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
43 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
44 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
45 ; 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]]
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: unreachable
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.exit
67 %i = load i32, ptr %inv
68 %c.2 = icmp ult i32 %i, 2
69 br i1 %c.2, label %loop.latch, label %unreachable.exit
72 %gep = getelementptr i32, ptr %ptr, i32 %iv
73 %lv = load i32, ptr %gep
74 %sum.next = add i32 %sum, %lv
75 %iv.next = add nuw nsw i32 %iv, 1
76 %c.3 = icmp ult i32 %iv, 1000
77 br i1 %c.3, label %loop.header, label %exit
87 define 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(
90 ; CHECK-NEXT: br label [[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:%.*]]
96 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4
97 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2
98 ; CHECK-NEXT: br i1 [[C_2]], label [[THEN_2:%.*]], label [[EXIT_2]]
100 ; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[I]], 4
101 ; CHECK-NEXT: br i1 [[C_4]], label [[LOOP_LATCH]], label [[EXIT_3:%.*]]
103 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
104 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
105 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
106 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
107 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
108 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
110 ; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]
111 ; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]
113 ; CHECK-NEXT: br label [[UNREACHABLE_BB:%.*]]
115 ; CHECK-NEXT: br label [[UNREACHABLE_BB]]
116 ; CHECK: unreachable.bb:
117 ; CHECK-NEXT: call void @foo()
118 ; CHECK-NEXT: unreachable
121 br label %loop.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.2
129 %i = load i32, ptr %inv
130 %c.2 = icmp ult i32 %i, 2
131 br i1 %c.2, label %then.2, label %exit.2
134 %c.4 = icmp ult i32 %i, 4
135 br i1 %c.4, label %loop.latch, label %exit.3
138 %gep = getelementptr i32, ptr %ptr, i32 %iv
139 %lv = load i32, ptr %gep
140 %sum.next = add i32 %sum, %lv
141 %iv.next = add nuw nsw i32 %iv, 1
142 %c.3 = icmp ult i32 %iv, 1000
143 br i1 %c.3, label %loop.header, label %exit
149 br label %unreachable.bb
152 br label %unreachable.bb
159 define 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(
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 4
167 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2
168 ; CHECK-NEXT: br i1 [[C_2]], label [[THEN:%.*]], label [[UNREACHABLE_EXIT:%.*]]
170 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]
172 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
173 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
174 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
175 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
176 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
177 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[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: unreachable
186 br label %loop.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 %inv
192 %c.2 = icmp ult i32 %i, 2
193 br i1 %c.2, label %then, label %unreachable.exit
196 br i1 %c.1, label %loop.latch, label %unreachable.exit
199 %gep = getelementptr i32, ptr %ptr, i32 %iv
200 %lv = load i32, ptr %gep
201 %sum.next = add i32 %sum, %lv
202 %iv.next = add nuw nsw i32 %iv, 1
203 %c.3 = icmp ult i32 %iv, 1000
204 br i1 %c.3, label %loop.header, label %exit
214 define 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(
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:%.*]]
224 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4
225 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[I]], 20
226 ; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH]]
228 ; CHECK-NEXT: br label [[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 4
233 ; 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]], 1
236 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
237 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[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: unreachable
246 br label %loop.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, %x
252 br i1 %c.1, label %then, label %else
255 %i = load i32, ptr %inv
256 %c.2 = icmp eq i32 %i, 20
257 br i1 %c.2, label %unreachable.exit, label %loop.latch
263 %p = phi i32 [ %i, %then ], [ 0, %else ]
264 %gep = getelementptr i32, ptr %ptr, i32 %iv
265 %lv = load i32, ptr %gep
266 %add.1 = add i32 %lv, %p
267 %sum.next = add i32 %sum, %add.1
268 %iv.next = add nuw nsw i32 %iv, 1
269 %c.3 = icmp ult i32 %iv, 1000
270 br i1 %c.3, label %loop.header, label %exit
280 define 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(
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:%.*]]
289 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4
290 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2
291 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]
293 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
294 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
295 ; CHECK-NEXT: store i32 [[LV]], ptr [[DST:%.*]], align 4
296 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
297 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
298 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
299 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[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: unreachable
308 br label %loop.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.exit
316 %i = load i32, ptr %inv
317 %c.2 = icmp ult i32 %i, 2
318 br i1 %c.2, label %loop.latch, label %unreachable.exit
321 %gep = getelementptr i32, ptr %ptr, i32 %iv
322 %lv = load i32, ptr %gep
323 store i32 %lv, ptr %dst
324 %sum.next = add i32 %sum, %lv
325 %iv.next = add nuw nsw i32 %iv, 1
326 %c.3 = icmp ult i32 %iv, 1000
327 br i1 %c.3, label %loop.header, label %exit
337 define i32 @do_not_peel_write2(ptr %ptr, i32 %N, ptr %inv, ptr %dst) {
338 ; CHECK-LABEL: @do_not_peel_write2(
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 4
345 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[I]], 20
346 ; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
348 ; CHECK-NEXT: store i32 [[I]], ptr [[DST:%.*]], align 4
349 ; CHECK-NEXT: br label [[LOOP_LATCH]]
351 ; CHECK-NEXT: br label [[UNREACHABLE_EXIT:%.*]]
353 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
354 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
355 ; 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]], 1
358 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
359 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[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: unreachable
368 br label %loop.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 %inv
374 %c.1 = icmp eq i32 %i, 20
375 br i1 %c.1, label %then, label %else
378 store i32 %i, ptr %dst
382 br label %unreachable.exit
385 %gep = getelementptr i32, ptr %ptr, i32 %iv
386 %lv = load i32, ptr %gep
387 %add.1 = add i32 %lv, %i
388 %sum.next = add i32 %sum, %add.1
389 %iv.next = add nuw nsw i32 %iv, 1
390 %c.3 = icmp ult i32 %iv, 1000
391 br i1 %c.3, label %loop.header, label %exit
401 declare i32 @llvm.experimental.deoptimize.i32(...)
403 define i32 @peel_with_deopt_exit(ptr %ptr, i32 %N, ptr %inv, i1 %c.1) {
404 ; CHECK-LABEL: @peel_with_deopt_exit(
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:%.*]]
412 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4
413 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2
414 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[DEOPT_EXIT]]
416 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
417 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
418 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
419 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
420 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
421 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
423 ; CHECK-NEXT: [[SUM_NEXT_LCSSA:%.*]] = phi i32 [ [[SUM_NEXT]], [[LOOP_LATCH]] ]
424 ; CHECK-NEXT: ret i32 [[SUM_NEXT_LCSSA]]
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]]
431 br label %loop.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.exit
439 %i = load i32, ptr %inv
440 %c.2 = icmp ult i32 %i, 2
441 br i1 %c.2, label %loop.latch, label %deopt.exit
444 %gep = getelementptr i32, ptr %ptr, i32 %iv
445 %lv = load i32, ptr %gep
446 %sum.next = add i32 %sum, %lv
447 %iv.next = add nuw nsw i32 %iv, 1
448 %c.3 = icmp ult i32 %iv, 1000
449 br i1 %c.3, label %loop.header, label %exit
455 %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum) ]
459 define i32 @do_not_peel_when_header_exiting(ptr %ptr, i32 %N, ptr %inv) {
460 ; CHECK-LABEL: @do_not_peel_when_header_exiting(
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]], 1000
467 ; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT:%.*]]
469 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4
470 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2
471 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT:%.*]]
473 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
474 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
475 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
476 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
477 ; CHECK-NEXT: br label [[LOOP_HEADER]]
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: unreachable
486 br label %loop.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, 1000
492 br i1 %c.1, label %then, label %exit
495 %i = load i32, ptr %inv
496 %c.2 = icmp ult i32 %i, 2
497 br i1 %c.2, label %loop.latch, label %unreachable.exit
500 %gep = getelementptr i32, ptr %ptr, i32 %iv
501 %lv = load i32, ptr %gep
502 %sum.next = add i32 %sum, %lv
503 %iv.next = add nuw nsw i32 %iv, 1
504 br label %loop.header
514 define 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(
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:%.*]]
523 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr [[INV:%.*]], align 4
524 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[IV]], [[N_2:%.*]]
525 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]
527 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
528 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
529 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
530 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
531 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
532 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[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: unreachable
541 br label %loop.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.exit
549 %i = load i32, ptr %inv
550 %c.2 = icmp ult i32 %iv, %N.2
551 br i1 %c.2, label %loop.latch, label %unreachable.exit
554 %gep = getelementptr i32, ptr %ptr, i32 %iv
555 %lv = load i32, ptr %gep
556 %sum.next = add i32 %sum, %lv
557 %iv.next = add nuw nsw i32 %iv, 1
558 %c.3 = icmp ult i32 %iv, 1000
559 br i1 %c.3, label %loop.header, label %exit
569 @glob = global i32 10
571 define 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(
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:%.*]]
580 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr @glob, align 4
581 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[I]], 2
582 ; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_LATCH]], label [[UNREACHABLE_EXIT]]
584 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]]
585 ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[GEP]], align 4
586 ; CHECK-NEXT: [[SUM_NEXT]] = add i32 [[SUM]], [[LV]]
587 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
588 ; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
589 ; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[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: unreachable
598 br label %loop.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.exit
606 %i = load i32, ptr @glob
607 %c.2 = icmp ult i32 %i, 2
608 br i1 %c.2, label %loop.latch, label %unreachable.exit
611 %gep = getelementptr i32, ptr %ptr, i32 %iv
612 %lv = load i32, ptr %gep
613 %sum.next = add i32 %sum, %lv
614 %iv.next = add nuw nsw i32 %iv, 1
615 %c.3 = icmp ult i32 %iv, 1000
616 br i1 %c.3, label %loop.header, label %exit