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