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:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
21; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
22; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
23; CHECK:       deopt:
24; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
25; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
26; CHECK:       guarded:
27; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
28; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
29; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
30; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
31; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
32; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
33; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
34; CHECK:       exit.loopexit:
35; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
36; CHECK-NEXT:    br label [[EXIT]]
37; CHECK:       exit:
38; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
39; CHECK-NEXT:    ret i32 [[RESULT]]
40;
41entry:
42  %tmp5 = icmp eq i32 %n, 0
43  br i1 %tmp5, label %exit, label %loop.preheader
44
45loop.preheader:                                   ; preds = %entry
46  br label %loop
47
48loop:                                             ; preds = %guarded, %loop.preheader
49  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
50  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
51  %within.bounds = icmp ult i32 %i, %length
52  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
53  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
54  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
55
56deopt:                                            ; preds = %loop
57  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
58  ret i32 %deoptcall
59
60guarded:                                          ; preds = %loop
61  %i.i64 = zext i32 %i to i64
62  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
63  %array.i = load i32, i32* %array.i.ptr, align 4
64  %loop.acc.next = add i32 %loop.acc, %array.i
65  %i.next = add nuw i32 %i, 1
66  %continue = icmp ult i32 %i.next, %n
67  br i1 %continue, label %loop, label %exit
68
69exit:                                             ; preds = %guarded, %entry
70  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
71  ret i32 %result
72}
73
74define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) {
75; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(
76; CHECK-NEXT:  entry:
77; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
78; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
79; CHECK:       loop.preheader:
80; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]
81; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
82; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
83; CHECK-NEXT:    br label [[LOOP:%.*]]
84; CHECK:       loop:
85; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
86; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
87; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
88; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
89; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
90; CHECK:       deopt:
91; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
92; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
93; CHECK:       guarded:
94; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
95; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
96; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
97; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
98; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
99; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]
100; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
101; CHECK:       exit.loopexit:
102; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
103; CHECK-NEXT:    br label [[EXIT]]
104; CHECK:       exit:
105; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
106; CHECK-NEXT:    ret i32 [[RESULT]]
107;
108entry:
109  %tmp5 = icmp eq i32 %n, 0
110  br i1 %tmp5, label %exit, label %loop.preheader
111
112loop.preheader:                                   ; preds = %entry
113  br label %loop
114
115loop:                                             ; preds = %guarded, %loop.preheader
116  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
117  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
118  %within.bounds = icmp ult i32 %i, %length
119  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
120  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
121  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
122
123deopt:                                            ; preds = %loop
124  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
125  ret i32 %deoptcall
126
127guarded:                                          ; preds = %loop
128  %i.i64 = zext i32 %i to i64
129  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
130  %array.i = load i32, i32* %array.i.ptr, align 4
131  %loop.acc.next = add i32 %loop.acc, %array.i
132  %i.next = add nuw i32 %i, 1
133  %continue = icmp ule i32 %i.next, %n
134  br i1 %continue, label %loop, label %exit
135
136exit:                                             ; preds = %guarded, %entry
137  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
138  ret i32 %result
139}
140
141define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
142; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(
143; CHECK-NEXT:  entry:
144; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
145; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
146; CHECK:       loop.preheader:
147; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
148; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
149; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
150; CHECK-NEXT:    br label [[LOOP:%.*]]
151; CHECK:       loop:
152; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
153; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
154; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
155; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
156; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
157; CHECK:       deopt:
158; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
159; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
160; CHECK:       guarded:
161; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
162; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
163; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
164; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
165; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
166; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
167; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
168; CHECK:       exit.loopexit:
169; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
170; CHECK-NEXT:    br label [[EXIT]]
171; CHECK:       exit:
172; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
173; CHECK-NEXT:    ret i32 [[RESULT]]
174;
175entry:
176  %tmp5 = icmp eq i32 %n, 0
177  br i1 %tmp5, label %exit, label %loop.preheader
178
179loop.preheader:                                   ; preds = %entry
180  br label %loop
181
182loop:                                             ; preds = %guarded, %loop.preheader
183  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
184  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
185  %within.bounds = icmp ugt i32 %length, %i
186  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
187  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
188  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
189
190deopt:                                            ; preds = %loop
191  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
192  ret i32 %deoptcall
193
194guarded:                                          ; preds = %loop
195  %i.i64 = zext i32 %i to i64
196  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
197  %array.i = load i32, i32* %array.i.ptr, align 4
198  %loop.acc.next = add i32 %loop.acc, %array.i
199  %i.next = add nuw i32 %i, 1
200  %continue = icmp ult i32 %i.next, %n
201  br i1 %continue, label %loop, label %exit
202
203exit:                                             ; preds = %guarded, %entry
204  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
205  ret i32 %result
206}
207
208define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
209; CHECK-LABEL: @signed_loop_0_to_n_ult_check(
210; CHECK-NEXT:  entry:
211; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
212; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
213; CHECK:       loop.preheader:
214; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
215; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
216; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
217; CHECK-NEXT:    br label [[LOOP:%.*]]
218; CHECK:       loop:
219; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
220; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
221; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
222; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
223; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
224; CHECK:       deopt:
225; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
226; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
227; CHECK:       guarded:
228; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
229; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
230; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
231; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
232; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
233; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
234; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
235; CHECK:       exit.loopexit:
236; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
237; CHECK-NEXT:    br label [[EXIT]]
238; CHECK:       exit:
239; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
240; CHECK-NEXT:    ret i32 [[RESULT]]
241;
242
243entry:
244  %tmp5 = icmp sle i32 %n, 0
245  br i1 %tmp5, label %exit, label %loop.preheader
246
247loop.preheader:                                   ; preds = %entry
248  br label %loop
249
250loop:                                             ; preds = %guarded, %loop.preheader
251  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
252  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
253  %within.bounds = icmp ult i32 %i, %length
254  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
255  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
256  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
257
258deopt:                                            ; preds = %loop
259  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
260  ret i32 %deoptcall
261
262guarded:                                          ; preds = %loop
263  %i.i64 = zext i32 %i to i64
264  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
265  %array.i = load i32, i32* %array.i.ptr, align 4
266  %loop.acc.next = add i32 %loop.acc, %array.i
267  %i.next = add nuw i32 %i, 1
268  %continue = icmp slt i32 %i.next, %n
269  br i1 %continue, label %loop, label %exit
270
271exit:                                             ; preds = %guarded, %entry
272  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
273  ret i32 %result
274}
275
276define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
277; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(
278; CHECK-NEXT:  entry:
279; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
280; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], !range !1
281; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
282; CHECK:       loop.preheader:
283; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
284; CHECK-NEXT:    [[TMP1:%.*]] = and i1 true, [[TMP0]]
285; CHECK-NEXT:    br label [[LOOP:%.*]]
286; CHECK:       loop:
287; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
288; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
289; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
290; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
291; CHECK-NEXT:    br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
292; CHECK:       deopt:
293; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
294; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
295; CHECK:       guarded:
296; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
297; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
298; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
299; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
300; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
301; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
302; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
303; CHECK:       exit.loopexit:
304; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
305; CHECK-NEXT:    br label [[EXIT]]
306; CHECK:       exit:
307; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
308; CHECK-NEXT:    ret i32 [[RESULT]]
309;
310entry:
311  %tmp5 = icmp sle i32 %n, 0
312  %length = load i32, i32* %length.ptr, !range !1
313  br i1 %tmp5, label %exit, label %loop.preheader
314
315loop.preheader:                                   ; preds = %entry
316  br label %loop
317
318loop:                                             ; preds = %guarded, %loop.preheader
319  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
320  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
321  %within.bounds = icmp ult i32 %i, %length
322  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
323  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
324  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
325
326deopt:                                            ; preds = %loop
327  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
328  ret i32 %deoptcall
329
330guarded:                                          ; preds = %loop
331  %i.i64 = zext i32 %i to i64
332  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
333  %array.i = load i32, i32* %array.i.ptr, align 4
334  %loop.acc.next = add i32 %loop.acc, %array.i
335  %i.next = add nuw i32 %i, 1
336  %continue = icmp slt i32 %i.next, %n
337  br i1 %continue, label %loop, label %exit
338
339exit:                                             ; preds = %guarded, %entry
340  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
341  ret i32 %result
342}
343
344define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) {
345; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(
346; CHECK-NEXT:  entry:
347; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
348; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
349; CHECK:       loop.preheader:
350; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
351; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
352; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
353; CHECK-NEXT:    br label [[LOOP:%.*]]
354; CHECK:       loop:
355; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
356; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
357; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
358; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
359; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
360; CHECK:       deopt:
361; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
362; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
363; CHECK:       guarded:
364; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
365; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
366; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
367; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
368; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
369; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]
370; CHECK-NEXT:    br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
371; CHECK:       exit.loopexit:
372; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
373; CHECK-NEXT:    br label [[EXIT]]
374; CHECK:       exit:
375; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
376; CHECK-NEXT:    ret i32 [[RESULT]]
377;
378entry:
379  %tmp5 = icmp sle i32 %n, 0
380  br i1 %tmp5, label %exit, label %loop.preheader
381
382loop.preheader:                                   ; preds = %entry
383  br label %loop
384
385loop:                                             ; preds = %guarded, %loop.preheader
386  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
387  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
388  %within.bounds = icmp ult i32 %i, %length
389  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
390  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
391  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
392
393deopt:                                            ; preds = %loop
394  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
395  ret i32 %deoptcall
396
397guarded:                                          ; preds = %loop
398  %i.i64 = zext i32 %i to i64
399  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
400  %array.i = load i32, i32* %array.i.ptr, align 4
401  %loop.acc.next = add i32 %loop.acc, %array.i
402  %i.next = add nuw i32 %i, 1
403  %continue = icmp sgt i32 %i.next, %n
404  br i1 %continue, label %exit, label %loop
405
406exit:                                             ; preds = %guarded, %entry
407  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
408  ret i32 %result
409}
410
411define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) {
412; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(
413; CHECK-NEXT:  entry:
414; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
415; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
416; CHECK:       loop.preheader:
417; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
418; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
419; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
420; CHECK-NEXT:    br label [[LOOP:%.*]]
421; CHECK:       loop:
422; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
423; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
424; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
425; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
426; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
427; CHECK:       deopt:
428; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
429; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
430; CHECK:       guarded:
431; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
432; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
433; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
434; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
435; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
436; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
437; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
438; CHECK:       exit.loopexit:
439; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
440; CHECK-NEXT:    br label [[EXIT]]
441; CHECK:       exit:
442; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
443; CHECK-NEXT:    ret i32 [[RESULT]]
444;
445entry:
446  %tmp5 = icmp sle i32 %n, 0
447  br i1 %tmp5, label %exit, label %loop.preheader
448
449loop.preheader:                                   ; preds = %entry
450  br label %loop
451
452loop:                                             ; preds = %guarded, %loop.preheader
453  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
454  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
455  %within.bounds = icmp ult i32 %i, %length
456  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
457  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
458  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
459
460deopt:                                            ; preds = %loop
461  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
462  ret i32 %deoptcall
463
464guarded:                                          ; preds = %loop
465  %i.i64 = zext i32 %i to i64
466  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
467  %array.i = load i32, i32* %array.i.ptr, align 4
468  %loop.acc.next = add i32 %loop.acc, %array.i
469  %i.next = add nuw i32 %i, 1
470  %continue = icmp sle i32 %i.next, %n
471  br i1 %continue, label %loop, label %exit
472
473exit:                                             ; preds = %guarded, %entry
474  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
475  ret i32 %result
476}
477
478define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) {
479; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(
480; CHECK-NEXT:  entry:
481; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
482; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
483; CHECK:       loop.preheader:
484; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
485; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
486; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
487; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
488; CHECK-NEXT:    br label [[LOOP:%.*]]
489; CHECK:       loop:
490; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
491; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
492; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
493; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
494; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
495; CHECK:       deopt:
496; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
497; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
498; CHECK:       guarded:
499; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
500; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
501; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
502; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
503; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
504; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
505; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
506; CHECK:       exit.loopexit:
507; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
508; CHECK-NEXT:    br label [[EXIT]]
509; CHECK:       exit:
510; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
511; CHECK-NEXT:    ret i32 [[RESULT]]
512;
513entry:
514  %tmp5 = icmp sle i32 %n, 0
515  br i1 %tmp5, label %exit, label %loop.preheader
516
517loop.preheader:                                   ; preds = %entry
518  br label %loop
519
520loop:                                             ; preds = %guarded, %loop.preheader
521  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
522  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
523  %within.bounds = icmp ult i32 %i, %length
524  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
525  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
526  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
527
528deopt:                                            ; preds = %loop
529  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
530  ret i32 %deoptcall
531
532guarded:                                          ; preds = %loop
533  %i.i64 = zext i32 %i to i64
534  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
535  %array.i = load i32, i32* %array.i.ptr, align 4
536  %loop.acc.next = add i32 %loop.acc, %array.i
537  %i.next = add i32 %i, 1
538  %continue = icmp slt i32 %i, %n
539  br i1 %continue, label %loop, label %exit
540
541exit:                                             ; preds = %guarded, %entry
542  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
543  ret i32 %result
544}
545
546define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) {
547; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(
548; CHECK-NEXT:  entry:
549; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
550; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
551; CHECK:       loop.preheader:
552; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2
553; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
554; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
555; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
556; CHECK-NEXT:    br label [[LOOP:%.*]]
557; CHECK:       loop:
558; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
559; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
560; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
561; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
562; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
563; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
564; CHECK:       deopt:
565; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
566; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
567; CHECK:       guarded:
568; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
569; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
570; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
571; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
572; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
573; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
574; CHECK:       exit.loopexit:
575; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
576; CHECK-NEXT:    br label [[EXIT]]
577; CHECK:       exit:
578; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
579; CHECK-NEXT:    ret i32 [[RESULT]]
580;
581entry:
582  %tmp5 = icmp sle i32 %n, 0
583  br i1 %tmp5, label %exit, label %loop.preheader
584
585loop.preheader:                                   ; preds = %entry
586  br label %loop
587
588loop:                                             ; preds = %guarded, %loop.preheader
589  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
590  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
591  %i.next = add i32 %i, 1
592  %within.bounds = icmp ult i32 %i.next, %length
593  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
594  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
595  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
596
597deopt:                                            ; preds = %loop
598  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
599  ret i32 %deoptcall
600
601guarded:                                          ; preds = %loop
602  %i.i64 = zext i32 %i to i64
603  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
604  %array.i = load i32, i32* %array.i.ptr, align 4
605  %loop.acc.next = add i32 %loop.acc, %array.i
606  %continue = icmp slt i32 %i, %n
607  br i1 %continue, label %loop, label %exit
608
609exit:                                             ; preds = %guarded, %entry
610  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
611  ret i32 %result
612}
613
614define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
615; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(
616; CHECK-NEXT:  entry:
617; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
618; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
619; CHECK:       loop.preheader:
620; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
621; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]
622; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
623; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
624; CHECK-NEXT:    br label [[LOOP:%.*]]
625; CHECK:       loop:
626; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
627; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
628; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
629; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
630; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
631; CHECK:       deopt:
632; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
633; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
634; CHECK:       guarded:
635; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
636; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
637; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
638; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
639; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
640; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
641; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
642; CHECK:       exit.loopexit:
643; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
644; CHECK-NEXT:    br label [[EXIT]]
645; CHECK:       exit:
646; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
647; CHECK-NEXT:    ret i32 [[RESULT]]
648;
649entry:
650  %tmp5 = icmp sle i32 %n, 0
651  br i1 %tmp5, label %exit, label %loop.preheader
652
653loop.preheader:                                   ; preds = %entry
654  br label %loop
655
656loop:                                             ; preds = %guarded, %loop.preheader
657  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
658  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
659  %i.offset = add i32 %i, 1
660  %within.bounds = icmp ult i32 %i.offset, %length
661  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
662  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
663  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
664
665deopt:                                            ; preds = %loop
666  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
667  ret i32 %deoptcall
668
669guarded:                                          ; preds = %loop
670  %i.i64 = zext i32 %i to i64
671  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
672  %array.i = load i32, i32* %array.i.ptr, align 4
673  %loop.acc.next = add i32 %loop.acc, %array.i
674  %i.next = add i32 %i, 1
675  %continue = icmp sle i32 %i.next, %n
676  br i1 %continue, label %loop, label %exit
677
678exit:                                             ; preds = %guarded, %entry
679  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
680  ret i32 %result
681}
682
683define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
684; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(
685; CHECK-NEXT:  entry:
686; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
687; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
688; CHECK:       loop.preheader:
689; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
690; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]
691; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
692; CHECK-NEXT:    br label [[LOOP:%.*]]
693; CHECK:       loop:
694; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
695; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
696; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
697; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
698; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
699; CHECK:       deopt:
700; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
701; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
702; CHECK:       guarded:
703; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
704; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
705; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
706; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
707; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
708; CHECK-NEXT:    [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1
709; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]
710; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
711; CHECK:       exit.loopexit:
712; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
713; CHECK-NEXT:    br label [[EXIT]]
714; CHECK:       exit:
715; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
716; CHECK-NEXT:    ret i32 [[RESULT]]
717;
718entry:
719  %tmp5 = icmp sle i32 %n, 0
720  br i1 %tmp5, label %exit, label %loop.preheader
721
722loop.preheader:                                   ; preds = %entry
723  br label %loop
724
725loop:                                             ; preds = %guarded, %loop.preheader
726  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
727  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
728  %i.offset = add i32 %i, 1
729  %within.bounds = icmp ult i32 %i.offset, %length
730  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
731  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
732  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
733
734deopt:                                            ; preds = %loop
735  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
736  ret i32 %deoptcall
737
738guarded:                                          ; preds = %loop
739  %i.i64 = zext i32 %i to i64
740  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
741  %array.i = load i32, i32* %array.i.ptr, align 4
742  %loop.acc.next = add i32 %loop.acc, %array.i
743  %i.next = add i32 %i, 1
744  %i.next.offset = add i32 %i.next, 1
745  %continue = icmp sle i32 %i.next.offset, %n
746  br i1 %continue, label %loop, label %exit
747
748exit:                                             ; preds = %guarded, %entry
749  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
750  ret i32 %result
751}
752
753define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
754; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(
755; CHECK-NEXT:  entry:
756; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
757; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
758; CHECK:       loop.preheader:
759; CHECK-NEXT:    br label [[LOOP:%.*]]
760; CHECK:       loop:
761; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
762; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
763; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
764; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
765; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
766; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
767; CHECK:       deopt:
768; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
769; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
770; CHECK:       guarded:
771; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
772; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
773; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
774; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
775; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
776; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
777; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
778; CHECK:       exit.loopexit:
779; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
780; CHECK-NEXT:    br label [[EXIT]]
781; CHECK:       exit:
782; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
783; CHECK-NEXT:    ret i32 [[RESULT]]
784;
785entry:
786  %tmp5 = icmp sle i32 %n, 0
787  br i1 %tmp5, label %exit, label %loop.preheader
788
789loop.preheader:                                   ; preds = %entry
790  br label %loop
791
792loop:                                             ; preds = %guarded, %loop.preheader
793  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
794  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
795  %within.bounds = icmp ult i32 %i, %length
796  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
797  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
798  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
799
800deopt:                                            ; preds = %loop
801  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
802  ret i32 %deoptcall
803
804guarded:                                          ; preds = %loop
805  %i.i64 = zext i32 %i to i64
806  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
807  %array.i = load i32, i32* %array.i.ptr, align 4
808  %loop.acc.next = add i32 %loop.acc, %array.i
809  %i.next = add nsw i32 %i, 1
810  %continue = icmp ne i32 %i.next, %n
811  br i1 %continue, label %loop, label %exit
812
813exit:                                             ; preds = %guarded, %entry
814  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
815  ret i32 %result
816}
817
818define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) {
819; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(
820; CHECK-NEXT:  entry:
821; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
822; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
823; CHECK:       loop.preheader:
824; CHECK-NEXT:    br label [[LOOP:%.*]]
825; CHECK:       loop:
826; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
827; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
828; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
829; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
830; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
831; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
832; CHECK:       deopt:
833; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
834; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
835; CHECK:       guarded:
836; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
837; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
838; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
839; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
840; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 2
841; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
842; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
843; CHECK:       exit.loopexit:
844; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
845; CHECK-NEXT:    br label [[EXIT]]
846; CHECK:       exit:
847; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
848; CHECK-NEXT:    ret i32 [[RESULT]]
849;
850entry:
851  %tmp5 = icmp sle i32 %n, 0
852  br i1 %tmp5, label %exit, label %loop.preheader
853
854loop.preheader:                                   ; preds = %entry
855  br label %loop
856
857loop:                                             ; preds = %guarded, %loop.preheader
858  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
859  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
860  %within.bounds = icmp ult i32 %i, %length
861  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
862  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
863  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
864
865deopt:                                            ; preds = %loop
866  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
867  ret i32 %deoptcall
868
869guarded:                                          ; preds = %loop
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  %i.next = add nsw i32 %i, 2
875  %continue = icmp slt i32 %i.next, %n
876  br i1 %continue, label %loop, label %exit
877
878exit:                                             ; preds = %guarded, %entry
879  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
880  ret i32 %result
881}
882
883define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) {
884; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(
885; CHECK-NEXT:  entry:
886; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
887; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
888; CHECK:       loop.preheader:
889; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
890; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
891; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
892; CHECK-NEXT:    br label [[LOOP:%.*]]
893; CHECK:       loop:
894; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
895; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
896; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
897; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
898; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
899; CHECK-NEXT:    br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
900; CHECK:       deopt:
901; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
902; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
903; CHECK:       guarded:
904; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
905; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
906; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
907; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
908; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
909; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
910; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
911; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
912; CHECK:       exit.loopexit:
913; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
914; CHECK-NEXT:    br label [[EXIT]]
915; CHECK:       exit:
916; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
917; CHECK-NEXT:    ret i32 [[RESULT]]
918;
919entry:
920  %tmp5 = icmp sle i32 %n, 0
921  br i1 %tmp5, label %exit, label %loop.preheader
922
923loop.preheader:                                   ; preds = %entry
924  br label %loop
925
926loop:                                             ; preds = %guarded, %loop.preheader
927  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
928  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
929  %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
930  %within.bounds = icmp ult i32 %j, %length
931  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
932  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
933  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
934
935deopt:                                            ; preds = %loop
936  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
937  ret i32 %deoptcall
938
939guarded:                                          ; preds = %loop
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  %j.next = add nsw i32 %j, 1
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:                                             ; preds = %guarded, %entry
950  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
951  ret i32 %result
952}
953
954define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i, i32 %start.j, i32 %length, i32 %n) {
955; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(
956; CHECK-NEXT:  entry:
957; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
958; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
959; CHECK:       loop.preheader:
960; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]
961; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]
962; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]
963; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]
964; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
965; CHECK-NEXT:    br label [[LOOP:%.*]]
966; CHECK:       loop:
967; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
968; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]
969; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]
970; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
971; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
972; CHECK-NEXT:    br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
973; CHECK:       deopt:
974; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
975; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
976; CHECK:       guarded:
977; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
978; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
979; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
980; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
981; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
982; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
983; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
984; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
985; CHECK:       exit.loopexit:
986; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
987; CHECK-NEXT:    br label [[EXIT]]
988; CHECK:       exit:
989; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
990; CHECK-NEXT:    ret i32 [[RESULT]]
991;
992entry:
993  %tmp5 = icmp sle i32 %n, 0
994  br i1 %tmp5, label %exit, label %loop.preheader
995
996loop.preheader:                                   ; preds = %entry
997  br label %loop
998
999loop:                                             ; preds = %guarded, %loop.preheader
1000  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1001  %i = phi i32 [ %i.next, %guarded ], [ %start.i, %loop.preheader ]
1002  %j = phi i32 [ %j.next, %guarded ], [ %start.j, %loop.preheader ]
1003  %within.bounds = icmp ult i32 %j, %length
1004  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1005  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1006  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1007
1008deopt:                                            ; preds = %loop
1009  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1010  ret i32 %deoptcall
1011
1012guarded:                                          ; preds = %loop
1013  %i.i64 = zext i32 %i to i64
1014  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1015  %array.i = load i32, i32* %array.i.ptr, align 4
1016  %loop.acc.next = add i32 %loop.acc, %array.i
1017  %j.next = add i32 %j, 1
1018  %i.next = add i32 %i, 1
1019  %continue = icmp slt i32 %i.next, %n
1020  br i1 %continue, label %loop, label %exit
1021
1022exit:                                             ; preds = %guarded, %entry
1023  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1024  ret i32 %result
1025}
1026
1027define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) {
1028; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(
1029; CHECK-NEXT:  entry:
1030; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1031; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1032; CHECK:       loop.preheader:
1033; CHECK-NEXT:    br label [[LOOP:%.*]]
1034; CHECK:       loop:
1035; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1036; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1037; CHECK-NEXT:    [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1038; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]
1039; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1040; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1041; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1042; CHECK:       deopt:
1043; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1044; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1045; CHECK:       guarded:
1046; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1047; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1048; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1049; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1050; CHECK-NEXT:    [[J_NEXT]] = add i16 [[J]], 1
1051; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1052; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1053; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1054; CHECK:       exit.loopexit:
1055; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1056; CHECK-NEXT:    br label [[EXIT]]
1057; CHECK:       exit:
1058; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1059; CHECK-NEXT:    ret i32 [[RESULT]]
1060;
1061entry:
1062  %tmp5 = icmp sle i32 %n, 0
1063  br i1 %tmp5, label %exit, label %loop.preheader
1064
1065loop.preheader:                                   ; preds = %entry
1066  br label %loop
1067
1068loop:                                             ; preds = %guarded, %loop.preheader
1069  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1070  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1071  %j = phi i16 [ %j.next, %guarded ], [ 0, %loop.preheader ]
1072  %within.bounds = icmp ult i16 %j, %length
1073  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1074  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1075  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1076
1077deopt:                                            ; preds = %loop
1078  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1079  ret i32 %deoptcall
1080
1081guarded:                                          ; preds = %loop
1082  %i.i64 = zext i32 %i to i64
1083  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1084  %array.i = load i32, i32* %array.i.ptr, align 4
1085  %loop.acc.next = add i32 %loop.acc, %array.i
1086  %j.next = add i16 %j, 1
1087  %i.next = add i32 %i, 1
1088  %continue = icmp slt i32 %i.next, %n
1089  br i1 %continue, label %loop, label %exit
1090
1091exit:                                             ; preds = %guarded, %entry
1092  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1093  ret i32 %result
1094}
1095
1096define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) {
1097; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(
1098; CHECK-NEXT:  entry:
1099; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1100; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1101; CHECK:       loop.preheader:
1102; CHECK-NEXT:    br label [[LOOP:%.*]]
1103; CHECK:       loop:
1104; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1105; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1106; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1107; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
1108; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1109; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1110; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1111; CHECK:       deopt:
1112; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1113; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1114; CHECK:       guarded:
1115; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1116; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1117; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1118; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1119; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 2
1120; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1121; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1122; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1123; CHECK:       exit.loopexit:
1124; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1125; CHECK-NEXT:    br label [[EXIT]]
1126; CHECK:       exit:
1127; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1128; CHECK-NEXT:    ret i32 [[RESULT]]
1129;
1130entry:
1131  %tmp5 = icmp sle i32 %n, 0
1132  br i1 %tmp5, label %exit, label %loop.preheader
1133
1134loop.preheader:                                   ; preds = %entry
1135  br label %loop
1136
1137loop:                                             ; preds = %guarded, %loop.preheader
1138  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1139  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1140  %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
1141  %within.bounds = icmp ult i32 %j, %length
1142  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1143  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1144  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1145
1146deopt:                                            ; preds = %loop
1147  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1148  ret i32 %deoptcall
1149
1150guarded:                                          ; preds = %loop
1151  %i.i64 = zext i32 %i to i64
1152  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1153  %array.i = load i32, i32* %array.i.ptr, align 4
1154  %loop.acc.next = add i32 %loop.acc, %array.i
1155  %j.next = add nsw i32 %j, 2
1156  %i.next = add nsw i32 %i, 1
1157  %continue = icmp slt i32 %i.next, %n
1158  br i1 %continue, label %loop, label %exit
1159
1160exit:                                             ; preds = %guarded, %entry
1161  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1162  ret i32 %result
1163}
1164
1165define i32 @two_range_checks(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32 %n) {
1166; CHECK-LABEL: @two_range_checks(
1167; CHECK-NEXT:  entry:
1168; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1169; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1170; CHECK:       loop.preheader:
1171; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1172; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1173; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1174; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1175; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1176; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1177; CHECK-NEXT:    br label [[LOOP:%.*]]
1178; CHECK:       loop:
1179; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1180; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1181; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1182; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]]
1183; CHECK-NEXT:    [[TMP7:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
1184; CHECK-NEXT:    br i1 [[TMP7]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1185; CHECK:       deopt:
1186; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1187; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1188; CHECK:       guarded:
1189; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1190; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1191; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1192; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1193; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1194; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1195; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1196; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1197; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1198; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1199; CHECK:       exit.loopexit:
1200; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1201; CHECK-NEXT:    br label [[EXIT]]
1202; CHECK:       exit:
1203; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1204; CHECK-NEXT:    ret i32 [[RESULT]]
1205;
1206entry:
1207  %tmp5 = icmp eq i32 %n, 0
1208  br i1 %tmp5, label %exit, label %loop.preheader
1209
1210loop.preheader:                                   ; preds = %entry
1211  br label %loop
1212
1213loop:                                             ; preds = %guarded, %loop.preheader
1214  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1215  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1216  %within.bounds.1 = icmp ult i32 %i, %length.1
1217  %within.bounds.2 = icmp ult i32 %i, %length.2
1218  %within.bounds = and i1 %within.bounds.1, %within.bounds.2
1219  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1220  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1221  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1222
1223deopt:                                            ; preds = %loop
1224  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1225  ret i32 %deoptcall
1226
1227guarded:                                          ; preds = %loop
1228  %i.i64 = zext i32 %i to i64
1229  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1230  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1231  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1232  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1233  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1234  %loop.acc.next = add i32 %loop.acc.1, %array.2.i
1235  %i.next = add nuw i32 %i, 1
1236  %continue = icmp ult i32 %i.next, %n
1237  br i1 %continue, label %loop, label %exit
1238
1239exit:                                             ; preds = %guarded, %entry
1240  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1241  ret i32 %result
1242}
1243
1244define i32 @three_range_checks(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32* %array.3, i32 %length.3, i32 %n) {
1245; CHECK-LABEL: @three_range_checks(
1246; CHECK-NEXT:  entry:
1247; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1248; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1249; CHECK:       loop.preheader:
1250; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1251; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1252; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1253; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1254; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1255; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1256; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1257; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1258; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1259; CHECK-NEXT:    br label [[LOOP:%.*]]
1260; CHECK:       loop:
1261; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1262; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1263; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1264; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]]
1265; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
1266; CHECK-NEXT:    [[TMP11:%.*]] = and i1 [[TMP10]], [[WIDENABLE_COND]]
1267; CHECK-NEXT:    br i1 [[TMP11]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1268; CHECK:       deopt:
1269; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1270; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1271; CHECK:       guarded:
1272; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1273; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1274; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1275; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1276; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1277; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1278; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1279; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1280; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1281; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1282; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1283; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1284; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1285; CHECK:       exit.loopexit:
1286; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1287; CHECK-NEXT:    br label [[EXIT]]
1288; CHECK:       exit:
1289; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1290; CHECK-NEXT:    ret i32 [[RESULT]]
1291;
1292entry:
1293  %tmp5 = icmp eq i32 %n, 0
1294  br i1 %tmp5, label %exit, label %loop.preheader
1295
1296loop.preheader:                                   ; preds = %entry
1297  br label %loop
1298
1299loop:                                             ; preds = %guarded, %loop.preheader
1300  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1301  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1302  %within.bounds.1 = icmp ult i32 %i, %length.1
1303  %within.bounds.2 = icmp ult i32 %i, %length.2
1304  %within.bounds.3 = icmp ult i32 %i, %length.3
1305  %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
1306  %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
1307  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1308  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1309  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1310
1311deopt:                                            ; preds = %loop
1312  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1313  ret i32 %deoptcall
1314
1315guarded:                                          ; preds = %loop
1316  %i.i64 = zext i32 %i to i64
1317  %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1318  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1319  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1320  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1321  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1322  %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1323  %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1324  %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1325  %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1326  %i.next = add nuw i32 %i, 1
1327  %continue = icmp ult i32 %i.next, %n
1328  br i1 %continue, label %loop, label %exit
1329
1330exit:                                             ; preds = %guarded, %entry
1331  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1332  ret i32 %result
1333}
1334
1335define i32 @three_guards(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32* %array.3, i32 %length.3, i32 %n) {
1336; CHECK-LABEL: @three_guards(
1337; CHECK-NEXT:  entry:
1338; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1339; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1340; CHECK:       loop.preheader:
1341; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1342; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1343; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1344; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1345; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1346; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1347; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1348; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1349; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1350; CHECK-NEXT:    br label [[LOOP:%.*]]
1351; CHECK:       loop:
1352; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED6:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1353; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED6]] ], [ 0, [[LOOP_PREHEADER]] ]
1354; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1355; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
1356; CHECK-NEXT:    br i1 [[TMP9]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
1357; CHECK:       deopt:
1358; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1359; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1360; CHECK:       guarded:
1361; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1362; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1363; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1364; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1365; CHECK-NEXT:    [[WIDENABLE_COND4:%.*]] = call i1 @llvm.experimental.widenable.condition()
1366; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND4]]
1367; CHECK-NEXT:    br i1 [[TMP10]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof !0
1368; CHECK:       deopt2:
1369; CHECK-NEXT:    [[DEOPTCALL3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1370; CHECK-NEXT:    ret i32 [[DEOPTCALL3]]
1371; CHECK:       guarded1:
1372; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1373; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1374; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1375; CHECK-NEXT:    [[WIDENABLE_COND9:%.*]] = call i1 @llvm.experimental.widenable.condition()
1376; CHECK-NEXT:    [[TMP11:%.*]] = and i1 [[TMP8]], [[WIDENABLE_COND9]]
1377; CHECK-NEXT:    br i1 [[TMP11]], label [[GUARDED6]], label [[DEOPT7:%.*]], !prof !0
1378; CHECK:       deopt7:
1379; CHECK-NEXT:    [[DEOPTCALL8:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1380; CHECK-NEXT:    ret i32 [[DEOPTCALL8]]
1381; CHECK:       guarded6:
1382; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1383; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1384; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1385; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1386; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1387; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1388; CHECK:       exit.loopexit:
1389; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED6]] ]
1390; CHECK-NEXT:    br label [[EXIT]]
1391; CHECK:       exit:
1392; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1393; CHECK-NEXT:    ret i32 [[RESULT]]
1394;
1395entry:
1396  %tmp5 = icmp eq i32 %n, 0
1397  br i1 %tmp5, label %exit, label %loop.preheader
1398
1399loop.preheader:                                   ; preds = %entry
1400  br label %loop
1401
1402loop:                                             ; preds = %guarded6, %loop.preheader
1403  %loop.acc = phi i32 [ %loop.acc.next, %guarded6 ], [ 0, %loop.preheader ]
1404  %i = phi i32 [ %i.next, %guarded6 ], [ 0, %loop.preheader ]
1405  %within.bounds.1 = icmp ult i32 %i, %length.1
1406  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1407  %exiplicit_guard_cond = and i1 %within.bounds.1, %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.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1417  %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1418  %loop.acc.1 = add i32 %loop.acc, %array.1.i
1419  %within.bounds.2 = icmp ult i32 %i, %length.2
1420  %widenable_cond4 = call i1 @llvm.experimental.widenable.condition()
1421  %exiplicit_guard_cond5 = and i1 %within.bounds.2, %widenable_cond4
1422  br i1 %exiplicit_guard_cond5, label %guarded1, label %deopt2, !prof !0
1423
1424deopt2:                                           ; preds = %guarded
1425  %deoptcall3 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1426  ret i32 %deoptcall3
1427
1428guarded1:                                         ; preds = %guarded
1429  %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1430  %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1431  %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1432  %within.bounds.3 = icmp ult i32 %i, %length.3
1433  %widenable_cond9 = call i1 @llvm.experimental.widenable.condition()
1434  %exiplicit_guard_cond10 = and i1 %within.bounds.3, %widenable_cond9
1435  br i1 %exiplicit_guard_cond10, label %guarded6, label %deopt7, !prof !0
1436
1437deopt7:                                           ; preds = %guarded1
1438  %deoptcall8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1439  ret i32 %deoptcall8
1440
1441guarded6:                                         ; preds = %guarded1
1442  %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1443  %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1444  %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1445  %i.next = add nuw i32 %i, 1
1446  %continue = icmp ult i32 %i.next, %n
1447  br i1 %continue, label %loop, label %exit
1448
1449exit:                                             ; preds = %guarded6, %entry
1450  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded6 ]
1451  ret i32 %result
1452}
1453
1454define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) {
1455; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(
1456; CHECK-NEXT:  entry:
1457; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1458; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1459; CHECK:       loop.preheader:
1460; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
1461; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1462; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1463; CHECK-NEXT:    br label [[LOOP:%.*]]
1464; CHECK:       loop:
1465; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1466; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1467; CHECK-NEXT:    [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
1468; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1469; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
1470; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
1471; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1472; CHECK:       deopt:
1473; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1474; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1475; CHECK:       guarded:
1476; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1477; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1478; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1479; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1480; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1481; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1482; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1483; CHECK:       exit.loopexit:
1484; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1485; CHECK-NEXT:    br label [[EXIT]]
1486; CHECK:       exit:
1487; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1488; CHECK-NEXT:    ret i32 [[RESULT]]
1489;
1490entry:
1491  %tmp5 = icmp eq i32 %n, 0
1492  br i1 %tmp5, label %exit, label %loop.preheader
1493
1494loop.preheader:                                   ; preds = %entry
1495  br label %loop
1496
1497loop:                                             ; preds = %guarded, %loop.preheader
1498  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1499  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1500  %within.bounds = icmp ult i32 %i, %length
1501  %unrelated.cond = icmp ult i32 %x, %length
1502  %guard.cond = and i1 %within.bounds, %unrelated.cond
1503  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1504  %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1505  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1506
1507deopt:                                            ; preds = %loop
1508  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1509  ret i32 %deoptcall
1510
1511guarded:                                          ; preds = %loop
1512  %i.i64 = zext i32 %i to i64
1513  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1514  %array.i = load i32, i32* %array.i.ptr, align 4
1515  %loop.acc.next = add i32 %loop.acc, %array.i
1516  %i.next = add nuw i32 %i, 1
1517  %continue = icmp ult i32 %i.next, %n
1518  br i1 %continue, label %loop, label %exit
1519
1520exit:                                             ; preds = %guarded, %entry
1521  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1522  ret i32 %result
1523}
1524
1525define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
1526; CHECK-LABEL: @test_no_widened_conditions(
1527; CHECK-NEXT:  entry:
1528; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1529; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1530; CHECK:       loop.preheader:
1531; CHECK-NEXT:    br label [[LOOP:%.*]]
1532; CHECK:       loop:
1533; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1534; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1535; CHECK-NEXT:    [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]
1536; CHECK-NEXT:    [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]
1537; CHECK-NEXT:    [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]
1538; CHECK-NEXT:    [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]
1539; CHECK-NEXT:    [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]
1540; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1541; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
1542; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1543; CHECK:       deopt:
1544; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1545; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1546; CHECK:       guarded:
1547; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1548; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1549; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1550; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1551; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1552; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1553; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1554; CHECK:       exit.loopexit:
1555; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1556; CHECK-NEXT:    br label [[EXIT]]
1557; CHECK:       exit:
1558; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1559; CHECK-NEXT:    ret i32 [[RESULT]]
1560;
1561entry:
1562  %tmp5 = icmp eq i32 %n, 0
1563  br i1 %tmp5, label %exit, label %loop.preheader
1564
1565loop.preheader:                                   ; preds = %entry
1566  br label %loop
1567
1568loop:                                             ; preds = %guarded, %loop.preheader
1569  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1570  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1571  %unrelated.cond.1 = icmp eq i32 %x1, %i
1572  %unrelated.cond.2 = icmp eq i32 %x2, %i
1573  %unrelated.cond.3 = icmp eq i32 %x3, %i
1574  %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
1575  %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
1576  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1577  %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1578  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1579
1580deopt:                                            ; preds = %loop
1581  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1582  ret i32 %deoptcall
1583
1584guarded:                                          ; preds = %loop
1585  %i.i64 = zext i32 %i to i64
1586  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1587  %array.i = load i32, i32* %array.i.ptr, align 4
1588  %loop.acc.next = add i32 %loop.acc, %array.i
1589  %i.next = add nuw i32 %i, 1
1590  %continue = icmp ult i32 %i.next, %n
1591  br i1 %continue, label %loop, label %exit
1592
1593exit:                                             ; preds = %guarded, %entry
1594  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1595  ret i32 %result
1596}
1597
1598define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) {
1599; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(
1600; CHECK-NEXT:  entry:
1601; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1602; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1603; CHECK:       loop.preheader:
1604; CHECK-NEXT:    br label [[LOOP:%.*]]
1605; CHECK:       loop:
1606; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1607; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1608; CHECK-NEXT:    [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]
1609; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]
1610; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1611; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1612; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1613; CHECK:       deopt:
1614; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1615; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1616; CHECK:       guarded:
1617; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1618; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1619; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1620; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1621; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1622; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1623; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1624; CHECK:       exit.loopexit:
1625; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1626; CHECK-NEXT:    br label [[EXIT]]
1627; CHECK:       exit:
1628; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1629; CHECK-NEXT:    ret i32 [[RESULT]]
1630;
1631entry:
1632  %tmp5 = icmp sle i32 %n, 0
1633  br i1 %tmp5, label %exit, label %loop.preheader
1634
1635loop.preheader:                                   ; preds = %entry
1636  br label %loop
1637
1638loop:                                             ; preds = %guarded, %loop.preheader
1639  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1640  %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
1641  %bound = add i32 %i, %x
1642  %within.bounds = icmp ult i32 %i, %bound
1643  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1644  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1645  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1646
1647deopt:                                            ; preds = %loop
1648  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1649  ret i32 %deoptcall
1650
1651guarded:                                          ; preds = %loop
1652  %i.i64 = zext i32 %i to i64
1653  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1654  %array.i = load i32, i32* %array.i.ptr, align 4
1655  %loop.acc.next = add i32 %loop.acc, %array.i
1656  %i.next = add nsw i32 %i, 1
1657  %continue = icmp slt i32 %i.next, %n
1658  br i1 %continue, label %loop, label %exit
1659
1660exit:                                             ; preds = %guarded, %entry
1661  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1662  ret i32 %result
1663}
1664
1665define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) {
1666; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(
1667; CHECK-NEXT:  entry:
1668; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1669; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1670; CHECK:       loop.preheader:
1671; CHECK-NEXT:    br label [[LOOP:%.*]]
1672; CHECK:       loop:
1673; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1674; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1675; CHECK-NEXT:    [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]
1676; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1677; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
1678; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1679; CHECK:       deopt:
1680; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1681; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1682; CHECK:       guarded:
1683; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1684; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1685; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1686; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1687; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1688; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1689; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1690; CHECK:       exit.loopexit:
1691; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1692; CHECK-NEXT:    br label [[EXIT]]
1693; CHECK:       exit:
1694; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1695; CHECK-NEXT:    ret i32 [[RESULT]]
1696;
1697entry:
1698  %tmp5 = icmp sle i32 %n, 0
1699  br i1 %tmp5, label %exit, label %loop.preheader
1700
1701loop.preheader:                                   ; preds = %entry
1702  br label %loop
1703
1704loop:                                             ; preds = %guarded, %loop.preheader
1705  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1706  %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
1707  %guard.cond = icmp eq i32 %i, %x
1708  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1709  %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
1710  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1711
1712deopt:                                            ; preds = %loop
1713  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1714  ret i32 %deoptcall
1715
1716guarded:                                          ; preds = %loop
1717  %i.i64 = zext i32 %i to i64
1718  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1719  %array.i = load i32, i32* %array.i.ptr, align 4
1720  %loop.acc.next = add i32 %loop.acc, %array.i
1721  %i.next = add nsw i32 %i, 1
1722  %continue = icmp slt i32 %i.next, %n
1723  br i1 %continue, label %loop, label %exit
1724
1725exit:                                             ; preds = %guarded, %entry
1726  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1727  ret i32 %result
1728}
1729
1730define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
1731; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(
1732; CHECK-NEXT:  entry:
1733; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1734; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1735; CHECK:       loop.preheader:
1736; CHECK-NEXT:    [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32
1737; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1738; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]
1739; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1740; CHECK-NEXT:    br label [[LOOP:%.*]]
1741; CHECK:       loop:
1742; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1743; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1744; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1745; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
1746; CHECK-NEXT:    br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1747; CHECK:       deopt:
1748; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1749; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1750; CHECK:       guarded:
1751; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1752; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1753; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1754; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1755; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1756; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1757; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1758; CHECK:       exit.loopexit:
1759; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1760; CHECK-NEXT:    br label [[EXIT]]
1761; CHECK:       exit:
1762; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1763; CHECK-NEXT:    ret i32 [[RESULT]]
1764;
1765entry:
1766  %tmp5 = icmp eq i32 %n, 0
1767  br i1 %tmp5, label %exit, label %loop.preheader
1768
1769loop.preheader:                                   ; preds = %entry
1770  br label %loop
1771
1772loop:                                             ; preds = %guarded, %loop.preheader
1773  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1774  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1775  %length = zext i16 %length.i16 to i32
1776  %within.bounds = icmp ult i32 %i, %length
1777  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1778  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1779  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1780
1781deopt:                                            ; preds = %loop
1782  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1783  ret i32 %deoptcall
1784
1785guarded:                                          ; preds = %loop
1786  %i.i64 = zext i32 %i to i64
1787  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1788  %array.i = load i32, i32* %array.i.ptr, align 4
1789  %loop.acc.next = add i32 %loop.acc, %array.i
1790  %i.next = add nuw i32 %i, 1
1791  %continue = icmp ult i32 %i.next, %n
1792  br i1 %continue, label %loop, label %exit
1793
1794exit:                                             ; preds = %guarded, %entry
1795  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1796  ret i32 %result
1797}
1798
1799define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
1800; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(
1801; CHECK-NEXT:  entry:
1802; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1803; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1804; CHECK:       loop.preheader:
1805; CHECK-NEXT:    br label [[LOOP:%.*]]
1806; CHECK:       loop:
1807; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1808; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
1809; CHECK-NEXT:    [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]
1810; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_UDIV]]
1811; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
1812; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
1813; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1814; CHECK:       deopt:
1815; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1816; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1817; CHECK:       guarded:
1818; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1819; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1820; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1821; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1822; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1823; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1824; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1825; CHECK:       exit.loopexit:
1826; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
1827; CHECK-NEXT:    br label [[EXIT]]
1828; CHECK:       exit:
1829; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1830; CHECK-NEXT:    ret i32 [[RESULT]]
1831;
1832entry:
1833  %tmp5 = icmp eq i32 %n, 0
1834  br i1 %tmp5, label %exit, label %loop.preheader
1835
1836loop.preheader:                                   ; preds = %entry
1837  br label %loop
1838
1839loop:                                             ; preds = %guarded, %loop.preheader
1840  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
1841  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1842  %length.udiv = udiv i32 %length, %divider
1843  %within.bounds = icmp ult i32 %i, %length.udiv
1844  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1845  %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
1846  br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
1847
1848deopt:                                            ; preds = %loop
1849  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1850  ret i32 %deoptcall
1851
1852guarded:                                          ; preds = %loop
1853  %i.i64 = zext i32 %i to i64
1854  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1855  %array.i = load i32, i32* %array.i.ptr, align 4
1856  %loop.acc.next = add i32 %loop.acc, %array.i
1857  %i.next = add nuw i32 %i, 1
1858  %continue = icmp ult i32 %i.next, %n
1859  br i1 %continue, label %loop, label %exit
1860
1861exit:                                             ; preds = %guarded, %entry
1862  %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
1863  ret i32 %result
1864}
1865
1866; Make sure that if we're going to consider a branch widenable, that the
1867; call to widenable condition is actually present.
1868define i32 @negative_WC_required(i32* %array, i32 %length, i32 %n, i1 %unrelated) {
1869; CHECK-LABEL: @negative_WC_required(
1870; CHECK-NEXT:  entry:
1871; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1872; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1873; CHECK:       loop.preheader:
1874; CHECK-NEXT:    br label [[LOOP:%.*]]
1875; CHECK:       loop:
1876; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1877; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1878; CHECK-NEXT:    [[NOT_WIDENABLE:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED:%.*]]
1879; CHECK-NEXT:    br i1 [[NOT_WIDENABLE]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1880; CHECK:       deopt:
1881; CHECK-NEXT:    [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1882; CHECK-NEXT:    ret i32 [[DEOPTCALL]]
1883; CHECK:       guarded:
1884; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1885; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1886; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
1887; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1888; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1889; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1890; CHECK:       exit.loopexit:
1891; CHECK-NEXT:    br label [[EXIT]]
1892; CHECK:       exit:
1893; CHECK-NEXT:    ret i32 0
1894;
1895entry:
1896  %tmp5 = icmp eq i32 %n, 0
1897  br i1 %tmp5, label %exit, label %loop.preheader
1898
1899loop.preheader:                                   ; preds = %entry
1900  br label %loop
1901
1902loop:
1903  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1904  %within.bounds = icmp ult i32 %i, %length
1905  %not_widenable = and i1 %within.bounds, %unrelated
1906  br i1 %not_widenable, label %guarded, label %deopt, !prof !0
1907
1908deopt:
1909  %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1910  ret i32 %deoptcall
1911
1912guarded:                                          ; preds = %loop
1913  %i.i64 = zext i32 %i to i64
1914  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1915  store i32 0, i32* %array.i.ptr, align 4
1916  %i.next = add nuw i32 %i, 1
1917  %continue = icmp ult i32 %i.next, %n
1918  br i1 %continue, label %loop, label %exit
1919
1920exit:                                             ; preds = %guarded, %entry
1921  ret i32 0
1922}
1923
1924
1925declare i32 @llvm.experimental.deoptimize.i32(...)
1926
1927; Function Attrs: inaccessiblememonly nounwind
1928declare i1 @llvm.experimental.widenable.condition() #0
1929
1930attributes #0 = { inaccessiblememonly nounwind }
1931
1932!0 = !{!"branch_weights", i32 1048576, i32 1}
1933!1 = !{i32 1, i32 -2147483648}
1934