Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LoopUnroll / peel-to-turn-invariant-accesses-dereferenceable.ll
blob1098de0acd1a9cccd025a50f4c7df36300f68444
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=loop-unroll -S %s | FileCheck %s
4 declare void @foo()
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(
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 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:%.*]]
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 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]]
39 ; CHECK:       loop.latch:
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]]
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:    unreachable
58 entry:
59   br label %loop.header
61 loop.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.exit
66 then:
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
71 loop.latch:
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
79 exit:
80   ret i32 %sum.next
82 unreachable.exit:
83   call void @foo()
84   unreachable
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(
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 4
97 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i32 [[I]], 2
98 ; 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]], 4
101 ; 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 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:%.*]]
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:    unreachable
120 entry:
121   br label %loop.header
123 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
128 then:
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
133 then.2:
134   %c.4 = icmp ult i32 %i, 4
135   br i1 %c.4, label %loop.latch, label %exit.3
137 loop.latch:
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
145 exit:
146   ret i32 %sum.next
148 exit.2:
149   br label %unreachable.bb
151 exit.3:
152   br label %unreachable.bb
154 unreachable.bb:
155   call void @foo()
156   unreachable
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(
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 4
167 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i32 [[I]], 2
168 ; 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 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:%.*]]
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:    unreachable
185 entry:
186   br label %loop.header
188 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
195 then:
196   br i1 %c.1, label %loop.latch, label %unreachable.exit
198 loop.latch:
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
206 exit:
207   ret i32 %sum.next
209 unreachable.exit:
210   call void @foo()
211   unreachable
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(
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 4
225 ; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i32 [[I]], 20
226 ; 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 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:%.*]]
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:    unreachable
245 entry:
246   br label %loop.header
248 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
254 then:
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
259 else:
260   br label %loop.latch
262 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
272 exit:
273   ret i32 %sum.next
275 unreachable.exit:
276   call void @foo()
277   unreachable
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(
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 4
290 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i32 [[I]], 2
291 ; 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 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:%.*]]
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:    unreachable
307 entry:
308   br label %loop.header
310 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
315 then:
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
320 loop.latch:
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
329 exit:
330   ret i32 %sum.next
332 unreachable.exit:
333   call void @foo()
334   unreachable
337 define 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 4
345 ; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[I]], 20
346 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[ELSE:%.*]]
347 ; CHECK:       then:
348 ; CHECK-NEXT:    store i32 [[I]], ptr [[DST:%.*]], align 4
349 ; 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 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:%.*]]
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:    unreachable
367 entry:
368   br label %loop.header
370 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
377 then:
378   store i32 %i, ptr %dst
379   br label %loop.latch
381 else:
382   br label %unreachable.exit
384 loop.latch:
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
393 exit:
394   ret i32 %sum.next
396 unreachable.exit:
397   call void @foo()
398   unreachable
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(
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 4
413 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i32 [[I]], 2
414 ; 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 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:%.*]]
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]]
430 entry:
431   br label %loop.header
433 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
438 then:
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
443 loop.latch:
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
451 exit:
452   ret i32 %sum.next
454 deopt.exit:
455   %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum) ]
456   ret i32 %rval
459 define 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]], 1000
467 ; CHECK-NEXT:    br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT:%.*]]
468 ; CHECK:       then:
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:%.*]]
472 ; CHECK:       loop.latch:
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]]
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:    unreachable
485 entry:
486   br label %loop.header
488 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
494 then:
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
499 loop.latch:
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
506 exit:
507   ret i32 %sum
509 unreachable.exit:
510   call void @foo()
511   unreachable
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(
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 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]]
526 ; CHECK:       loop.latch:
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:%.*]]
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:    unreachable
540 entry:
541   br label %loop.header
543 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
548 then:
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
553 loop.latch:
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
561 exit:
562   ret i32 %sum.next
564 unreachable.exit:
565   call void @foo()
566   unreachable
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(
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 4
581 ; CHECK-NEXT:    [[C_2:%.*]] = icmp ult i32 [[I]], 2
582 ; 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 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:%.*]]
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:    unreachable
597 entry:
598   br label %loop.header
600 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
605 then:
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
610 loop.latch:
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
618 exit:
619   ret i32 %sum.next
621 unreachable.exit:
622   call void @foo()
623   unreachable