1 ; 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
4 declare void @llvm.experimental.guard(i1, ...)
6 define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
7 ; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check
9 %tmp5 = icmp eq i32 %n, 0
10 br i1 %tmp5, label %exit, label %loop.preheader
13 ; CHECK: loop.preheader:
14 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
15 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
16 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
17 ; CHECK-NEXT: br label %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"() ]
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
33 %i.next = add nuw i32 %i, 1
34 %continue = icmp ult i32 %i.next, %n
35 br i1 %continue, label %loop, label %exit
38 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
42 define 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
45 %tmp5 = icmp eq i32 %n, 0
46 br i1 %tmp5, label %exit, label %loop.preheader
49 ; CHECK: loop.preheader:
50 ; CHECK: [[limit_check:[^ ]+]] = icmp ult i32 %n, %length
51 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
52 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
53 ; CHECK-NEXT: br label %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"() ]
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
69 %i.next = add nuw i32 %i, 1
70 %continue = icmp ule i32 %i.next, %n
71 br i1 %continue, label %loop, label %exit
74 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
78 define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
79 ; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check
81 %tmp5 = icmp eq i32 %n, 0
82 br i1 %tmp5, label %exit, label %loop.preheader
85 ; CHECK: loop.preheader:
86 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
87 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
88 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
89 ; CHECK-NEXT: br label %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"() ]
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
105 %i.next = add nuw i32 %i, 1
106 %continue = icmp ult i32 %i.next, %n
107 br i1 %continue, label %loop, label %exit
110 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
114 define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
115 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check
117 %tmp5 = icmp sle i32 %n, 0
118 br i1 %tmp5, label %exit, label %loop.preheader
121 ; CHECK: loop.preheader:
122 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
123 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
124 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
125 ; CHECK-NEXT: br label %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"() ]
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
141 %i.next = add nuw i32 %i, 1
142 %continue = icmp slt i32 %i.next, %n
143 br i1 %continue, label %loop, label %exit
146 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
150 define 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
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
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
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"() ]
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
177 %i.next = add nuw i32 %i, 1
178 %continue = icmp slt i32 %i.next, %n
179 br i1 %continue, label %loop, label %exit
182 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
186 define 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
189 %tmp5 = icmp sle i32 %n, 0
190 br i1 %tmp5, label %exit, label %loop.preheader
193 ; CHECK: loop.preheader:
194 ; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
195 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
196 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
197 ; CHECK-NEXT: br label %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"() ]
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
213 %i.next = add nuw i32 %i, 1
214 %continue = icmp sgt i32 %i.next, %n
215 br i1 %continue, label %exit, label %loop
218 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
222 define 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
225 %tmp5 = icmp sle i32 %n, 0
226 br i1 %tmp5, label %exit, label %loop.preheader
229 ; CHECK: loop.preheader:
230 ; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
231 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
232 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
233 ; CHECK-NEXT: br label %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"() ]
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
249 %i.next = add nuw i32 %i, 1
250 %continue = icmp sle i32 %i.next, %n
251 br i1 %continue, label %loop, label %exit
254 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
258 define 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
261 %tmp5 = icmp sle i32 %n, 0
262 br i1 %tmp5, label %exit, label %loop.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
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"() ]
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
286 %i.next = add i32 %i, 1
287 %continue = icmp slt i32 %i, %n
288 br i1 %continue, label %loop, label %exit
291 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
295 define 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
298 %tmp5 = icmp sle i32 %n, 0
299 br i1 %tmp5, label %exit, label %loop.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
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 ]
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"() ]
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
325 %continue = icmp slt i32 %i, %n
326 br i1 %continue, label %loop, label %exit
329 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
333 define 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
336 %tmp5 = icmp sle i32 %n, 0
337 br i1 %tmp5, label %exit, label %loop.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
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"() ]
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
362 %i.next = add i32 %i, 1
363 %continue = icmp sle i32 %i.next, %n
364 br i1 %continue, label %loop, label %exit
367 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
371 define 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
374 %tmp5 = icmp sle i32 %n, 0
375 br i1 %tmp5, label %exit, label %loop.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
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"() ]
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
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
405 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
409 define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
410 ; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n
412 %tmp5 = icmp sle i32 %n, 0
413 br i1 %tmp5, label %exit, label %loop.preheader
416 ; CHECK: loop.preheader:
417 ; CHECK-NEXT: br label %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"() ]
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
434 %i.next = add nsw i32 %i, 1
435 %continue = icmp ne i32 %i.next, %n
436 br i1 %continue, label %loop, label %exit
439 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
443 define 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
446 %tmp5 = icmp sle i32 %n, 0
447 br i1 %tmp5, label %exit, label %loop.preheader
450 ; CHECK: loop.preheader:
451 ; CHECK-NEXT: br label %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"() ]
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
468 %i.next = add nsw i32 %i, 2
469 %continue = icmp slt i32 %i.next, %n
470 br i1 %continue, label %loop, label %exit
473 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
477 define 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
480 %tmp5 = icmp sle i32 %n, 0
481 br i1 %tmp5, label %exit, label %loop.preheader
484 ; CHECK: loop.preheader:
485 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
486 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
487 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
488 ; CHECK-NEXT: br label %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 ]
498 %within.bounds = icmp ult i32 %j, %length
499 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
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
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
512 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
516 define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i,
517 i32 %start.j, i32 %length,
519 ; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check
521 %tmp5 = icmp sle i32 %n, 0
522 br i1 %tmp5, label %exit, label %loop.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
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 ]
541 %within.bounds = icmp ult i32 %j, %length
542 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
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
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
555 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
559 define 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
562 %tmp5 = icmp sle i32 %n, 0
563 br i1 %tmp5, label %exit, label %loop.preheader
566 ; CHECK: loop.preheader:
567 ; CHECK-NEXT: br label %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 ]
578 %within.bounds = icmp ult i16 %j, %length
579 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
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
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
592 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
596 define 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
599 %tmp5 = icmp sle i32 %n, 0
600 br i1 %tmp5, label %exit, label %loop.preheader
603 ; CHECK: loop.preheader:
604 ; CHECK-NEXT: br label %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 ]
613 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
615 %within.bounds = icmp ult i32 %j, %length
616 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
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
623 %j.next = add nsw i32 %j, 2
624 %i.next = add nsw i32 %i, 1
625 %continue = icmp slt i32 %i.next, %n
626 br i1 %continue, label %loop, label %exit
629 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
633 define 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
637 %tmp5 = icmp eq i32 %n, 0
638 br i1 %tmp5, label %exit, label %loop.preheader
641 ; CHECK: loop.preheader:
642 ; 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}}
644 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
645 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
646 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
647 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
648 ; CHECK-NEXT: br label %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"() ]
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
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
671 %i.next = add nuw i32 %i, 1
672 %continue = icmp ult i32 %i.next, %n
673 br i1 %continue, label %loop, label %exit
676 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
680 define 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
685 %tmp5 = icmp eq i32 %n, 0
686 br i1 %tmp5, label %exit, label %loop.preheader
689 ; CHECK: loop.preheader:
690 ; 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}}
692 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
693 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
694 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
695 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
696 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
697 ; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
698 ; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
699 ; CHECK-NEXT: br label %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"() ]
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
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
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
729 %i.next = add nuw i32 %i, 1
730 %continue = icmp ult i32 %i.next, %n
731 br i1 %continue, label %loop, label %exit
734 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
738 define 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
743 %tmp5 = icmp eq i32 %n, 0
744 br i1 %tmp5, label %exit, label %loop.preheader
747 ; CHECK: loop.preheader:
748 ; 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}}
750 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
751 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
752 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
753 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
754 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
755 ; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
756 ; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
757 ; CHECK-NEXT: br label %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"() ]
766 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
767 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
769 %within.bounds.1 = icmp ult i32 %i, %length.1
770 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ]
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
777 %within.bounds.2 = icmp ult i32 %i, %length.2
778 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ]
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
784 %within.bounds.3 = icmp ult i32 %i, %length.3
785 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ]
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
791 %i.next = add nuw i32 %i, 1
792 %continue = icmp ult i32 %i.next, %n
793 br i1 %continue, label %loop, label %exit
796 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
800 define 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
803 %tmp5 = icmp eq i32 %n, 0
804 br i1 %tmp5, label %exit, label %loop.preheader
807 ; CHECK: loop.preheader:
808 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
809 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
810 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
811 ; CHECK-NEXT: br label %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"() ]
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
831 %i.next = add nuw i32 %i, 1
832 %continue = icmp ult i32 %i.next, %n
833 br i1 %continue, label %loop, label %exit
836 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
840 ; Don't change the guard condition if there were no widened subconditions
841 define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
842 ; CHECK-LABEL: @test_no_widened_conditions
844 %tmp5 = icmp eq i32 %n, 0
845 br i1 %tmp5, label %exit, label %loop.preheader
848 ; CHECK: loop.preheader:
849 ; CHECK-NEXT: br label %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
868 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
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
875 %i.next = add nuw i32 %i, 1
876 %continue = icmp ult i32 %i.next, %n
877 br i1 %continue, label %loop, label %exit
880 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
884 define 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
887 %tmp5 = icmp sle i32 %n, 0
888 br i1 %tmp5, label %exit, label %loop.preheader
891 ; CHECK: loop.preheader:
892 ; CHECK-NEXT: br label %loop
897 ; CHECK: %bound = add i32 %i, %x
898 ; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %bound
899 ; 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
903 %within.bounds = icmp ult i32 %i, %bound
904 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
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
911 %i.next = add nsw i32 %i, 1
912 %continue = icmp slt i32 %i.next, %n
913 br i1 %continue, label %loop, label %exit
916 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
920 define 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
923 %tmp5 = icmp sle i32 %n, 0
924 br i1 %tmp5, label %exit, label %loop.preheader
927 ; CHECK: loop.preheader:
928 ; CHECK-NEXT: br label %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"() ]
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
945 %i.next = add nsw i32 %i, 1
946 %continue = icmp slt i32 %i.next, %n
947 br i1 %continue, label %loop, label %exit
950 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
954 define 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
957 %tmp5 = icmp eq i32 %n, 0
958 br i1 %tmp5, label %exit, label %loop.preheader
961 ; CHECK: loop.preheader:
962 ; CHECK: [[length:[^ ]+]] = zext i16 %length.i16 to i32
963 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, [[length]]
964 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, [[length]]
965 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
966 ; CHECK-NEXT: br label %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"() ]
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
983 %i.next = add nuw i32 %i, 1
984 %continue = icmp ult i32 %i.next, %n
985 br i1 %continue, label %loop, label %exit
988 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
992 define 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
995 %tmp5 = icmp eq i32 %n, 0
996 br i1 %tmp5, label %exit, label %loop.preheader
999 ; CHECK: loop.preheader:
1000 ; CHECK-NEXT: br label %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"() ]
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
1021 %i.next = add nuw i32 %i, 1
1022 %continue = icmp ult i32 %i.next, %n
1023 br i1 %continue, label %loop, label %exit
1026 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]