1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -loop-predication -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
3; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
4
5declare void @llvm.experimental.guard(i1, ...)
6
7define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
8; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
11; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
12; CHECK:       loop.preheader:
13; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
14; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
15; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
16; CHECK-NEXT:    br label [[LOOP:%.*]]
17; CHECK:       loop:
18; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
19; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
20; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
21; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
22; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
23; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
24; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
25;
26entry:
27  %tmp5 = icmp eq i32 %n, 0
28  br i1 %tmp5, label %exit, label %loop.preheader
29
30loop.preheader:                                   ; preds = %entry
31  br label %loop
32
33loop:                                             ; preds = %guarded, %loop.preheader
34  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
35  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
36  %within.bounds = icmp ult i32 %i, %length
37  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
38  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
39  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
40
41deopt:                                            ; preds = %loop
42  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
43  ret i32 %deoptcall
44
45guarded:                                          ; preds = %loop
46  %i.i64 = zext i32 %i to i64
47  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
48  %array.i = load i32, i32* %array.i.ptr, align 4
49  %loop.acc.next = add i32 %loop.acc, %array.i
50  %i.next = add nuw i32 %i, 1
51  %continue = icmp ult i32 %i.next, %n
52  br i1 %continue, label %loop, label %exit
53
54exit:                                             ; preds = %guarded, %entry
55  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
56  ret i32 %result
57}
58
59define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) {
60; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(
61; CHECK-NEXT:  entry:
62; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
63; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
64; CHECK:       loop.preheader:
65; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]
66; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
67; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
68; CHECK-NEXT:    br label [[LOOP:%.*]]
69; CHECK:       loop:
70; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
71; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
72; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
73; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
74; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
75; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
76; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
77;
78entry:
79  %tmp5 = icmp eq i32 %n, 0
80  br i1 %tmp5, label %exit, label %loop.preheader
81
82loop.preheader:                                   ; preds = %entry
83  br label %loop
84
85loop:                                             ; preds = %guarded, %loop.preheader
86  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
87  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
88  %within.bounds = icmp ult i32 %i, %length
89  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
90  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
91  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
92
93deopt:                                            ; preds = %loop
94  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
95  ret i32 %deoptcall
96
97guarded:                                          ; preds = %loop
98  %i.i64 = zext i32 %i to i64
99  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
100  %array.i = load i32, i32* %array.i.ptr, align 4
101  %loop.acc.next = add i32 %loop.acc, %array.i
102  %i.next = add nuw i32 %i, 1
103  %continue = icmp ule i32 %i.next, %n
104  br i1 %continue, label %loop, label %exit
105
106exit:                                             ; preds = %guarded, %entry
107  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
108  ret i32 %result
109}
110
111define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
112; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(
113; CHECK-NEXT:  entry:
114; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
115; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
116; CHECK:       loop.preheader:
117; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
118; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
119; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
120; CHECK-NEXT:    br label [[LOOP:%.*]]
121; CHECK:       loop:
122; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
123; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
124; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ugt i32 [[LENGTH]], [[I]]
125; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
126; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
127; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
128; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
129;
130entry:
131  %tmp5 = icmp eq i32 %n, 0
132  br i1 %tmp5, label %exit, label %loop.preheader
133
134loop.preheader:                                   ; preds = %entry
135  br label %loop
136
137loop:                                             ; preds = %guarded, %loop.preheader
138  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
139  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
140  %within.bounds = icmp ugt i32 %length, %i
141  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
142  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
143  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
144
145deopt:                                            ; preds = %loop
146  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
147  ret i32 %deoptcall
148
149guarded:                                          ; preds = %loop
150  %i.i64 = zext i32 %i to i64
151  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
152  %array.i = load i32, i32* %array.i.ptr, align 4
153  %loop.acc.next = add i32 %loop.acc, %array.i
154  %i.next = add nuw i32 %i, 1
155  %continue = icmp ult i32 %i.next, %n
156  br i1 %continue, label %loop, label %exit
157
158exit:                                             ; preds = %guarded, %entry
159  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
160  ret i32 %result
161}
162
163define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
164; CHECK-LABEL: @signed_loop_0_to_n_ult_check(
165; CHECK-NEXT:  entry:
166; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
167; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
168; CHECK:       loop.preheader:
169; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
170; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
171; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
172; CHECK-NEXT:    br label [[LOOP:%.*]]
173; CHECK:       loop:
174; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
175; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
176; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
177; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
178; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
179; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
180; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
181
182;
183entry:
184  %tmp5 = icmp sle i32 %n, 0
185  br i1 %tmp5, label %exit, label %loop.preheader
186
187loop.preheader:                                   ; preds = %entry
188  br label %loop
189
190loop:                                             ; preds = %guarded, %loop.preheader
191  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
192  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
193  %within.bounds = icmp ult i32 %i, %length
194  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
195  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
196  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
197
198deopt:                                            ; preds = %loop
199  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
200  ret i32 %deoptcall
201
202guarded:                                          ; preds = %loop
203  %i.i64 = zext i32 %i to i64
204  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
205  %array.i = load i32, i32* %array.i.ptr, align 4
206  %loop.acc.next = add i32 %loop.acc, %array.i
207  %i.next = add nuw i32 %i, 1
208  %continue = icmp slt i32 %i.next, %n
209  br i1 %continue, label %loop, label %exit
210
211exit:                                             ; preds = %guarded, %entry
212  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
213  ret i32 %result
214}
215
216define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
217; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(
218; CHECK-NEXT:  entry:
219; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
220; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], !range !1
221; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
222; CHECK:       loop.preheader:
223; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
224; CHECK-NEXT:    [[TMP1:%.*]] = and i1 true, [[TMP0]]
225; CHECK-NEXT:    br label [[LOOP:%.*]]
226; CHECK:       loop:
227; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
228; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
229; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
230; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
231; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
232; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
233; CHECK-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
234;
235entry:
236  %tmp5 = icmp sle i32 %n, 0
237  %length = load i32, i32* %length.ptr, !range !1
238  br i1 %tmp5, label %exit, label %loop.preheader
239
240loop.preheader:                                   ; preds = %entry
241  br label %loop
242
243loop:                                             ; preds = %guarded, %loop.preheader
244  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
245  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
246  %within.bounds = icmp ult i32 %i, %length
247  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
248  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
249  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
250
251deopt:                                            ; preds = %loop
252  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
253  ret i32 %deoptcall
254
255guarded:                                          ; preds = %loop
256  %i.i64 = zext i32 %i to i64
257  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
258  %array.i = load i32, i32* %array.i.ptr, align 4
259  %loop.acc.next = add i32 %loop.acc, %array.i
260  %i.next = add nuw i32 %i, 1
261  %continue = icmp slt i32 %i.next, %n
262  br i1 %continue, label %loop, label %exit
263
264exit:                                             ; preds = %guarded, %entry
265  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
266  ret i32 %result
267}
268
269define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) {
270; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(
271; CHECK-NEXT:  entry:
272; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
273; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
274; CHECK:       loop.preheader:
275; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
276; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
277; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
278; CHECK-NEXT:    br label [[LOOP:%.*]]
279; CHECK:       loop:
280; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
281; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
282; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
283; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
284; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
285; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
286; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
287;
288entry:
289  %tmp5 = icmp sle i32 %n, 0
290  br i1 %tmp5, label %exit, label %loop.preheader
291
292loop.preheader:                                   ; preds = %entry
293  br label %loop
294
295loop:                                             ; preds = %guarded, %loop.preheader
296  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
297  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
298  %within.bounds = icmp ult i32 %i, %length
299  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
300  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
301  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
302
303deopt:                                            ; preds = %loop
304  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
305  ret i32 %deoptcall
306
307guarded:                                          ; preds = %loop
308  %i.i64 = zext i32 %i to i64
309  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
310  %array.i = load i32, i32* %array.i.ptr, align 4
311  %loop.acc.next = add i32 %loop.acc, %array.i
312  %i.next = add nuw i32 %i, 1
313  %continue = icmp sgt i32 %i.next, %n
314  br i1 %continue, label %exit, label %loop
315
316exit:                                             ; preds = %guarded, %entry
317  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
318  ret i32 %result
319}
320
321define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) {
322; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(
323; CHECK-NEXT:  entry:
324; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
325; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
326; CHECK:       loop.preheader:
327; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
328; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
329; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
330; CHECK-NEXT:    br label [[LOOP:%.*]]
331; CHECK:       loop:
332; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
333; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
334; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
335; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
336; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
337; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
338; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
339;
340entry:
341  %tmp5 = icmp sle i32 %n, 0
342  br i1 %tmp5, label %exit, label %loop.preheader
343
344loop.preheader:                                   ; preds = %entry
345  br label %loop
346
347loop:                                             ; preds = %guarded, %loop.preheader
348  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
349  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
350  %within.bounds = icmp ult i32 %i, %length
351  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
352  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
353  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
354
355deopt:                                            ; preds = %loop
356  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
357  ret i32 %deoptcall
358
359guarded:                                          ; preds = %loop
360  %i.i64 = zext i32 %i to i64
361  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
362  %array.i = load i32, i32* %array.i.ptr, align 4
363  %loop.acc.next = add i32 %loop.acc, %array.i
364  %i.next = add nuw i32 %i, 1
365  %continue = icmp sle i32 %i.next, %n
366  br i1 %continue, label %loop, label %exit
367
368exit:                                             ; preds = %guarded, %entry
369  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
370  ret i32 %result
371}
372
373define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) {
374; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(
375; CHECK-NEXT:  entry:
376; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
377; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
378; CHECK:       loop.preheader:
379; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
380; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
381; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
382; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
383; CHECK-NEXT:    br label [[LOOP:%.*]]
384; CHECK:       loop:
385; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
386; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
387; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
388; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
389; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
390; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
391; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
392;
393entry:
394  %tmp5 = icmp sle i32 %n, 0
395  br i1 %tmp5, label %exit, label %loop.preheader
396
397loop.preheader:                                   ; preds = %entry
398  br label %loop
399
400loop:                                             ; preds = %guarded, %loop.preheader
401  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
402  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
403  %within.bounds = icmp ult i32 %i, %length
404  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
405  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
406  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
407
408deopt:                                            ; preds = %loop
409  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
410  ret i32 %deoptcall
411
412guarded:                                          ; preds = %loop
413  %i.i64 = zext i32 %i to i64
414  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
415  %array.i = load i32, i32* %array.i.ptr, align 4
416  %loop.acc.next = add i32 %loop.acc, %array.i
417  %i.next = add i32 %i, 1
418  %continue = icmp slt i32 %i, %n
419  br i1 %continue, label %loop, label %exit
420
421exit:                                             ; preds = %guarded, %entry
422  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
423  ret i32 %result
424}
425
426define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) {
427; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(
428; CHECK-NEXT:  entry:
429; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
430; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
431; CHECK:       loop.preheader:
432; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2
433; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
434; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
435; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
436; CHECK-NEXT:    br label [[LOOP:%.*]]
437; CHECK:       loop:
438; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
439; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
440; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
441; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
442; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
443; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
444; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
445; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
446;
447entry:
448  %tmp5 = icmp sle i32 %n, 0
449  br i1 %tmp5, label %exit, label %loop.preheader
450
451loop.preheader:                                   ; preds = %entry
452  br label %loop
453
454loop:                                             ; preds = %guarded, %loop.preheader
455  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
456  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
457  %i.next = add i32 %i, 1
458  %within.bounds = icmp ult i32 %i.next, %length
459  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
460  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
461  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
462
463deopt:                                            ; preds = %loop
464  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
465  ret i32 %deoptcall
466
467guarded:                                          ; preds = %loop
468  %i.i64 = zext i32 %i to i64
469  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
470  %array.i = load i32, i32* %array.i.ptr, align 4
471  %loop.acc.next = add i32 %loop.acc, %array.i
472  %continue = icmp slt i32 %i, %n
473  br i1 %continue, label %loop, label %exit
474
475exit:                                             ; preds = %guarded, %entry
476  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
477  ret i32 %result
478}
479
480define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
481; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(
482; CHECK-NEXT:  entry:
483; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
484; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
485; CHECK:       loop.preheader:
486; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
487; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]
488; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
489; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
490; CHECK-NEXT:    br label [[LOOP:%.*]]
491; CHECK:       loop:
492; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
493; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
494; CHECK-NEXT:    [[I_OFFSET:%.*]] = add i32 [[I]], 1
495; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]
496; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
497; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
498; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
499; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
500;
501entry:
502  %tmp5 = icmp sle i32 %n, 0
503  br i1 %tmp5, label %exit, label %loop.preheader
504
505loop.preheader:                                   ; preds = %entry
506  br label %loop
507
508loop:                                             ; preds = %guarded, %loop.preheader
509  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
510  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
511  %i.offset = add i32 %i, 1
512  %within.bounds = icmp ult i32 %i.offset, %length
513  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
514  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
515  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
516
517deopt:                                            ; preds = %loop
518  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
519  ret i32 %deoptcall
520
521guarded:                                          ; preds = %loop
522  %i.i64 = zext i32 %i to i64
523  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
524  %array.i = load i32, i32* %array.i.ptr, align 4
525  %loop.acc.next = add i32 %loop.acc, %array.i
526  %i.next = add i32 %i, 1
527  %continue = icmp sle i32 %i.next, %n
528  br i1 %continue, label %loop, label %exit
529
530exit:                                             ; preds = %guarded, %entry
531  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
532  ret i32 %result
533}
534
535define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
536; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(
537; CHECK-NEXT:  entry:
538; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
539; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
540; CHECK:       loop.preheader:
541; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
542; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]
543; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
544; CHECK-NEXT:    br label [[LOOP:%.*]]
545; CHECK:       loop:
546; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
547; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
548; CHECK-NEXT:    [[I_OFFSET:%.*]] = add i32 [[I]], 1
549; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]]
550; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
551; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
552; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
553; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
554;
555entry:
556  %tmp5 = icmp sle i32 %n, 0
557  br i1 %tmp5, label %exit, label %loop.preheader
558
559loop.preheader:                                   ; preds = %entry
560  br label %loop
561
562loop:                                             ; preds = %guarded, %loop.preheader
563  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
564  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
565  %i.offset = add i32 %i, 1
566  %within.bounds = icmp ult i32 %i.offset, %length
567  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
568  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
569  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
570
571deopt:                                            ; preds = %loop
572  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
573  ret i32 %deoptcall
574
575guarded:                                          ; preds = %loop
576  %i.i64 = zext i32 %i to i64
577  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
578  %array.i = load i32, i32* %array.i.ptr, align 4
579  %loop.acc.next = add i32 %loop.acc, %array.i
580  %i.next = add i32 %i, 1
581  %i.next.offset = add i32 %i.next, 1
582  %continue = icmp sle i32 %i.next.offset, %n
583  br i1 %continue, label %loop, label %exit
584
585exit:                                             ; preds = %guarded, %entry
586  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
587  ret i32 %result
588}
589
590define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
591; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(
592; CHECK-NEXT:  entry:
593; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
594; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
595; CHECK:       loop.preheader:
596; CHECK-NEXT:    br label [[LOOP:%.*]]
597; CHECK:       loop:
598; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
599; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
600; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
601; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
602; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
603; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
604;
605entry:
606  %tmp5 = icmp sle i32 %n, 0
607  br i1 %tmp5, label %exit, label %loop.preheader
608
609loop.preheader:                                   ; preds = %entry
610  br label %loop
611
612loop:                                             ; preds = %guarded, %loop.preheader
613  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
614  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
615  %within.bounds = icmp ult i32 %i, %length
616  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
617  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
618  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
619
620deopt:                                            ; preds = %loop
621  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
622  ret i32 %deoptcall
623
624guarded:                                          ; preds = %loop
625  %i.i64 = zext i32 %i to i64
626  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
627  %array.i = load i32, i32* %array.i.ptr, align 4
628  %loop.acc.next = add i32 %loop.acc, %array.i
629  %i.next = add nsw i32 %i, 1
630  %continue = icmp ne i32 %i.next, %n
631  br i1 %continue, label %loop, label %exit
632
633exit:                                             ; preds = %guarded, %entry
634  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
635  ret i32 %result
636}
637
638define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) {
639; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(
640; CHECK-NEXT:  entry:
641; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
642; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
643; CHECK:       loop.preheader:
644; CHECK-NEXT:    br label [[LOOP:%.*]]
645; CHECK:       loop:
646; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
647; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
648; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
649; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
650; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
651; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
652;
653entry:
654  %tmp5 = icmp sle i32 %n, 0
655  br i1 %tmp5, label %exit, label %loop.preheader
656
657loop.preheader:                                   ; preds = %entry
658  br label %loop
659
660loop:                                             ; preds = %guarded, %loop.preheader
661  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
662  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
663  %within.bounds = icmp ult i32 %i, %length
664  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
665  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
666  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
667
668deopt:                                            ; preds = %loop
669  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
670  ret i32 %deoptcall
671
672guarded:                                          ; preds = %loop
673  %i.i64 = zext i32 %i to i64
674  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
675  %array.i = load i32, i32* %array.i.ptr, align 4
676  %loop.acc.next = add i32 %loop.acc, %array.i
677  %i.next = add nsw i32 %i, 2
678  %continue = icmp slt i32 %i.next, %n
679  br i1 %continue, label %loop, label %exit
680
681exit:                                             ; preds = %guarded, %entry
682  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
683  ret i32 %result
684}
685
686define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) {
687; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(
688; CHECK-NEXT:  entry:
689; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
690; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
691; CHECK:       loop.preheader:
692; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
693; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
694; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
695; CHECK-NEXT:    br label [[LOOP:%.*]]
696; CHECK:       loop:
697; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
698; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
699; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
700; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
701; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
702; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
703; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
704; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
705;
706entry:
707  %tmp5 = icmp sle i32 %n, 0
708  br i1 %tmp5, label %exit, label %loop.preheader
709
710loop.preheader:                                   ; preds = %entry
711  br label %loop
712
713loop:                                             ; preds = %guarded, %loop.preheader
714  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
715  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
716  %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
717  %within.bounds = icmp ult i32 %j, %length
718  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
719  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
720  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
721
722deopt:                                            ; preds = %loop
723  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
724  ret i32 %deoptcall
725
726guarded:                                          ; preds = %loop
727  %i.i64 = zext i32 %i to i64
728  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
729  %array.i = load i32, i32* %array.i.ptr, align 4
730  %loop.acc.next = add i32 %loop.acc, %array.i
731  %j.next = add nsw i32 %j, 1
732  %i.next = add nsw i32 %i, 1
733  %continue = icmp slt i32 %i.next, %n
734  br i1 %continue, label %loop, label %exit
735
736exit:                                             ; preds = %guarded, %entry
737  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
738  ret i32 %result
739}
740
741define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i, i32 %start.j, i32 %length, i32 %n) {
742; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(
743; CHECK-NEXT:  entry:
744; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
745; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
746; CHECK:       loop.preheader:
747; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]
748; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]
749; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]
750; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]
751; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
752; CHECK-NEXT:    br label [[LOOP:%.*]]
753; CHECK:       loop:
754; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
755; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]
756; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]
757; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]]
758; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
759; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
760; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
761; CHECK-NEXT:    br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
762;
763entry:
764  %tmp5 = icmp sle i32 %n, 0
765  br i1 %tmp5, label %exit, label %loop.preheader
766
767loop.preheader:                                   ; preds = %entry
768  br label %loop
769
770loop:                                             ; preds = %guarded, %loop.preheader
771  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
772  %i = phi i32 [ %i.next, %guarded ], [ %start.i, %loop.preheader ]
773  %j = phi i32 [ %j.next, %guarded ], [ %start.j, %loop.preheader ]
774  %within.bounds = icmp ult i32 %j, %length
775  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
776  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
777  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
778
779deopt:                                            ; preds = %loop
780  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
781  ret i32 %deoptcall
782
783guarded:                                          ; preds = %loop
784  %i.i64 = zext i32 %i to i64
785  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
786  %array.i = load i32, i32* %array.i.ptr, align 4
787  %loop.acc.next = add i32 %loop.acc, %array.i
788  %j.next = add i32 %j, 1
789  %i.next = add i32 %i, 1
790  %continue = icmp slt i32 %i.next, %n
791  br i1 %continue, label %loop, label %exit
792
793exit:                                             ; preds = %guarded, %entry
794  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
795  ret i32 %result
796}
797
798define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) {
799; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(
800; CHECK-NEXT:  entry:
801; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
802; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
803; CHECK:       loop.preheader:
804; CHECK-NEXT:    br label [[LOOP:%.*]]
805; CHECK:       loop:
806; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
807; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
808; CHECK-NEXT:    [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
809; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]
810; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
811; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
812; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
813;
814entry:
815  %tmp5 = icmp sle i32 %n, 0
816  br i1 %tmp5, label %exit, label %loop.preheader
817
818loop.preheader:                                   ; preds = %entry
819  br label %loop
820
821loop:                                             ; preds = %guarded, %loop.preheader
822  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
823  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
824  %j = phi i16 [ %j.next, %guarded ], [ 0, %loop.preheader ]
825  %within.bounds = icmp ult i16 %j, %length
826  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
827  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
828  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
829
830deopt:                                            ; preds = %loop
831  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
832  ret i32 %deoptcall
833
834guarded:                                          ; preds = %loop
835  %i.i64 = zext i32 %i to i64
836  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
837  %array.i = load i32, i32* %array.i.ptr, align 4
838  %loop.acc.next = add i32 %loop.acc, %array.i
839  %j.next = add i16 %j, 1
840  %i.next = add i32 %i, 1
841  %continue = icmp slt i32 %i.next, %n
842  br i1 %continue, label %loop, label %exit
843
844exit:                                             ; preds = %guarded, %entry
845  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
846  ret i32 %result
847}
848
849define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) {
850; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(
851; CHECK-NEXT:  entry:
852; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
853; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
854; CHECK:       loop.preheader:
855; CHECK-NEXT:    br label [[LOOP:%.*]]
856; CHECK:       loop:
857; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
858; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
859; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
860; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
861; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
862; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
863; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
864;
865entry:
866  %tmp5 = icmp sle i32 %n, 0
867  br i1 %tmp5, label %exit, label %loop.preheader
868
869loop.preheader:                                   ; preds = %entry
870  br label %loop
871
872loop:                                             ; preds = %guarded, %loop.preheader
873  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
874  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
875  %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
876  %within.bounds = icmp ult i32 %j, %length
877  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
878  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
879  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
880
881deopt:                                            ; preds = %loop
882  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
883  ret i32 %deoptcall
884
885guarded:                                          ; preds = %loop
886  %i.i64 = zext i32 %i to i64
887  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
888  %array.i = load i32, i32* %array.i.ptr, align 4
889  %loop.acc.next = add i32 %loop.acc, %array.i
890  %j.next = add nsw i32 %j, 2
891  %i.next = add nsw i32 %i, 1
892  %continue = icmp slt i32 %i.next, %n
893  br i1 %continue, label %loop, label %exit
894
895exit:                                             ; preds = %guarded, %entry
896  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
897  ret i32 %result
898}
899
900define i32 @two_range_checks(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32 %n) {
901; CHECK-LABEL: @two_range_checks(
902; CHECK-NEXT:  entry:
903; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
904; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
905; CHECK:       loop.preheader:
906; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
907; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]
908; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
909; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
910; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]]
911; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
912; CHECK-NEXT:    br label [[LOOP:%.*]]
913; CHECK:       loop:
914; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
915; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
916; CHECK-NEXT:    [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
917; CHECK-NEXT:    [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
918; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]]
919; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
920; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
921; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]]
922; CHECK-NEXT:    [[TMP7:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
923; CHECK-NEXT:    br i1 [[TMP7]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
924;
925entry:
926  %tmp5 = icmp eq i32 %n, 0
927  br i1 %tmp5, label %exit, label %loop.preheader
928
929loop.preheader:                                   ; preds = %entry
930  br label %loop
931
932loop:                                             ; preds = %guarded, %loop.preheader
933  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
934  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
935  %within.bounds.1 = icmp ult i32 %i, %length.1
936  %within.bounds.2 = icmp ult i32 %i, %length.2
937  %within.bounds = and i1 %within.bounds.1, %within.bounds.2
938  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
939  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
940  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
941
942deopt:                                            ; preds = %loop
943  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
944  ret i32 %deoptcall
945
946guarded:                                          ; preds = %loop
947  %i.i64 = zext i32 %i to i64
948  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
949  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
950  %loop.acc.1 = add i32 %loop.acc, %array.1.i
951  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
952  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
953  %loop.acc.next = add i32 %loop.acc.1, %array.2.i
954  %i.next = add nuw i32 %i, 1
955  %continue = icmp ult i32 %i.next, %n
956  br i1 %continue, label %loop, label %exit
957
958exit:                                             ; preds = %guarded, %entry
959  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
960  ret i32 %result
961}
962
963define i32 @three_range_checks(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32* %array.3, i32 %length.3, i32 %n) {
964; CHECK-LABEL: @three_range_checks(
965; CHECK-NEXT:  entry:
966; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
967; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
968; CHECK:       loop.preheader:
969; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
970; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]
971; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
972; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
973; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
974; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
975; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
976; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]]
977; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
978; CHECK-NEXT:    br label [[LOOP:%.*]]
979; CHECK:       loop:
980; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
981; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
982; CHECK-NEXT:    [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
983; CHECK-NEXT:    [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
984; CHECK-NEXT:    [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]
985; CHECK-NEXT:    [[WITHIN_BOUNDS_1_AND_2:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WITHIN_BOUNDS_2]]
986; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = and i1 [[WITHIN_BOUNDS_1_AND_2]], [[WITHIN_BOUNDS_3]]
987; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
988; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
989; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]]
990; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
991; CHECK-NEXT:    [[TMP11:%.*]] = and i1 [[TMP10]], [[WIDENABLE_COND]]
992; CHECK-NEXT:    br i1 [[TMP11]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
993;
994entry:
995  %tmp5 = icmp eq i32 %n, 0
996  br i1 %tmp5, label %exit, label %loop.preheader
997
998loop.preheader:                                   ; preds = %entry
999  br label %loop
1000
1001loop:                                             ; preds = %guarded, %loop.preheader
1002  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1003  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1004  %within.bounds.1 = icmp ult i32 %i, %length.1
1005  %within.bounds.2 = icmp ult i32 %i, %length.2
1006  %within.bounds.3 = icmp ult i32 %i, %length.3
1007  %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
1008  %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
1009  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1010  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1011  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1012
1013deopt:                                            ; preds = %loop
1014  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1015  ret i32 %deoptcall
1016
1017guarded:                                          ; preds = %loop
1018  %i.i64 = zext i32 %i to i64
1019  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1020  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1021  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1022  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1023  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1024  %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1025  %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1026  %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1027  %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1028  %i.next = add nuw i32 %i, 1
1029  %continue = icmp ult i32 %i.next, %n
1030  br i1 %continue, label %loop, label %exit
1031
1032exit:                                             ; preds = %guarded, %entry
1033  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1034  ret i32 %result
1035}
1036
1037define i32 @three_guards(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32* %array.3, i32 %length.3, i32 %n) {
1038; CHECK-LABEL: @three_guards(
1039; CHECK-NEXT:  entry:
1040; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1041; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1042; CHECK:       loop.preheader:
1043; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1044; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1045; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1046; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1047; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1048; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1049; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1050; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1051; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1052; CHECK-NEXT:    br label [[LOOP:%.*]]
1053; CHECK:       loop:
1054; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED6:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1055; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED6]] ], [ 0, [[LOOP_PREHEADER]] ]
1056; CHECK-NEXT:    [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
1057; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1058; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS_1]], [[WIDENABLE_COND]]
1059; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
1060; CHECK-NEXT:    br i1 [[TMP9]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
1061; CHECK:       deopt:
1062; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1063; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1064; CHECK:       guarded:
1065; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1066; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1067; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1068; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1069; CHECK-NEXT:    [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
1070; CHECK-NEXT:    [[WIDENABLE_COND4:%.*]] = call i1 @llvm.experimental.widenable.condition()
1071; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND5:%.*]] = and i1 [[WITHIN_BOUNDS_2]], [[WIDENABLE_COND4]]
1072; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND4]]
1073; CHECK-NEXT:    br i1 [[TMP10]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
1074; CHECK:       deopt2:
1075; CHECK-NEXT:    [[DEOPTCALL3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1076; CHECK-NEXT:    ret i32 [[DEOPTCALL3]]
1077; CHECK:       guarded1:
1078; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1079; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1080; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1081; CHECK-NEXT:    [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]]
1082; CHECK-NEXT:    [[WIDENABLE_COND9:%.*]] = call i1 @llvm.experimental.widenable.condition()
1083; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND10:%.*]] = and i1 [[WITHIN_BOUNDS_3]], [[WIDENABLE_COND9]]
1084; CHECK-NEXT:    [[TMP11:%.*]] = and i1 [[TMP8]], [[WIDENABLE_COND9]]
1085; CHECK-NEXT:    br i1 [[TMP11]], label [[GUARDED6]], label [[DEOPT7:%.*]], !prof !0
1086; CHECK:       deopt7:
1087; CHECK-NEXT:    [[DEOPTCALL8:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1088; CHECK-NEXT:    ret i32 [[DEOPTCALL8]]
1089; CHECK:       guarded6:
1090; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1091; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1092; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1093; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1094; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1095; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1096; CHECK:       exit.loopexit:
1097; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED6]] ]
1098; CHECK-NEXT:    br label [[EXIT]]
1099; CHECK:       exit:
1100; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1101; CHECK-NEXT:    ret i32 [[RESULT]]
1102;
1103entry:
1104  %tmp5 = icmp eq i32 %n, 0
1105  br i1 %tmp5, label %exit, label %loop.preheader
1106
1107loop.preheader:                                   ; preds = %entry
1108  br label %loop
1109
1110loop:                                             ; preds = %guarded6, %loop.preheader
1111  %loop.acc = phi i32 [ %loop.acc.next, %guarded6 ], [ 0, %loop.preheader ]
1112  %i = phi i32 [ %i.next, %guarded6 ], [ 0, %loop.preheader ]
1113  %within.bounds.1 = icmp ult i32 %i, %length.1
1114  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1115  %exiplicit_guard_cond = and i1 %within.bounds.1, %widenable_cond
1116  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1117
1118deopt:                                            ; preds = %loop
1119  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1120  ret i32 %deoptcall
1121
1122guarded:                                          ; preds = %loop
1123  %i.i64 = zext i32 %i to i64
1124  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1125  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1126  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1127  %within.bounds.2 = icmp ult i32 %i, %length.2
1128  %widenable_cond4 = call i1 @llvm.experimental.widenable.condition()
1129  %exiplicit_guard_cond5 = and i1 %within.bounds.2, %widenable_cond4
1130  br i1 %exiplicit_guard_cond5, label %guarded1, label %deopt2, !prof !0
1131
1132deopt2:                                           ; preds = %guarded
1133  %deoptcall3 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1134  ret i32 %deoptcall3
1135
1136guarded1:                                         ; preds = %guarded
1137  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1138  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1139  %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1140  %within.bounds.3 = icmp ult i32 %i, %length.3
1141  %widenable_cond9 = call i1 @llvm.experimental.widenable.condition()
1142  %exiplicit_guard_cond10 = and i1 %within.bounds.3, %widenable_cond9
1143  br i1 %exiplicit_guard_cond10, label %guarded6, label %deopt7, !prof !0
1144
1145deopt7:                                           ; preds = %guarded1
1146  %deoptcall8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1147  ret i32 %deoptcall8
1148
1149guarded6:                                         ; preds = %guarded1
1150  %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1151  %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1152  %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1153  %i.next = add nuw i32 %i, 1
1154  %continue = icmp ult i32 %i.next, %n
1155  br i1 %continue, label %loop, label %exit
1156
1157exit:                                             ; preds = %guarded6, %entry
1158  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded6 ]
1159  ret i32 %result
1160}
1161
1162define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) {
1163; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(
1164; CHECK-NEXT:  entry:
1165; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1166; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1167; CHECK:       loop.preheader:
1168; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
1169; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1170; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1171; CHECK-NEXT:    br label [[LOOP:%.*]]
1172; CHECK:       loop:
1173; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1174; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1175; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1176; CHECK-NEXT:    [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
1177; CHECK-NEXT:    [[GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED_COND]]
1178; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1179; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
1180; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
1181; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
1182; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1183;
1184entry:
1185  %tmp5 = icmp eq i32 %n, 0
1186  br i1 %tmp5, label %exit, label %loop.preheader
1187
1188loop.preheader:                                   ; preds = %entry
1189  br label %loop
1190
1191loop:                                             ; preds = %guarded, %loop.preheader
1192  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1193  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1194  %within.bounds = icmp ult i32 %i, %length
1195  %unrelated.cond = icmp ult i32 %x, %length
1196  %guard.cond = and i1 %within.bounds, %unrelated.cond
1197  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1198  %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1199  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1200
1201deopt:                                            ; preds = %loop
1202  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1203  ret i32 %deoptcall
1204
1205guarded:                                          ; preds = %loop
1206  %i.i64 = zext i32 %i to i64
1207  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1208  %array.i = load i32, i32* %array.i.ptr, align 4
1209  %loop.acc.next = add i32 %loop.acc, %array.i
1210  %i.next = add nuw i32 %i, 1
1211  %continue = icmp ult i32 %i.next, %n
1212  br i1 %continue, label %loop, label %exit
1213
1214exit:                                             ; preds = %guarded, %entry
1215  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1216  ret i32 %result
1217}
1218
1219define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
1220; CHECK-LABEL: @test_no_widened_conditions(
1221; CHECK-NEXT:  entry:
1222; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1223; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1224; CHECK:       loop.preheader:
1225; CHECK-NEXT:    br label [[LOOP:%.*]]
1226; CHECK:       loop:
1227; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1228; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1229; CHECK-NEXT:    [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]
1230; CHECK-NEXT:    [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]
1231; CHECK-NEXT:    [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]
1232; CHECK-NEXT:    [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]
1233; CHECK-NEXT:    [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]
1234; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1235; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
1236; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1237;
1238entry:
1239  %tmp5 = icmp eq i32 %n, 0
1240  br i1 %tmp5, label %exit, label %loop.preheader
1241
1242loop.preheader:                                   ; preds = %entry
1243  br label %loop
1244
1245loop:                                             ; preds = %guarded, %loop.preheader
1246  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1247  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1248  %unrelated.cond.1 = icmp eq i32 %x1, %i
1249  %unrelated.cond.2 = icmp eq i32 %x2, %i
1250  %unrelated.cond.3 = icmp eq i32 %x3, %i
1251  %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
1252  %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
1253  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1254  %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1255  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1256
1257deopt:                                            ; preds = %loop
1258  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1259  ret i32 %deoptcall
1260
1261guarded:                                          ; preds = %loop
1262  %i.i64 = zext i32 %i to i64
1263  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1264  %array.i = load i32, i32* %array.i.ptr, align 4
1265  %loop.acc.next = add i32 %loop.acc, %array.i
1266  %i.next = add nuw i32 %i, 1
1267  %continue = icmp ult i32 %i.next, %n
1268  br i1 %continue, label %loop, label %exit
1269
1270exit:                                             ; preds = %guarded, %entry
1271  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1272  ret i32 %result
1273}
1274
1275define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) {
1276; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(
1277; CHECK-NEXT:  entry:
1278; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1279; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1280; CHECK:       loop.preheader:
1281; CHECK-NEXT:    br label [[LOOP:%.*]]
1282; CHECK:       loop:
1283; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1284; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1285; CHECK-NEXT:    [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]
1286; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]
1287; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1288; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1289; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1290;
1291entry:
1292  %tmp5 = icmp sle i32 %n, 0
1293  br i1 %tmp5, label %exit, label %loop.preheader
1294
1295loop.preheader:                                   ; preds = %entry
1296  br label %loop
1297
1298loop:                                             ; preds = %guarded, %loop.preheader
1299  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1300  %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
1301  %bound = add i32 %i, %x
1302  %within.bounds = icmp ult i32 %i, %bound
1303  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1304  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1305  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1306
1307deopt:                                            ; preds = %loop
1308  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1309  ret i32 %deoptcall
1310
1311guarded:                                          ; preds = %loop
1312  %i.i64 = zext i32 %i to i64
1313  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1314  %array.i = load i32, i32* %array.i.ptr, align 4
1315  %loop.acc.next = add i32 %loop.acc, %array.i
1316  %i.next = add nsw i32 %i, 1
1317  %continue = icmp slt i32 %i.next, %n
1318  br i1 %continue, label %loop, label %exit
1319
1320exit:                                             ; preds = %guarded, %entry
1321  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1322  ret i32 %result
1323}
1324
1325define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) {
1326; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(
1327; CHECK-NEXT:  entry:
1328; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1329; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1330; CHECK:       loop.preheader:
1331; CHECK-NEXT:    br label [[LOOP:%.*]]
1332; CHECK:       loop:
1333; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1334; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1335; CHECK-NEXT:    [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]
1336; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1337; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
1338; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1339;
1340entry:
1341  %tmp5 = icmp sle i32 %n, 0
1342  br i1 %tmp5, label %exit, label %loop.preheader
1343
1344loop.preheader:                                   ; preds = %entry
1345  br label %loop
1346
1347loop:                                             ; preds = %guarded, %loop.preheader
1348  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1349  %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
1350  %guard.cond = icmp eq i32 %i, %x
1351  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1352  %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1353  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1354
1355deopt:                                            ; preds = %loop
1356  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1357  ret i32 %deoptcall
1358
1359guarded:                                          ; preds = %loop
1360  %i.i64 = zext i32 %i to i64
1361  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1362  %array.i = load i32, i32* %array.i.ptr, align 4
1363  %loop.acc.next = add i32 %loop.acc, %array.i
1364  %i.next = add nsw i32 %i, 1
1365  %continue = icmp slt i32 %i.next, %n
1366  br i1 %continue, label %loop, label %exit
1367
1368exit:                                             ; preds = %guarded, %entry
1369  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1370  ret i32 %result
1371}
1372
1373define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
1374; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(
1375; CHECK-NEXT:  entry:
1376; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1377; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1378; CHECK:       loop.preheader:
1379; CHECK-NEXT:    [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32
1380; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1381; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]
1382; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1383; CHECK-NEXT:    br label [[LOOP:%.*]]
1384; CHECK:       loop:
1385; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1386; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1387; CHECK-NEXT:    [[LENGTH:%.*]] = zext i16 [[LENGTH_I16]] to i32
1388; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1389; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1390; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1391; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
1392; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1393;
1394entry:
1395  %tmp5 = icmp eq i32 %n, 0
1396  br i1 %tmp5, label %exit, label %loop.preheader
1397
1398loop.preheader:                                   ; preds = %entry
1399  br label %loop
1400
1401loop:                                             ; preds = %guarded, %loop.preheader
1402  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1403  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1404  %length = zext i16 %length.i16 to i32
1405  %within.bounds = icmp ult i32 %i, %length
1406  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1407  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1408  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1409
1410deopt:                                            ; preds = %loop
1411  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1412  ret i32 %deoptcall
1413
1414guarded:                                          ; preds = %loop
1415  %i.i64 = zext i32 %i to i64
1416  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1417  %array.i = load i32, i32* %array.i.ptr, align 4
1418  %loop.acc.next = add i32 %loop.acc, %array.i
1419  %i.next = add nuw i32 %i, 1
1420  %continue = icmp ult i32 %i.next, %n
1421  br i1 %continue, label %loop, label %exit
1422
1423exit:                                             ; preds = %guarded, %entry
1424  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1425  ret i32 %result
1426}
1427
1428define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
1429; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(
1430; CHECK-NEXT:  entry:
1431; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1432; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1433; CHECK:       loop.preheader:
1434; CHECK-NEXT:    br label [[LOOP:%.*]]
1435; CHECK:       loop:
1436; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1437; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1438; CHECK-NEXT:    [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]
1439; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_UDIV]]
1440; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1441; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1442; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1443;
1444entry:
1445  %tmp5 = icmp eq i32 %n, 0
1446  br i1 %tmp5, label %exit, label %loop.preheader
1447
1448loop.preheader:                                   ; preds = %entry
1449  br label %loop
1450
1451loop:                                             ; preds = %guarded, %loop.preheader
1452  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1453  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1454  %length.udiv = udiv i32 %length, %divider
1455  %within.bounds = icmp ult i32 %i, %length.udiv
1456  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1457  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1458  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1459
1460deopt:                                            ; preds = %loop
1461  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1462  ret i32 %deoptcall
1463
1464guarded:                                          ; preds = %loop
1465  %i.i64 = zext i32 %i to i64
1466  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1467  %array.i = load i32, i32* %array.i.ptr, align 4
1468  %loop.acc.next = add i32 %loop.acc, %array.i
1469  %i.next = add nuw i32 %i, 1
1470  %continue = icmp ult i32 %i.next, %n
1471  br i1 %continue, label %loop, label %exit
1472
1473exit:                                             ; preds = %guarded, %entry
1474  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1475  ret i32 %result
1476}
1477
1478declare i32 @llvm.experimental.deoptimize.i32(...)
1479
1480; Function Attrs: inaccessiblememonly nounwind
1481declare i1 @llvm.experimental.widenable.condition() #0
1482
1483attributes #0 = { inaccessiblememonly nounwind }
1484
1485!0 = !{!"branch_weights", i32 1048576, i32 1}
1486!1 = !{i32 1, i32 -2147483648}
1487