blob: 59842902b0e1f8c280cb5811aa49db7dd0c2b592 [file] [log] [blame]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +00001; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
2; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
3
4declare void @llvm.experimental.guard(i1, ...)
5
6define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
7; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check
8entry:
9 %tmp5 = icmp eq i32 %n, 0
10 br i1 %tmp5, label %exit, label %loop.preheader
11
12loop.preheader:
13; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +000014; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
15; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenko889dc1e2017-09-22 13:13:57 +000016; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +000017; CHECK-NEXT: br label %loop
18 br label %loop
19
20loop:
21; CHECK: loop:
22; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
23 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
24 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
25 %within.bounds = icmp ult i32 %i, %length
26 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
27
28 %i.i64 = zext i32 %i to i64
29 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
30 %array.i = load i32, i32* %array.i.ptr, align 4
31 %loop.acc.next = add i32 %loop.acc, %array.i
32
33 %i.next = add nuw i32 %i, 1
34 %continue = icmp ult i32 %i.next, %n
35 br i1 %continue, label %loop, label %exit
36
37exit:
38 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
39 ret i32 %result
40}
41
Artur Pilipenkob4527e12017-10-12 20:40:27 +000042define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) {
43; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check
44entry:
45 %tmp5 = icmp eq i32 %n, 0
46 br i1 %tmp5, label %exit, label %loop.preheader
47
48loop.preheader:
49; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +000050; CHECK: [[limit_check:[^ ]+]] = icmp ult i32 %n, %length
51; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenkob4527e12017-10-12 20:40:27 +000052; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
53; CHECK-NEXT: br label %loop
54 br label %loop
55
56loop:
57; CHECK: loop:
58; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
59 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
60 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
61 %within.bounds = icmp ult i32 %i, %length
62 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
63
64 %i.i64 = zext i32 %i to i64
65 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
66 %array.i = load i32, i32* %array.i.ptr, align 4
67 %loop.acc.next = add i32 %loop.acc, %array.i
68
69 %i.next = add nuw i32 %i, 1
70 %continue = icmp ule i32 %i.next, %n
71 br i1 %continue, label %loop, label %exit
72
73exit:
74 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
75 ret i32 %result
76}
77
Artur Pilipenko8fb3d572017-01-25 16:00:44 +000078define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
79; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check
80entry:
81 %tmp5 = icmp eq i32 %n, 0
82 br i1 %tmp5, label %exit, label %loop.preheader
83
84loop.preheader:
85; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +000086; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
87; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenko889dc1e2017-09-22 13:13:57 +000088; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +000089; CHECK-NEXT: br label %loop
90 br label %loop
91
92loop:
93; CHECK: loop:
94; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
95 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
96 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
97 %within.bounds = icmp ugt i32 %length, %i
98 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
99
100 %i.i64 = zext i32 %i to i64
101 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
102 %array.i = load i32, i32* %array.i.ptr, align 4
103 %loop.acc.next = add i32 %loop.acc, %array.i
104
105 %i.next = add nuw i32 %i, 1
106 %continue = icmp ult i32 %i.next, %n
107 br i1 %continue, label %loop, label %exit
108
109exit:
110 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
111 ret i32 %result
112}
113
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000114define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
115; CHECK-LABEL: @signed_loop_0_to_n_ult_check
116entry:
117 %tmp5 = icmp sle i32 %n, 0
118 br i1 %tmp5, label %exit, label %loop.preheader
119
120loop.preheader:
121; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000122; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
123; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000124; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
125; CHECK-NEXT: br label %loop
126 br label %loop
127
128loop:
129; CHECK: loop:
130; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
131 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
132 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
133 %within.bounds = icmp ult i32 %i, %length
134 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
135
136 %i.i64 = zext i32 %i to i64
137 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
138 %array.i = load i32, i32* %array.i.ptr, align 4
139 %loop.acc.next = add i32 %loop.acc, %array.i
140
141 %i.next = add nuw i32 %i, 1
142 %continue = icmp slt i32 %i.next, %n
143 br i1 %continue, label %loop, label %exit
144
145exit:
146 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
147 ret i32 %result
148}
149
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000150define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
151; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known
152entry:
153 %tmp5 = icmp sle i32 %n, 0
154 %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648}
155 br i1 %tmp5, label %exit, label %loop.preheader
156
157loop.preheader:
158; CHECK: loop.preheader:
159; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
160; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 true, [[limit_check]]
161; CHECK-NEXT: br label %loop
162 br label %loop
163
164loop:
165; CHECK: loop:
166; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
167 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
168 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
169 %within.bounds = icmp ult i32 %i, %length
170 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
171
172 %i.i64 = zext i32 %i to i64
173 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
174 %array.i = load i32, i32* %array.i.ptr, align 4
175 %loop.acc.next = add i32 %loop.acc, %array.i
176
177 %i.next = add nuw i32 %i, 1
178 %continue = icmp slt i32 %i.next, %n
179 br i1 %continue, label %loop, label %exit
180
181exit:
182 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
183 ret i32 %result
184}
185
Artur Pilipenkob4527e12017-10-12 20:40:27 +0000186define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) {
187; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate
188entry:
189 %tmp5 = icmp sle i32 %n, 0
190 br i1 %tmp5, label %exit, label %loop.preheader
191
192loop.preheader:
193; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000194; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
195; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenkob4527e12017-10-12 20:40:27 +0000196; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
197; CHECK-NEXT: br label %loop
198 br label %loop
199
200loop:
201; CHECK: loop:
202; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
203 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
204 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
205 %within.bounds = icmp ult i32 %i, %length
206 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
207
208 %i.i64 = zext i32 %i to i64
209 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
210 %array.i = load i32, i32* %array.i.ptr, align 4
211 %loop.acc.next = add i32 %loop.acc, %array.i
212
213 %i.next = add nuw i32 %i, 1
214 %continue = icmp sgt i32 %i.next, %n
215 br i1 %continue, label %exit, label %loop
216
217exit:
218 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
219 ret i32 %result
220}
221
222define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) {
223; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check
224entry:
225 %tmp5 = icmp sle i32 %n, 0
226 br i1 %tmp5, label %exit, label %loop.preheader
227
228loop.preheader:
229; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000230; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
231; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenkob4527e12017-10-12 20:40:27 +0000232; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
233; CHECK-NEXT: br label %loop
234 br label %loop
235
236loop:
237; CHECK: loop:
238; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
239 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
240 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
241 %within.bounds = icmp ult i32 %i, %length
242 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
243
244 %i.i64 = zext i32 %i to i64
245 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
246 %array.i = load i32, i32* %array.i.ptr, align 4
247 %loop.acc.next = add i32 %loop.acc, %array.i
248
249 %i.next = add nuw i32 %i, 1
250 %continue = icmp sle i32 %i.next, %n
251 br i1 %continue, label %loop, label %exit
252
253exit:
254 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
255 ret i32 %result
256}
257
Artur Pilipenko8aadc642017-10-27 14:46:17 +0000258define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) {
259; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check
260entry:
261 %tmp5 = icmp sle i32 %n, 0
262 br i1 %tmp5, label %exit, label %loop.preheader
263
264loop.preheader:
265; CHECK: loop.preheader:
266; CHECK: [[length_minus_1:[^ ]+]] = add i32 %length, -1
267; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[length_minus_1]]
268; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
269; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
270; CHECK-NEXT: br label %loop
271 br label %loop
272
273loop:
274; CHECK: loop:
275; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
276 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
277 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
278 %within.bounds = icmp ult i32 %i, %length
279 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
280
281 %i.i64 = zext i32 %i to i64
282 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
283 %array.i = load i32, i32* %array.i.ptr, align 4
284 %loop.acc.next = add i32 %loop.acc, %array.i
285
286 %i.next = add i32 %i, 1
287 %continue = icmp slt i32 %i, %n
288 br i1 %continue, label %loop, label %exit
289
290exit:
291 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
292 ret i32 %result
293}
294
295define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) {
296; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check
297entry:
298 %tmp5 = icmp sle i32 %n, 0
299 br i1 %tmp5, label %exit, label %loop.preheader
300
301loop.preheader:
302; CHECK: loop.preheader:
303; CHECK: [[length_minus_2:[^ ]+]] = add i32 %length, -2
304; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[length_minus_2]]
305; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length
306; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
307; CHECK-NEXT: br label %loop
308 br label %loop
309
310loop:
311; CHECK: loop:
312; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
313 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
314 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
315
316 %i.next = add i32 %i, 1
317 %within.bounds = icmp ult i32 %i.next, %length
318 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
319
320 %i.i64 = zext i32 %i to i64
321 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
322 %array.i = load i32, i32* %array.i.ptr, align 4
323 %loop.acc.next = add i32 %loop.acc, %array.i
324
325 %continue = icmp slt i32 %i, %n
326 br i1 %continue, label %loop, label %exit
327
328exit:
329 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
330 ret i32 %result
331}
332
333define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
334; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check
335entry:
336 %tmp5 = icmp sle i32 %n, 0
337 br i1 %tmp5, label %exit, label %loop.preheader
338
339loop.preheader:
340; CHECK: loop.preheader:
341; CHECK: [[length_minus_1:[^ ]+]] = add i32 %length, -1
342; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp slt i32 %n, [[length_minus_1]]
343; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length
344; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
345; CHECK-NEXT: br label %loop
346 br label %loop
347
348loop:
349; CHECK: loop:
350; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
351 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
352 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
353 %i.offset = add i32 %i, 1
354 %within.bounds = icmp ult i32 %i.offset, %length
355 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
356
357 %i.i64 = zext i32 %i to i64
358 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
359 %array.i = load i32, i32* %array.i.ptr, align 4
360 %loop.acc.next = add i32 %loop.acc, %array.i
361
362 %i.next = add i32 %i, 1
363 %continue = icmp sle i32 %i.next, %n
364 br i1 %continue, label %loop, label %exit
365
366exit:
367 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
368 ret i32 %result
369}
370
371define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
372; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check
373entry:
374 %tmp5 = icmp sle i32 %n, 0
375 br i1 %tmp5, label %exit, label %loop.preheader
376
377loop.preheader:
378; CHECK: loop.preheader:
379; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
380; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length
381; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
382; CHECK-NEXT: br label %loop
383 br label %loop
384
385loop:
386; CHECK: loop:
387; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
388 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
389 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
390 %i.offset = add i32 %i, 1
391 %within.bounds = icmp ult i32 %i.offset, %length
392 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
393
394 %i.i64 = zext i32 %i to i64
395 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
396 %array.i = load i32, i32* %array.i.ptr, align 4
397 %loop.acc.next = add i32 %loop.acc, %array.i
398
399 %i.next = add i32 %i, 1
400 %i.next.offset = add i32 %i.next, 1
401 %continue = icmp sle i32 %i.next.offset, %n
402 br i1 %continue, label %loop, label %exit
403
404exit:
405 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
406 ret i32 %result
407}
408
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000409define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
410; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n
411entry:
412 %tmp5 = icmp sle i32 %n, 0
413 br i1 %tmp5, label %exit, label %loop.preheader
414
415loop.preheader:
416; CHECK: loop.preheader:
417; CHECK-NEXT: br label %loop
418 br label %loop
419
420loop:
421; CHECK: loop:
422; CHECK: %within.bounds = icmp ult i32 %i, %length
423; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
424 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
425 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
426 %within.bounds = icmp ult i32 %i, %length
427 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
428
429 %i.i64 = zext i32 %i to i64
430 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
431 %array.i = load i32, i32* %array.i.ptr, align 4
432 %loop.acc.next = add i32 %loop.acc, %array.i
433
434 %i.next = add nsw i32 %i, 1
435 %continue = icmp ne i32 %i.next, %n
436 br i1 %continue, label %loop, label %exit
437
438exit:
439 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
440 ret i32 %result
441}
442
443define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) {
444; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step
445entry:
446 %tmp5 = icmp sle i32 %n, 0
447 br i1 %tmp5, label %exit, label %loop.preheader
448
449loop.preheader:
450; CHECK: loop.preheader:
451; CHECK-NEXT: br label %loop
452 br label %loop
453
454loop:
455; CHECK: loop:
456; CHECK: %within.bounds = icmp ult i32 %i, %length
457; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
458 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
459 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
460 %within.bounds = icmp ult i32 %i, %length
461 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
462
463 %i.i64 = zext i32 %i to i64
464 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
465 %array.i = load i32, i32* %array.i.ptr, align 4
466 %loop.acc.next = add i32 %loop.acc, %array.i
467
468 %i.next = add nsw i32 %i, 2
469 %continue = icmp slt i32 %i.next, %n
470 br i1 %continue, label %loop, label %exit
471
472exit:
473 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
474 ret i32 %result
475}
476
477define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) {
478; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check
479entry:
480 %tmp5 = icmp sle i32 %n, 0
481 br i1 %tmp5, label %exit, label %loop.preheader
482
483loop.preheader:
484; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000485; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
486; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000487; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
488; CHECK-NEXT: br label %loop
489 br label %loop
490
491loop:
492; CHECK: loop:
493; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
494 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
495 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
496 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
497
498 %within.bounds = icmp ult i32 %j, %length
499 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
500
501 %i.i64 = zext i32 %i to i64
502 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
503 %array.i = load i32, i32* %array.i.ptr, align 4
504 %loop.acc.next = add i32 %loop.acc, %array.i
505
506 %j.next = add nsw i32 %j, 1
507 %i.next = add nsw i32 %i, 1
508 %continue = icmp slt i32 %i.next, %n
509 br i1 %continue, label %loop, label %exit
510
511exit:
512 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
513 ret i32 %result
514}
515
Artur Pilipenko8aadc642017-10-27 14:46:17 +0000516define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i,
517 i32 %start.j, i32 %length,
518 i32 %n) {
519; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check
520entry:
521 %tmp5 = icmp sle i32 %n, 0
522 br i1 %tmp5, label %exit, label %loop.preheader
523
524loop.preheader:
525; CHECK: loop.preheader:
526; CHECK: [[length_plus_start_i:[^ ]+]] = add i32 %length, %start.i
527; CHECK-NEXT: [[limit:[^ ]+]] = sub i32 [[length_plus_start_i]], %start.j
528; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[limit]]
529; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 %start.j, %length
530; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
531; CHECK-NEXT: br label %loop
532 br label %loop
533
534loop:
535; CHECK: loop:
536; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
537 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
538 %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ]
539 %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ]
540
541 %within.bounds = icmp ult i32 %j, %length
542 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
543
544 %i.i64 = zext i32 %i to i64
545 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
546 %array.i = load i32, i32* %array.i.ptr, align 4
547 %loop.acc.next = add i32 %loop.acc, %array.i
548
549 %j.next = add i32 %j, 1
550 %i.next = add i32 %i, 1
551 %continue = icmp slt i32 %i.next, %n
552 br i1 %continue, label %loop, label %exit
553
554exit:
555 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
556 ret i32 %result
557}
558
559define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) {
560; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types
561entry:
562 %tmp5 = icmp sle i32 %n, 0
563 br i1 %tmp5, label %exit, label %loop.preheader
564
565loop.preheader:
566; CHECK: loop.preheader:
567; CHECK-NEXT: br label %loop
568 br label %loop
569
570loop:
571; CHECK: loop:
572; CHECK: %within.bounds = icmp ult i16 %j, %length
573; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
574 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
575 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
576 %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ]
577
578 %within.bounds = icmp ult i16 %j, %length
579 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
580
581 %i.i64 = zext i32 %i to i64
582 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
583 %array.i = load i32, i32* %array.i.ptr, align 4
584 %loop.acc.next = add i32 %loop.acc, %array.i
585
586 %j.next = add i16 %j, 1
587 %i.next = add i32 %i, 1
588 %continue = icmp slt i32 %i.next, %n
589 br i1 %continue, label %loop, label %exit
590
591exit:
592 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
593 ret i32 %result
594}
595
596define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) {
597; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000598entry:
599 %tmp5 = icmp sle i32 %n, 0
600 br i1 %tmp5, label %exit, label %loop.preheader
601
602loop.preheader:
603; CHECK: loop.preheader:
604; CHECK-NEXT: br label %loop
605 br label %loop
606
607loop:
608; CHECK: loop:
609; CHECK: %within.bounds = icmp ult i32 %j, %length
610; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
611 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
612 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
Artur Pilipenko8aadc642017-10-27 14:46:17 +0000613 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000614
615 %within.bounds = icmp ult i32 %j, %length
616 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
617
618 %i.i64 = zext i32 %i to i64
619 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
620 %array.i = load i32, i32* %array.i.ptr, align 4
621 %loop.acc.next = add i32 %loop.acc, %array.i
622
Artur Pilipenko8aadc642017-10-27 14:46:17 +0000623 %j.next = add nsw i32 %j, 2
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000624 %i.next = add nsw i32 %i, 1
625 %continue = icmp slt i32 %i.next, %n
626 br i1 %continue, label %loop, label %exit
627
628exit:
629 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
630 ret i32 %result
631}
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000632
633define i32 @two_range_checks(i32* %array.1, i32 %length.1,
634 i32* %array.2, i32 %length.2, i32 %n) {
635; CHECK-LABEL: @two_range_checks
636entry:
637 %tmp5 = icmp eq i32 %n, 0
638 br i1 %tmp5, label %exit, label %loop.preheader
639
640loop.preheader:
641; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000642; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
643; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000644; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000645; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000646; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000647; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000648; CHECK-NEXT: br label %loop
649 br label %loop
650
651loop:
652; CHECK: loop:
653; CHECK: [[wide_cond:[^ ]+]] = and i1 [[wide_cond_1]], [[wide_cond_2]]
654; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
655 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
656 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
657 %within.bounds.1 = icmp ult i32 %i, %length.1
658 %within.bounds.2 = icmp ult i32 %i, %length.2
659 %within.bounds = and i1 %within.bounds.1, %within.bounds.2
660 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
661
662 %i.i64 = zext i32 %i to i64
663 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
664 %array.1.i = load i32, i32* %array.1.i.ptr, align 4
665 %loop.acc.1 = add i32 %loop.acc, %array.1.i
666
667 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
668 %array.2.i = load i32, i32* %array.2.i.ptr, align 4
669 %loop.acc.next = add i32 %loop.acc.1, %array.2.i
670
671 %i.next = add nuw i32 %i, 1
672 %continue = icmp ult i32 %i.next, %n
673 br i1 %continue, label %loop, label %exit
674
675exit:
676 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
677 ret i32 %result
678}
679
680define i32 @three_range_checks(i32* %array.1, i32 %length.1,
681 i32* %array.2, i32 %length.2,
682 i32* %array.3, i32 %length.3, i32 %n) {
683; CHECK-LABEL: @three_range_checks
684entry:
685 %tmp5 = icmp eq i32 %n, 0
686 br i1 %tmp5, label %exit, label %loop.preheader
687
688loop.preheader:
689; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000690; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
691; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000692; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000693; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000694; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000695; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000696; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000697; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000698; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000699; CHECK-NEXT: br label %loop
700 br label %loop
701
702loop:
703; CHECK: loop:
704; CHECK: [[wide_cond_and:[^ ]+]] = and i1 [[wide_cond_1]], [[wide_cond_2]]
705; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[wide_cond_and]], [[wide_cond_3]]
706; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
707 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
708 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
709 %within.bounds.1 = icmp ult i32 %i, %length.1
710 %within.bounds.2 = icmp ult i32 %i, %length.2
711 %within.bounds.3 = icmp ult i32 %i, %length.3
712 %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
713 %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
714 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
715
716 %i.i64 = zext i32 %i to i64
717 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
718 %array.1.i = load i32, i32* %array.1.i.ptr, align 4
719 %loop.acc.1 = add i32 %loop.acc, %array.1.i
720
721 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
722 %array.2.i = load i32, i32* %array.2.i.ptr, align 4
723 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
724
725 %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
726 %array.3.i = load i32, i32* %array.3.i.ptr, align 4
727 %loop.acc.next = add i32 %loop.acc.2, %array.3.i
728
729 %i.next = add nuw i32 %i, 1
730 %continue = icmp ult i32 %i.next, %n
731 br i1 %continue, label %loop, label %exit
732
733exit:
734 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
735 ret i32 %result
736}
737
738define i32 @three_guards(i32* %array.1, i32 %length.1,
739 i32* %array.2, i32 %length.2,
740 i32* %array.3, i32 %length.3, i32 %n) {
741; CHECK-LABEL: @three_guards
742entry:
743 %tmp5 = icmp eq i32 %n, 0
744 br i1 %tmp5, label %exit, label %loop.preheader
745
746loop.preheader:
747; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000748; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
749; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000750; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000751; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000752; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000753; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000754; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000755; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000756; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000757; CHECK-NEXT: br label %loop
758 br label %loop
759
760loop:
761; CHECK: loop:
762; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_1]], i32 9) [ "deopt"() ]
763; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_2]], i32 9) [ "deopt"() ]
764; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_3]], i32 9) [ "deopt"() ]
765
766 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
767 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
768
769 %within.bounds.1 = icmp ult i32 %i, %length.1
770 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ]
771
772 %i.i64 = zext i32 %i to i64
773 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
774 %array.1.i = load i32, i32* %array.1.i.ptr, align 4
775 %loop.acc.1 = add i32 %loop.acc, %array.1.i
776
777 %within.bounds.2 = icmp ult i32 %i, %length.2
778 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ]
779
780 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
781 %array.2.i = load i32, i32* %array.2.i.ptr, align 4
782 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
783
784 %within.bounds.3 = icmp ult i32 %i, %length.3
785 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ]
786
787 %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
788 %array.3.i = load i32, i32* %array.3.i.ptr, align 4
789 %loop.acc.next = add i32 %loop.acc.2, %array.3.i
790
791 %i.next = add nuw i32 %i, 1
792 %continue = icmp ult i32 %i.next, %n
793 br i1 %continue, label %loop, label %exit
794
795exit:
796 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
797 ret i32 %result
798}
799
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000800define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) {
801; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition
802entry:
803 %tmp5 = icmp eq i32 %n, 0
804 br i1 %tmp5, label %exit, label %loop.preheader
805
806loop.preheader:
807; CHECK: loop.preheader:
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000808; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
809; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000810; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000811; CHECK-NEXT: br label %loop
812 br label %loop
813
814loop:
815; CHECK: loop:
816; CHECK: %unrelated.cond = icmp ult i32 %x, %length
817; CHECK: [[guard_cond:[^ ]+]] = and i1 %unrelated.cond, [[wide_cond]]
818; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[guard_cond]], i32 9) [ "deopt"() ]
819 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
820 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
821 %within.bounds = icmp ult i32 %i, %length
822 %unrelated.cond = icmp ult i32 %x, %length
823 %guard.cond = and i1 %within.bounds, %unrelated.cond
824 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
825
826 %i.i64 = zext i32 %i to i64
827 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
828 %array.i = load i32, i32* %array.i.ptr, align 4
829 %loop.acc.next = add i32 %loop.acc, %array.i
830
831 %i.next = add nuw i32 %i, 1
832 %continue = icmp ult i32 %i.next, %n
833 br i1 %continue, label %loop, label %exit
834
835exit:
836 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
837 ret i32 %result
838}
839
840; Don't change the guard condition if there were no widened subconditions
841define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
842; CHECK-LABEL: @test_no_widened_conditions
843entry:
844 %tmp5 = icmp eq i32 %n, 0
845 br i1 %tmp5, label %exit, label %loop.preheader
846
847loop.preheader:
848; CHECK: loop.preheader:
849; CHECK-NEXT: br label %loop
850 br label %loop
851
852loop:
853; CHECK: loop:
854; CHECK: %unrelated.cond.1 = icmp eq i32 %x1, %i
855; CHECK-NEXT: %unrelated.cond.2 = icmp eq i32 %x2, %i
856; CHECK-NEXT: %unrelated.cond.3 = icmp eq i32 %x3, %i
857; CHECK-NEXT: %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
858; CHECK-NEXT: %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
859; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
860 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
861 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
862 %unrelated.cond.1 = icmp eq i32 %x1, %i
863 %unrelated.cond.2 = icmp eq i32 %x2, %i
864 %unrelated.cond.3 = icmp eq i32 %x3, %i
865 %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
866 %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
867
868 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
869
870 %i.i64 = zext i32 %i to i64
871 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
872 %array.i = load i32, i32* %array.i.ptr, align 4
873 %loop.acc.next = add i32 %loop.acc, %array.i
874
875 %i.next = add nuw i32 %i, 1
876 %continue = icmp ult i32 %i.next, %n
877 br i1 %continue, label %loop, label %exit
878
879exit:
880 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
881 ret i32 %result
882}
883
884define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) {
885; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound
886entry:
887 %tmp5 = icmp sle i32 %n, 0
888 br i1 %tmp5, label %exit, label %loop.preheader
889
890loop.preheader:
891; CHECK: loop.preheader:
892; CHECK-NEXT: br label %loop
893 br label %loop
894
895loop:
896; CHECK: loop:
897; CHECK: %bound = add i32 %i, %x
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000898; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %bound
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000899; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
900 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
901 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
902 %bound = add i32 %i, %x
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000903 %within.bounds = icmp ult i32 %i, %bound
Artur Pilipenko8fb3d572017-01-25 16:00:44 +0000904 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
905
906 %i.i64 = zext i32 %i to i64
907 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
908 %array.i = load i32, i32* %array.i.ptr, align 4
909 %loop.acc.next = add i32 %loop.acc, %array.i
910
911 %i.next = add nsw i32 %i, 1
912 %continue = icmp slt i32 %i.next, %n
913 br i1 %continue, label %loop, label %exit
914
915exit:
916 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
917 ret i32 %result
918}
919
920define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) {
921; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate
922entry:
923 %tmp5 = icmp sle i32 %n, 0
924 br i1 %tmp5, label %exit, label %loop.preheader
925
926loop.preheader:
927; CHECK: loop.preheader:
928; CHECK-NEXT: br label %loop
929 br label %loop
930
931loop:
932; CHECK: loop:
933; CHECK: %guard.cond = icmp eq i32 %i, %x
934; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
935 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
936 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
937 %guard.cond = icmp eq i32 %i, %x
938 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
939
940 %i.i64 = zext i32 %i to i64
941 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
942 %array.i = load i32, i32* %array.i.ptr, align 4
943 %loop.acc.next = add i32 %loop.acc, %array.i
944
945 %i.next = add nsw i32 %i, 1
946 %continue = icmp slt i32 %i.next, %n
947 br i1 %continue, label %loop, label %exit
948
949exit:
950 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
951 ret i32 %result
Artur Pilipenko0860bfc2017-02-27 15:44:49 +0000952}
953
954define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
955; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length
956entry:
957 %tmp5 = icmp eq i32 %n, 0
958 br i1 %tmp5, label %exit, label %loop.preheader
959
960loop.preheader:
961; CHECK: loop.preheader:
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000962; CHECK: [[length:[^ ]+]] = zext i16 %length.i16 to i32
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000963; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, [[length]]
Artur Pilipenkoead69ee2017-10-12 21:21:17 +0000964; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, [[length]]
Artur Pilipenko889dc1e2017-09-22 13:13:57 +0000965; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
Artur Pilipenko0860bfc2017-02-27 15:44:49 +0000966; CHECK-NEXT: br label %loop
967 br label %loop
968
969loop:
970; CHECK: loop:
971; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
972 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
973 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
974 %length = zext i16 %length.i16 to i32
975 %within.bounds = icmp ult i32 %i, %length
976 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
977
978 %i.i64 = zext i32 %i to i64
979 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
980 %array.i = load i32, i32* %array.i.ptr, align 4
981 %loop.acc.next = add i32 %loop.acc, %array.i
982
983 %i.next = add nuw i32 %i, 1
984 %continue = icmp ult i32 %i.next, %n
985 br i1 %continue, label %loop, label %exit
986
987exit:
988 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
989 ret i32 %result
990}
991
992define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
993; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length
994entry:
995 %tmp5 = icmp eq i32 %n, 0
996 br i1 %tmp5, label %exit, label %loop.preheader
997
998loop.preheader:
999; CHECK: loop.preheader:
1000; CHECK-NEXT: br label %loop
1001 br label %loop
1002
1003loop:
1004; CHECK: loop:
1005; CHECK-NEXT: %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1006; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1007; CHECK-NEXT: %length.udiv = udiv i32 %length, %divider
1008; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %length.udiv
1009; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1010 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1011 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1012 %length.udiv = udiv i32 %length, %divider
1013 %within.bounds = icmp ult i32 %i, %length.udiv
1014 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1015
1016 %i.i64 = zext i32 %i to i64
1017 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1018 %array.i = load i32, i32* %array.i.ptr, align 4
1019 %loop.acc.next = add i32 %loop.acc, %array.i
1020
1021 %i.next = add nuw i32 %i, 1
1022 %continue = icmp ult i32 %i.next, %n
1023 br i1 %continue, label %loop, label %exit
1024
1025exit:
1026 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1027 ret i32 %result
1028}