• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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:
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
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
42define 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:
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
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
78define 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:
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
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
114define 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:
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
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
150define 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
186define 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:
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
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:
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
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
258define 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
409define 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:
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
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
516define 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
598entry:
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 ]
613  %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
614
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
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
627
628exit:
629  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
630  ret i32 %result
631}
632
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:
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
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:
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
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:
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
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
800define 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:
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
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
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"() ]
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
952}
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:
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
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}
1029