[PowerPC] Do not emit record-form rotates when record-form andi suffices
[llvm-core.git] / test / Transforms / LoopPredication / basic.ll
blob59842902b0e1f8c280cb5811aa49db7dd0c2b592
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
8 entry:
9   %tmp5 = icmp eq i32 %n, 0
10   br i1 %tmp5, label %exit, label %loop.preheader
12 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
18   br label %loop
20 loop:
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"() ]
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
37 exit:
38   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
39   ret i32 %result
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
44 entry:
45   %tmp5 = icmp eq i32 %n, 0
46   br i1 %tmp5, label %exit, label %loop.preheader
48 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
54   br label %loop
56 loop:
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"() ]
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
73 exit:
74   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
75   ret i32 %result
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
80 entry:
81   %tmp5 = icmp eq i32 %n, 0
82   br i1 %tmp5, label %exit, label %loop.preheader
84 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
90   br label %loop
92 loop:
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"() ]
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
109 exit:
110   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
111   ret i32 %result
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
116 entry:
117   %tmp5 = icmp sle i32 %n, 0
118   br i1 %tmp5, label %exit, label %loop.preheader
120 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
126   br label %loop
128 loop:
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"() ]
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
145 exit:
146   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
147   ret i32 %result
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
152 entry:
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
157 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
162   br label %loop
164 loop:
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"() ]
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
181 exit:
182   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
183   ret i32 %result
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
188 entry:
189   %tmp5 = icmp sle i32 %n, 0
190   br i1 %tmp5, label %exit, label %loop.preheader
192 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
198   br label %loop
200 loop:
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"() ]
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
217 exit:
218   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
219   ret i32 %result
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
224 entry:
225   %tmp5 = icmp sle i32 %n, 0
226   br i1 %tmp5, label %exit, label %loop.preheader
228 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
234   br label %loop
236 loop:
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"() ]
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
253 exit:
254   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
255   ret i32 %result
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
260 entry:
261   %tmp5 = icmp sle i32 %n, 0
262   br i1 %tmp5, label %exit, label %loop.preheader
264 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
271   br label %loop
273 loop:
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"() ]
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
290 exit:
291   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
292   ret i32 %result
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
297 entry:
298   %tmp5 = icmp sle i32 %n, 0
299   br i1 %tmp5, label %exit, label %loop.preheader
301 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
308   br label %loop
310 loop:
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 ]
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
328 exit:
329   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
330   ret i32 %result
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
335 entry:
336   %tmp5 = icmp sle i32 %n, 0
337   br i1 %tmp5, label %exit, label %loop.preheader
339 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
346   br label %loop
348 loop:
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"() ]
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
366 exit:
367   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
368   ret i32 %result
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
373 entry:
374   %tmp5 = icmp sle i32 %n, 0
375   br i1 %tmp5, label %exit, label %loop.preheader
377 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
383   br label %loop
385 loop:
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"() ]
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
404 exit:
405   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
406   ret i32 %result
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
411 entry:
412   %tmp5 = icmp sle i32 %n, 0
413   br i1 %tmp5, label %exit, label %loop.preheader
415 loop.preheader:
416 ; CHECK: loop.preheader:
417 ; CHECK-NEXT: br label %loop
418   br label %loop
420 loop:
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"() ]
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
438 exit:
439   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
440   ret i32 %result
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
445 entry:
446   %tmp5 = icmp sle i32 %n, 0
447   br i1 %tmp5, label %exit, label %loop.preheader
449 loop.preheader:
450 ; CHECK: loop.preheader:
451 ; CHECK-NEXT: br label %loop
452   br label %loop
454 loop:
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"() ]
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
472 exit:
473   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
474   ret i32 %result
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
479 entry:
480   %tmp5 = icmp sle i32 %n, 0
481   br i1 %tmp5, label %exit, label %loop.preheader
483 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
489   br label %loop
491 loop:
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 ]
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
511 exit:
512   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
513   ret i32 %result
516 define 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
520 entry:
521   %tmp5 = icmp sle i32 %n, 0
522   br i1 %tmp5, label %exit, label %loop.preheader
524 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
532   br label %loop
534 loop:
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 ]
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
554 exit:
555   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
556   ret i32 %result
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
561 entry:
562   %tmp5 = icmp sle i32 %n, 0
563   br i1 %tmp5, label %exit, label %loop.preheader
565 loop.preheader:
566 ; CHECK: loop.preheader:
567 ; CHECK-NEXT: br label %loop
568   br label %loop
570 loop:
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 ]
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
591 exit:
592   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
593   ret i32 %result
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
598 entry:
599   %tmp5 = icmp sle i32 %n, 0
600   br i1 %tmp5, label %exit, label %loop.preheader
602 loop.preheader:
603 ; CHECK: loop.preheader:
604 ; CHECK-NEXT: br label %loop
605   br label %loop
607 loop:
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 ]
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
628 exit:
629   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
630   ret i32 %result
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
636 entry:
637   %tmp5 = icmp eq i32 %n, 0
638   br i1 %tmp5, label %exit, label %loop.preheader
640 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
649   br label %loop
651 loop:
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"() ]
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
675 exit:
676   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
677   ret i32 %result
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
684 entry:
685   %tmp5 = icmp eq i32 %n, 0
686   br i1 %tmp5, label %exit, label %loop.preheader
688 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
700   br label %loop
702 loop:
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"() ]
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
733 exit:
734   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
735   ret i32 %result
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
742 entry:
743   %tmp5 = icmp eq i32 %n, 0
744   br i1 %tmp5, label %exit, label %loop.preheader
746 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
758   br label %loop
760 loop:
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"() ]
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
795 exit:
796   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
797   ret i32 %result
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
802 entry:
803   %tmp5 = icmp eq i32 %n, 0
804   br i1 %tmp5, label %exit, label %loop.preheader
806 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
812   br label %loop
814 loop:
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"() ]
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
835 exit:
836   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
837   ret i32 %result
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
843 entry:
844   %tmp5 = icmp eq i32 %n, 0
845   br i1 %tmp5, label %exit, label %loop.preheader
847 loop.preheader:
848 ; CHECK: loop.preheader:
849 ; CHECK-NEXT: br label %loop
850   br label %loop
852 loop:
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
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
879 exit:
880   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
881   ret i32 %result
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
886 entry:
887   %tmp5 = icmp sle i32 %n, 0
888   br i1 %tmp5, label %exit, label %loop.preheader
890 loop.preheader:
891 ; CHECK: loop.preheader:
892 ; CHECK-NEXT: br label %loop
893   br label %loop
895 loop:
896 ; CHECK: 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
915 exit:
916   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
917   ret i32 %result
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
922 entry:
923   %tmp5 = icmp sle i32 %n, 0
924   br i1 %tmp5, label %exit, label %loop.preheader
926 loop.preheader:
927 ; CHECK: loop.preheader:
928 ; CHECK-NEXT: br label %loop
929   br label %loop
931 loop:
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"() ]
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
949 exit:
950   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
951   ret i32 %result
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
956 entry:
957   %tmp5 = icmp eq i32 %n, 0
958   br i1 %tmp5, label %exit, label %loop.preheader
960 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
967   br label %loop
969 loop:
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"() ]
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
987 exit:
988   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
989   ret i32 %result
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
994 entry:
995   %tmp5 = icmp eq i32 %n, 0
996   br i1 %tmp5, label %exit, label %loop.preheader
998 loop.preheader:
999 ; CHECK: loop.preheader:
1000 ; CHECK-NEXT: br label %loop
1001   br label %loop
1003 loop:
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"() ]
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
1025 exit:
1026   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1027   ret i32 %result