[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / Transforms / LoopPredication / basic.ll
blob18991b66f4116173809d96d66960c7bffcde0266
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-mssa(loop-predication)' -verify-memoryssa < %s 2>&1 | FileCheck %s
5 declare void @llvm.experimental.guard(i1, ...)
7 define 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:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
21 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
22 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
23 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
24 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
25 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
26 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
27 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
28 ; CHECK:       exit.loopexit:
29 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
30 ; CHECK-NEXT:    br label [[EXIT]]
31 ; CHECK:       exit:
32 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
33 ; CHECK-NEXT:    ret i32 [[RESULT]]
35 entry:
36   %tmp5 = icmp eq i32 %n, 0
37   br i1 %tmp5, label %exit, label %loop.preheader
39 loop.preheader:
40   br label %loop
42 loop:
43   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
44   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
45   %within.bounds = icmp ult i32 %i, %length
46   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
48   %i.i64 = zext i32 %i to i64
49   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
50   %array.i = load i32, i32* %array.i.ptr, align 4
51   %loop.acc.next = add i32 %loop.acc, %array.i
53   %i.next = add nuw i32 %i, 1
54   %continue = icmp ult i32 %i.next, %n
55   br i1 %continue, label %loop, label %exit
57 exit:
58   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
59   ret i32 %result
62 define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) {
63 ; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(
64 ; CHECK-NEXT:  entry:
65 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
66 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
67 ; CHECK:       loop.preheader:
68 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]
69 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
70 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
71 ; CHECK-NEXT:    br label [[LOOP:%.*]]
72 ; CHECK:       loop:
73 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
74 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
75 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
76 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
77 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
78 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
79 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
80 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
81 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]
82 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
83 ; CHECK:       exit.loopexit:
84 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
85 ; CHECK-NEXT:    br label [[EXIT]]
86 ; CHECK:       exit:
87 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
88 ; CHECK-NEXT:    ret i32 [[RESULT]]
90 entry:
91   %tmp5 = icmp eq i32 %n, 0
92   br i1 %tmp5, label %exit, label %loop.preheader
94 loop.preheader:
95   br label %loop
97 loop:
98   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
99   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
100   %within.bounds = icmp ult i32 %i, %length
101   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
103   %i.i64 = zext i32 %i to i64
104   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
105   %array.i = load i32, i32* %array.i.ptr, align 4
106   %loop.acc.next = add i32 %loop.acc, %array.i
108   %i.next = add nuw i32 %i, 1
109   %continue = icmp ule i32 %i.next, %n
110   br i1 %continue, label %loop, label %exit
112 exit:
113   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
114   ret i32 %result
117 define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
118 ; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(
119 ; CHECK-NEXT:  entry:
120 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
121 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
122 ; CHECK:       loop.preheader:
123 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
124 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
125 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
126 ; CHECK-NEXT:    br label [[LOOP:%.*]]
127 ; CHECK:       loop:
128 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
129 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
130 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
131 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
132 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
133 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
134 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
135 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
136 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
137 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
138 ; CHECK:       exit.loopexit:
139 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
140 ; CHECK-NEXT:    br label [[EXIT]]
141 ; CHECK:       exit:
142 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
143 ; CHECK-NEXT:    ret i32 [[RESULT]]
145 entry:
146   %tmp5 = icmp eq i32 %n, 0
147   br i1 %tmp5, label %exit, label %loop.preheader
149 loop.preheader:
150   br label %loop
152 loop:
153   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
154   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
155   %within.bounds = icmp ugt i32 %length, %i
156   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
158   %i.i64 = zext i32 %i to i64
159   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
160   %array.i = load i32, i32* %array.i.ptr, align 4
161   %loop.acc.next = add i32 %loop.acc, %array.i
163   %i.next = add nuw i32 %i, 1
164   %continue = icmp ult i32 %i.next, %n
165   br i1 %continue, label %loop, label %exit
167 exit:
168   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
169   ret i32 %result
172 define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
173 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check(
174 ; CHECK-NEXT:  entry:
175 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
176 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
177 ; CHECK:       loop.preheader:
178 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
179 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
180 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
181 ; CHECK-NEXT:    br label [[LOOP:%.*]]
182 ; CHECK:       loop:
183 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
184 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
185 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
186 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
187 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
188 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
189 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
190 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
191 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
192 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
193 ; CHECK:       exit.loopexit:
194 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
195 ; CHECK-NEXT:    br label [[EXIT]]
196 ; CHECK:       exit:
197 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
198 ; CHECK-NEXT:    ret i32 [[RESULT]]
200 entry:
201   %tmp5 = icmp sle i32 %n, 0
202   br i1 %tmp5, label %exit, label %loop.preheader
204 loop.preheader:
205   br label %loop
207 loop:
208   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
209   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
210   %within.bounds = icmp ult i32 %i, %length
211   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
213   %i.i64 = zext i32 %i to i64
214   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
215   %array.i = load i32, i32* %array.i.ptr, align 4
216   %loop.acc.next = add i32 %loop.acc, %array.i
218   %i.next = add nuw i32 %i, 1
219   %continue = icmp slt i32 %i.next, %n
220   br i1 %continue, label %loop, label %exit
222 exit:
223   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
224   ret i32 %result
227 define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
228 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(
229 ; CHECK-NEXT:  entry:
230 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
231 ; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]]
232 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
233 ; CHECK:       loop.preheader:
234 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
235 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 true, [[TMP0]]
236 ; CHECK-NEXT:    br label [[LOOP:%.*]]
237 ; CHECK:       loop:
238 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
239 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
240 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
241 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
242 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
243 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
244 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
245 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
246 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
247 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
248 ; CHECK:       exit.loopexit:
249 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
250 ; CHECK-NEXT:    br label [[EXIT]]
251 ; CHECK:       exit:
252 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
253 ; CHECK-NEXT:    ret i32 [[RESULT]]
255 entry:
256   %tmp5 = icmp sle i32 %n, 0
257   %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648}
258   br i1 %tmp5, label %exit, label %loop.preheader
260 loop.preheader:
261   br label %loop
263 loop:
264   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
265   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
266   %within.bounds = icmp ult i32 %i, %length
267   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
269   %i.i64 = zext i32 %i to i64
270   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
271   %array.i = load i32, i32* %array.i.ptr, align 4
272   %loop.acc.next = add i32 %loop.acc, %array.i
274   %i.next = add nuw i32 %i, 1
275   %continue = icmp slt i32 %i.next, %n
276   br i1 %continue, label %loop, label %exit
278 exit:
279   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
280   ret i32 %result
283 define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) {
284 ; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(
285 ; CHECK-NEXT:  entry:
286 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
287 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
288 ; CHECK:       loop.preheader:
289 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
290 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
291 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
292 ; CHECK-NEXT:    br label [[LOOP:%.*]]
293 ; CHECK:       loop:
294 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
295 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
296 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
297 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
298 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
299 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
300 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
301 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
302 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]
303 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
304 ; CHECK:       exit.loopexit:
305 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
306 ; CHECK-NEXT:    br label [[EXIT]]
307 ; CHECK:       exit:
308 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
309 ; CHECK-NEXT:    ret i32 [[RESULT]]
311 entry:
312   %tmp5 = icmp sle i32 %n, 0
313   br i1 %tmp5, label %exit, label %loop.preheader
315 loop.preheader:
316   br label %loop
318 loop:
319   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
320   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
321   %within.bounds = icmp ult i32 %i, %length
322   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
324   %i.i64 = zext i32 %i to i64
325   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
326   %array.i = load i32, i32* %array.i.ptr, align 4
327   %loop.acc.next = add i32 %loop.acc, %array.i
329   %i.next = add nuw i32 %i, 1
330   %continue = icmp sgt i32 %i.next, %n
331   br i1 %continue, label %exit, label %loop
333 exit:
334   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
335   ret i32 %result
338 define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) {
339 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(
340 ; CHECK-NEXT:  entry:
341 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
342 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
343 ; CHECK:       loop.preheader:
344 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
345 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
346 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
347 ; CHECK-NEXT:    br label [[LOOP:%.*]]
348 ; CHECK:       loop:
349 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
350 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
351 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
352 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
353 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
354 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
355 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
356 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
357 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
358 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
359 ; CHECK:       exit.loopexit:
360 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
361 ; CHECK-NEXT:    br label [[EXIT]]
362 ; CHECK:       exit:
363 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
364 ; CHECK-NEXT:    ret i32 [[RESULT]]
366 entry:
367   %tmp5 = icmp sle i32 %n, 0
368   br i1 %tmp5, label %exit, label %loop.preheader
370 loop.preheader:
371   br label %loop
373 loop:
374   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
375   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
376   %within.bounds = icmp ult i32 %i, %length
377   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
379   %i.i64 = zext i32 %i to i64
380   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
381   %array.i = load i32, i32* %array.i.ptr, align 4
382   %loop.acc.next = add i32 %loop.acc, %array.i
384   %i.next = add nuw i32 %i, 1
385   %continue = icmp sle i32 %i.next, %n
386   br i1 %continue, label %loop, label %exit
388 exit:
389   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
390   ret i32 %result
393 define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) {
394 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(
395 ; CHECK-NEXT:  entry:
396 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
397 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
398 ; CHECK:       loop.preheader:
399 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
400 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
401 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
402 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
403 ; CHECK-NEXT:    br label [[LOOP:%.*]]
404 ; CHECK:       loop:
405 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
406 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
407 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
408 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
409 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
410 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
411 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
412 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
413 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
414 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
415 ; CHECK:       exit.loopexit:
416 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
417 ; CHECK-NEXT:    br label [[EXIT]]
418 ; CHECK:       exit:
419 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
420 ; CHECK-NEXT:    ret i32 [[RESULT]]
422 entry:
423   %tmp5 = icmp sle i32 %n, 0
424   br i1 %tmp5, label %exit, label %loop.preheader
426 loop.preheader:
427   br label %loop
429 loop:
430   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
431   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
432   %within.bounds = icmp ult i32 %i, %length
433   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
435   %i.i64 = zext i32 %i to i64
436   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
437   %array.i = load i32, i32* %array.i.ptr, align 4
438   %loop.acc.next = add i32 %loop.acc, %array.i
440   %i.next = add i32 %i, 1
441   %continue = icmp slt i32 %i, %n
442   br i1 %continue, label %loop, label %exit
444 exit:
445   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
446   ret i32 %result
449 define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) {
450 ; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(
451 ; CHECK-NEXT:  entry:
452 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
453 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
454 ; CHECK:       loop.preheader:
455 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2
456 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
457 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
458 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
459 ; CHECK-NEXT:    br label [[LOOP:%.*]]
460 ; CHECK:       loop:
461 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
462 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
463 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
464 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
465 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
466 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
467 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
468 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
469 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
470 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
471 ; CHECK:       exit.loopexit:
472 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
473 ; CHECK-NEXT:    br label [[EXIT]]
474 ; CHECK:       exit:
475 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
476 ; CHECK-NEXT:    ret i32 [[RESULT]]
478 entry:
479   %tmp5 = icmp sle i32 %n, 0
480   br i1 %tmp5, label %exit, label %loop.preheader
482 loop.preheader:
483   br label %loop
485 loop:
486   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
487   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
489   %i.next = add i32 %i, 1
490   %within.bounds = icmp ult i32 %i.next, %length
491   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
493   %i.i64 = zext i32 %i to i64
494   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
495   %array.i = load i32, i32* %array.i.ptr, align 4
496   %loop.acc.next = add i32 %loop.acc, %array.i
498   %continue = icmp slt i32 %i, %n
499   br i1 %continue, label %loop, label %exit
501 exit:
502   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
503   ret i32 %result
506 define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
507 ; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(
508 ; CHECK-NEXT:  entry:
509 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
510 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
511 ; CHECK:       loop.preheader:
512 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
513 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]
514 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
515 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
516 ; CHECK-NEXT:    br label [[LOOP:%.*]]
517 ; CHECK:       loop:
518 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
519 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
520 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
521 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
522 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
523 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
524 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
525 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
526 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
527 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
528 ; CHECK:       exit.loopexit:
529 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
530 ; CHECK-NEXT:    br label [[EXIT]]
531 ; CHECK:       exit:
532 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
533 ; CHECK-NEXT:    ret i32 [[RESULT]]
535 entry:
536   %tmp5 = icmp sle i32 %n, 0
537   br i1 %tmp5, label %exit, label %loop.preheader
539 loop.preheader:
540   br label %loop
542 loop:
543   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
544   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
545   %i.offset = add i32 %i, 1
546   %within.bounds = icmp ult i32 %i.offset, %length
547   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
549   %i.i64 = zext i32 %i to i64
550   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
551   %array.i = load i32, i32* %array.i.ptr, align 4
552   %loop.acc.next = add i32 %loop.acc, %array.i
554   %i.next = add i32 %i, 1
555   %continue = icmp sle i32 %i.next, %n
556   br i1 %continue, label %loop, label %exit
558 exit:
559   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
560   ret i32 %result
563 define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
564 ; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(
565 ; CHECK-NEXT:  entry:
566 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
567 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
568 ; CHECK:       loop.preheader:
569 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
570 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]
571 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
572 ; CHECK-NEXT:    br label [[LOOP:%.*]]
573 ; CHECK:       loop:
574 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
575 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
576 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
577 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
578 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
579 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
580 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
581 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
582 ; CHECK-NEXT:    [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1
583 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]
584 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
585 ; CHECK:       exit.loopexit:
586 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
587 ; CHECK-NEXT:    br label [[EXIT]]
588 ; CHECK:       exit:
589 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
590 ; CHECK-NEXT:    ret i32 [[RESULT]]
592 entry:
593   %tmp5 = icmp sle i32 %n, 0
594   br i1 %tmp5, label %exit, label %loop.preheader
596 loop.preheader:
597   br label %loop
599 loop:
600   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
601   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
602   %i.offset = add i32 %i, 1
603   %within.bounds = icmp ult i32 %i.offset, %length
604   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
606   %i.i64 = zext i32 %i to i64
607   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
608   %array.i = load i32, i32* %array.i.ptr, align 4
609   %loop.acc.next = add i32 %loop.acc, %array.i
611   %i.next = add i32 %i, 1
612   %i.next.offset = add i32 %i.next, 1
613   %continue = icmp sle i32 %i.next.offset, %n
614   br i1 %continue, label %loop, label %exit
616 exit:
617   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
618   ret i32 %result
621 define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
622 ; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(
623 ; CHECK-NEXT:  entry:
624 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
625 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
626 ; CHECK:       loop.preheader:
627 ; CHECK-NEXT:    br label [[LOOP:%.*]]
628 ; CHECK:       loop:
629 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
630 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
631 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
632 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
633 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
634 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
635 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
636 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
637 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
638 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
639 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
640 ; CHECK:       exit.loopexit:
641 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
642 ; CHECK-NEXT:    br label [[EXIT]]
643 ; CHECK:       exit:
644 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
645 ; CHECK-NEXT:    ret i32 [[RESULT]]
647 entry:
648   %tmp5 = icmp sle i32 %n, 0
649   br i1 %tmp5, label %exit, label %loop.preheader
651 loop.preheader:
652   br label %loop
654 loop:
655   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
656   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
657   %within.bounds = icmp ult i32 %i, %length
658   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
660   %i.i64 = zext i32 %i to i64
661   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
662   %array.i = load i32, i32* %array.i.ptr, align 4
663   %loop.acc.next = add i32 %loop.acc, %array.i
665   %i.next = add nsw i32 %i, 1
666   %continue = icmp ne i32 %i.next, %n
667   br i1 %continue, label %loop, label %exit
669 exit:
670   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
671   ret i32 %result
674 define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) {
675 ; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(
676 ; CHECK-NEXT:  entry:
677 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
678 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
679 ; CHECK:       loop.preheader:
680 ; CHECK-NEXT:    br label [[LOOP:%.*]]
681 ; CHECK:       loop:
682 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
683 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
684 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
685 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
686 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
687 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
688 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
689 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
690 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 2
691 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
692 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
693 ; CHECK:       exit.loopexit:
694 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
695 ; CHECK-NEXT:    br label [[EXIT]]
696 ; CHECK:       exit:
697 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
698 ; CHECK-NEXT:    ret i32 [[RESULT]]
700 entry:
701   %tmp5 = icmp sle i32 %n, 0
702   br i1 %tmp5, label %exit, label %loop.preheader
704 loop.preheader:
705   br label %loop
707 loop:
708   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
709   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
710   %within.bounds = icmp ult i32 %i, %length
711   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
713   %i.i64 = zext i32 %i to i64
714   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
715   %array.i = load i32, i32* %array.i.ptr, align 4
716   %loop.acc.next = add i32 %loop.acc, %array.i
718   %i.next = add nsw i32 %i, 2
719   %continue = icmp slt i32 %i.next, %n
720   br i1 %continue, label %loop, label %exit
722 exit:
723   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
724   ret i32 %result
727 define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) {
728 ; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(
729 ; CHECK-NEXT:  entry:
730 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
731 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
732 ; CHECK:       loop.preheader:
733 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
734 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
735 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
736 ; CHECK-NEXT:    br label [[LOOP:%.*]]
737 ; CHECK:       loop:
738 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
739 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
740 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
741 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
742 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
743 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
744 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
745 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
746 ; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
747 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
748 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
749 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
750 ; CHECK:       exit.loopexit:
751 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
752 ; CHECK-NEXT:    br label [[EXIT]]
753 ; CHECK:       exit:
754 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
755 ; CHECK-NEXT:    ret i32 [[RESULT]]
757 entry:
758   %tmp5 = icmp sle i32 %n, 0
759   br i1 %tmp5, label %exit, label %loop.preheader
761 loop.preheader:
762   br label %loop
764 loop:
765   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
766   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
767   %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
769   %within.bounds = icmp ult i32 %j, %length
770   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
772   %i.i64 = zext i32 %i to i64
773   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
774   %array.i = load i32, i32* %array.i.ptr, align 4
775   %loop.acc.next = add i32 %loop.acc, %array.i
777   %j.next = add nsw i32 %j, 1
778   %i.next = add nsw i32 %i, 1
779   %continue = icmp slt i32 %i.next, %n
780   br i1 %continue, label %loop, label %exit
782 exit:
783   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
784   ret i32 %result
787 define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i,
788 ; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(
789 ; CHECK-NEXT:  entry:
790 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
791 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
792 ; CHECK:       loop.preheader:
793 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]
794 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]
795 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]
796 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]
797 ; CHECK-NEXT:    [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
798 ; CHECK-NEXT:    br label [[LOOP:%.*]]
799 ; CHECK:       loop:
800 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
801 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]
802 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]
803 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP4]], i32 9) [ "deopt"() ]
804 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
805 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
806 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
807 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
808 ; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
809 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
810 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
811 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
812 ; CHECK:       exit.loopexit:
813 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
814 ; CHECK-NEXT:    br label [[EXIT]]
815 ; CHECK:       exit:
816 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
817 ; CHECK-NEXT:    ret i32 [[RESULT]]
819   i32 %start.j, i32 %length,
820   i32 %n) {
821 entry:
822   %tmp5 = icmp sle i32 %n, 0
823   br i1 %tmp5, label %exit, label %loop.preheader
825 loop.preheader:
826   br label %loop
828 loop:
829   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
830   %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ]
831   %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ]
833   %within.bounds = icmp ult i32 %j, %length
834   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
836   %i.i64 = zext i32 %i to i64
837   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
838   %array.i = load i32, i32* %array.i.ptr, align 4
839   %loop.acc.next = add i32 %loop.acc, %array.i
841   %j.next = add i32 %j, 1
842   %i.next = add i32 %i, 1
843   %continue = icmp slt i32 %i.next, %n
844   br i1 %continue, label %loop, label %exit
846 exit:
847   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
848   ret i32 %result
851 define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) {
852 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(
853 ; CHECK-NEXT:  entry:
854 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
855 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
856 ; CHECK:       loop.preheader:
857 ; CHECK-NEXT:    br label [[LOOP:%.*]]
858 ; CHECK:       loop:
859 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
860 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
861 ; CHECK-NEXT:    [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
862 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]
863 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
864 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
865 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
866 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
867 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
868 ; CHECK-NEXT:    [[J_NEXT]] = add i16 [[J]], 1
869 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
870 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
871 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
872 ; CHECK:       exit.loopexit:
873 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
874 ; CHECK-NEXT:    br label [[EXIT]]
875 ; CHECK:       exit:
876 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
877 ; CHECK-NEXT:    ret i32 [[RESULT]]
879 entry:
880   %tmp5 = icmp sle i32 %n, 0
881   br i1 %tmp5, label %exit, label %loop.preheader
883 loop.preheader:
884   br label %loop
886 loop:
887   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
888   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
889   %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ]
891   %within.bounds = icmp ult i16 %j, %length
892   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
894   %i.i64 = zext i32 %i to i64
895   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
896   %array.i = load i32, i32* %array.i.ptr, align 4
897   %loop.acc.next = add i32 %loop.acc, %array.i
899   %j.next = add i16 %j, 1
900   %i.next = add i32 %i, 1
901   %continue = icmp slt i32 %i.next, %n
902   br i1 %continue, label %loop, label %exit
904 exit:
905   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
906   ret i32 %result
909 define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) {
910 ; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(
911 ; CHECK-NEXT:  entry:
912 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
913 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
914 ; CHECK:       loop.preheader:
915 ; CHECK-NEXT:    br label [[LOOP:%.*]]
916 ; CHECK:       loop:
917 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
918 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
919 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
920 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
921 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
922 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
923 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
924 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
925 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
926 ; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 2
927 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
928 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
929 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
930 ; CHECK:       exit.loopexit:
931 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
932 ; CHECK-NEXT:    br label [[EXIT]]
933 ; CHECK:       exit:
934 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
935 ; CHECK-NEXT:    ret i32 [[RESULT]]
937 entry:
938   %tmp5 = icmp sle i32 %n, 0
939   br i1 %tmp5, label %exit, label %loop.preheader
941 loop.preheader:
942   br label %loop
944 loop:
945   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
946   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
947   %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ]
949   %within.bounds = icmp ult i32 %j, %length
950   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
952   %i.i64 = zext i32 %i to i64
953   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
954   %array.i = load i32, i32* %array.i.ptr, align 4
955   %loop.acc.next = add i32 %loop.acc, %array.i
957   %j.next = add nsw i32 %j, 2
958   %i.next = add nsw i32 %i, 1
959   %continue = icmp slt i32 %i.next, %n
960   br i1 %continue, label %loop, label %exit
962 exit:
963   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
964   ret i32 %result
967 define i32 @two_range_checks(i32* %array.1, i32 %length.1,
968 ; CHECK-LABEL: @two_range_checks(
969 ; CHECK-NEXT:  entry:
970 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
971 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
972 ; CHECK:       loop.preheader:
973 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
974 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]
975 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
976 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
977 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]]
978 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
979 ; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]]
980 ; CHECK-NEXT:    br label [[LOOP:%.*]]
981 ; CHECK:       loop:
982 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
983 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
984 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP6]], i32 9) [ "deopt"() ]
985 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
986 ; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
987 ; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
988 ; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
989 ; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
990 ; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
991 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
992 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
993 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
994 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
995 ; CHECK:       exit.loopexit:
996 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
997 ; CHECK-NEXT:    br label [[EXIT]]
998 ; CHECK:       exit:
999 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1000 ; CHECK-NEXT:    ret i32 [[RESULT]]
1002   i32* %array.2, i32 %length.2, i32 %n) {
1003 entry:
1004   %tmp5 = icmp eq i32 %n, 0
1005   br i1 %tmp5, label %exit, label %loop.preheader
1007 loop.preheader:
1008   br label %loop
1010 loop:
1011   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1012   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1013   %within.bounds.1 = icmp ult i32 %i, %length.1
1014   %within.bounds.2 = icmp ult i32 %i, %length.2
1015   %within.bounds = and i1 %within.bounds.1, %within.bounds.2
1016   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1018   %i.i64 = zext i32 %i to i64
1019   %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1020   %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1021   %loop.acc.1 = add i32 %loop.acc, %array.1.i
1023   %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1024   %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1025   %loop.acc.next = add i32 %loop.acc.1, %array.2.i
1027   %i.next = add nuw i32 %i, 1
1028   %continue = icmp ult i32 %i.next, %n
1029   br i1 %continue, label %loop, label %exit
1031 exit:
1032   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1033   ret i32 %result
1036 define i32 @three_range_checks(i32* %array.1, i32 %length.1,
1037 ; CHECK-LABEL: @three_range_checks(
1038 ; CHECK-NEXT:  entry:
1039 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1040 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1041 ; CHECK:       loop.preheader:
1042 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1043 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1044 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1045 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1046 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1047 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1048 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1049 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1050 ; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1051 ; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]]
1052 ; CHECK-NEXT:    [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
1053 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1054 ; CHECK:       loop:
1055 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1056 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1057 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP10]], i32 9) [ "deopt"() ]
1058 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1059 ; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1060 ; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1061 ; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1062 ; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1063 ; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1064 ; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1065 ; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1066 ; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1067 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1068 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1069 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1070 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1071 ; CHECK:       exit.loopexit:
1072 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1073 ; CHECK-NEXT:    br label [[EXIT]]
1074 ; CHECK:       exit:
1075 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1076 ; CHECK-NEXT:    ret i32 [[RESULT]]
1078   i32* %array.2, i32 %length.2,
1079   i32* %array.3, i32 %length.3, i32 %n) {
1080 entry:
1081   %tmp5 = icmp eq i32 %n, 0
1082   br i1 %tmp5, label %exit, label %loop.preheader
1084 loop.preheader:
1085   br label %loop
1087 loop:
1088   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1089   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1090   %within.bounds.1 = icmp ult i32 %i, %length.1
1091   %within.bounds.2 = icmp ult i32 %i, %length.2
1092   %within.bounds.3 = icmp ult i32 %i, %length.3
1093   %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
1094   %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
1095   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1097   %i.i64 = zext i32 %i to i64
1098   %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1099   %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1100   %loop.acc.1 = add i32 %loop.acc, %array.1.i
1102   %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1103   %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1104   %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1106   %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1107   %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1108   %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1110   %i.next = add nuw i32 %i, 1
1111   %continue = icmp ult i32 %i.next, %n
1112   br i1 %continue, label %loop, label %exit
1114 exit:
1115   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1116   ret i32 %result
1119 define i32 @three_guards(i32* %array.1, i32 %length.1,
1120 ; CHECK-LABEL: @three_guards(
1121 ; CHECK-NEXT:  entry:
1122 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1123 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1124 ; CHECK:       loop.preheader:
1125 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
1126 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]
1127 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1128 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
1129 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
1130 ; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
1131 ; CHECK-NEXT:    [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
1132 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]]
1133 ; CHECK-NEXT:    [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
1134 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1135 ; CHECK:       loop:
1136 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1137 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1138 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
1139 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1140 ; CHECK-NEXT:    [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
1141 ; CHECK-NEXT:    [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
1142 ; CHECK-NEXT:    [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
1143 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP5]], i32 9) [ "deopt"() ]
1144 ; CHECK-NEXT:    [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
1145 ; CHECK-NEXT:    [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
1146 ; CHECK-NEXT:    [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
1147 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP8]], i32 9) [ "deopt"() ]
1148 ; CHECK-NEXT:    [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
1149 ; CHECK-NEXT:    [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
1150 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
1151 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1152 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1153 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1154 ; CHECK:       exit.loopexit:
1155 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1156 ; CHECK-NEXT:    br label [[EXIT]]
1157 ; CHECK:       exit:
1158 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1159 ; CHECK-NEXT:    ret i32 [[RESULT]]
1161   i32* %array.2, i32 %length.2,
1162   i32* %array.3, i32 %length.3, i32 %n) {
1163 entry:
1164   %tmp5 = icmp eq i32 %n, 0
1165   br i1 %tmp5, label %exit, label %loop.preheader
1167 loop.preheader:
1168   br label %loop
1170 loop:
1172   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1173   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1175   %within.bounds.1 = icmp ult i32 %i, %length.1
1176   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ]
1178   %i.i64 = zext i32 %i to i64
1179   %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
1180   %array.1.i = load i32, i32* %array.1.i.ptr, align 4
1181   %loop.acc.1 = add i32 %loop.acc, %array.1.i
1183   %within.bounds.2 = icmp ult i32 %i, %length.2
1184   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ]
1186   %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
1187   %array.2.i = load i32, i32* %array.2.i.ptr, align 4
1188   %loop.acc.2 = add i32 %loop.acc.1, %array.2.i
1190   %within.bounds.3 = icmp ult i32 %i, %length.3
1191   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ]
1193   %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
1194   %array.3.i = load i32, i32* %array.3.i.ptr, align 4
1195   %loop.acc.next = add i32 %loop.acc.2, %array.3.i
1197   %i.next = add nuw i32 %i, 1
1198   %continue = icmp ult i32 %i.next, %n
1199   br i1 %continue, label %loop, label %exit
1201 exit:
1202   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1203   ret i32 %result
1206 define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) {
1207 ; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(
1208 ; CHECK-NEXT:  entry:
1209 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1210 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1211 ; CHECK:       loop.preheader:
1212 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
1213 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1214 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1215 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1216 ; CHECK:       loop:
1217 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1218 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1219 ; CHECK-NEXT:    [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
1220 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
1221 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1222 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1223 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1224 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1225 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1226 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1227 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1228 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1229 ; CHECK:       exit.loopexit:
1230 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1231 ; CHECK-NEXT:    br label [[EXIT]]
1232 ; CHECK:       exit:
1233 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1234 ; CHECK-NEXT:    ret i32 [[RESULT]]
1236 entry:
1237   %tmp5 = icmp eq i32 %n, 0
1238   br i1 %tmp5, label %exit, label %loop.preheader
1240 loop.preheader:
1241   br label %loop
1243 loop:
1244   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1245   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1246   %within.bounds = icmp ult i32 %i, %length
1247   %unrelated.cond = icmp ult i32 %x, %length
1248   %guard.cond = and i1 %within.bounds, %unrelated.cond
1249   call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1251   %i.i64 = zext i32 %i to i64
1252   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1253   %array.i = load i32, i32* %array.i.ptr, align 4
1254   %loop.acc.next = add i32 %loop.acc, %array.i
1256   %i.next = add nuw i32 %i, 1
1257   %continue = icmp ult i32 %i.next, %n
1258   br i1 %continue, label %loop, label %exit
1260 exit:
1261   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1262   ret i32 %result
1265 ; Don't change the guard condition if there were no widened subconditions
1266 define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
1267 ; CHECK-LABEL: @test_no_widened_conditions(
1268 ; CHECK-NEXT:  entry:
1269 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1270 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1271 ; CHECK:       loop.preheader:
1272 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1273 ; CHECK:       loop:
1274 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1275 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1276 ; CHECK-NEXT:    [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]
1277 ; CHECK-NEXT:    [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]
1278 ; CHECK-NEXT:    [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]
1279 ; CHECK-NEXT:    [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]
1280 ; CHECK-NEXT:    [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]
1281 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]
1282 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1283 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1284 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1285 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1286 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1287 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1288 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1289 ; CHECK:       exit.loopexit:
1290 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1291 ; CHECK-NEXT:    br label [[EXIT]]
1292 ; CHECK:       exit:
1293 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1294 ; CHECK-NEXT:    ret i32 [[RESULT]]
1296 entry:
1297   %tmp5 = icmp eq i32 %n, 0
1298   br i1 %tmp5, label %exit, label %loop.preheader
1300 loop.preheader:
1301   br label %loop
1303 loop:
1304   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1305   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1306   %unrelated.cond.1 = icmp eq i32 %x1, %i
1307   %unrelated.cond.2 = icmp eq i32 %x2, %i
1308   %unrelated.cond.3 = icmp eq i32 %x3, %i
1309   %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
1310   %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
1312   call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1314   %i.i64 = zext i32 %i to i64
1315   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1316   %array.i = load i32, i32* %array.i.ptr, align 4
1317   %loop.acc.next = add i32 %loop.acc, %array.i
1319   %i.next = add nuw i32 %i, 1
1320   %continue = icmp ult i32 %i.next, %n
1321   br i1 %continue, label %loop, label %exit
1323 exit:
1324   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1325   ret i32 %result
1328 define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) {
1329 ; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(
1330 ; CHECK-NEXT:  entry:
1331 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1332 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1333 ; CHECK:       loop.preheader:
1334 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1335 ; CHECK:       loop:
1336 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1337 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1338 ; CHECK-NEXT:    [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]
1339 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]
1340 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1341 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1342 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1343 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1344 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1345 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1346 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1347 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1348 ; CHECK:       exit.loopexit:
1349 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1350 ; CHECK-NEXT:    br label [[EXIT]]
1351 ; CHECK:       exit:
1352 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1353 ; CHECK-NEXT:    ret i32 [[RESULT]]
1355 entry:
1356   %tmp5 = icmp sle i32 %n, 0
1357   br i1 %tmp5, label %exit, label %loop.preheader
1359 loop.preheader:
1360   br label %loop
1362 loop:
1363   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1364   %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
1365   %bound = add i32 %i, %x
1366   %within.bounds = icmp ult i32 %i, %bound
1367   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1369   %i.i64 = zext i32 %i to i64
1370   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1371   %array.i = load i32, i32* %array.i.ptr, align 4
1372   %loop.acc.next = add i32 %loop.acc, %array.i
1374   %i.next = add nsw i32 %i, 1
1375   %continue = icmp slt i32 %i.next, %n
1376   br i1 %continue, label %loop, label %exit
1378 exit:
1379   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1380   ret i32 %result
1383 define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) {
1384 ; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(
1385 ; CHECK-NEXT:  entry:
1386 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1387 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1388 ; CHECK:       loop.preheader:
1389 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1390 ; CHECK:       loop:
1391 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1392 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
1393 ; CHECK-NEXT:    [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]
1394 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[GUARD_COND]], i32 9) [ "deopt"() ]
1395 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1396 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1397 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1398 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1399 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
1400 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1401 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1402 ; CHECK:       exit.loopexit:
1403 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1404 ; CHECK-NEXT:    br label [[EXIT]]
1405 ; CHECK:       exit:
1406 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1407 ; CHECK-NEXT:    ret i32 [[RESULT]]
1409 entry:
1410   %tmp5 = icmp sle i32 %n, 0
1411   br i1 %tmp5, label %exit, label %loop.preheader
1413 loop.preheader:
1414   br label %loop
1416 loop:
1417   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1418   %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ]
1419   %guard.cond = icmp eq i32 %i, %x
1420   call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ]
1422   %i.i64 = zext i32 %i to i64
1423   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1424   %array.i = load i32, i32* %array.i.ptr, align 4
1425   %loop.acc.next = add i32 %loop.acc, %array.i
1427   %i.next = add nsw i32 %i, 1
1428   %continue = icmp slt i32 %i.next, %n
1429   br i1 %continue, label %loop, label %exit
1431 exit:
1432   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1433   ret i32 %result
1436 define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
1437 ; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(
1438 ; CHECK-NEXT:  entry:
1439 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1440 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1441 ; CHECK:       loop.preheader:
1442 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32
1443 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1444 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]
1445 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1446 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1447 ; CHECK:       loop:
1448 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1449 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1450 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1451 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1452 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1453 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1454 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1455 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1456 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1457 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1458 ; CHECK:       exit.loopexit:
1459 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1460 ; CHECK-NEXT:    br label [[EXIT]]
1461 ; CHECK:       exit:
1462 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1463 ; CHECK-NEXT:    ret i32 [[RESULT]]
1465 entry:
1466   %tmp5 = icmp eq i32 %n, 0
1467   br i1 %tmp5, label %exit, label %loop.preheader
1469 loop.preheader:
1470   br label %loop
1472 loop:
1473   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1474   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1475   %length = zext i16 %length.i16 to i32
1476   %within.bounds = icmp ult i32 %i, %length
1477   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1479   %i.i64 = zext i32 %i to i64
1480   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1481   %array.i = load i32, i32* %array.i.ptr, align 4
1482   %loop.acc.next = add i32 %loop.acc, %array.i
1484   %i.next = add nuw i32 %i, 1
1485   %continue = icmp ult i32 %i.next, %n
1486   br i1 %continue, label %loop, label %exit
1488 exit:
1489   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1490   ret i32 %result
1493 define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
1494 ; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(
1495 ; CHECK-NEXT:  entry:
1496 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1497 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1498 ; CHECK:       loop.preheader:
1499 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1500 ; CHECK:       loop:
1501 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1502 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1503 ; CHECK-NEXT:    [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]
1504 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_UDIV]]
1505 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]]
1506 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1507 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
1508 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1509 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1510 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1511 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1512 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1513 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1514 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1515 ; CHECK:       exit.loopexit:
1516 ; CHECK-NEXT:    [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1517 ; CHECK-NEXT:    br label [[EXIT]]
1518 ; CHECK:       exit:
1519 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
1520 ; CHECK-NEXT:    ret i32 [[RESULT]]
1522 entry:
1523   %tmp5 = icmp eq i32 %n, 0
1524   br i1 %tmp5, label %exit, label %loop.preheader
1526 loop.preheader:
1527   br label %loop
1529 loop:
1530   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1531   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1532   %length.udiv = udiv i32 %length, %divider
1533   %within.bounds = icmp ult i32 %i, %length.udiv
1534   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1536   %i.i64 = zext i32 %i to i64
1537   %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1538   %array.i = load i32, i32* %array.i.ptr, align 4
1539   %loop.acc.next = add i32 %loop.acc, %array.i
1541   %i.next = add nuw i32 %i, 1
1542   %continue = icmp ult i32 %i.next, %n
1543   br i1 %continue, label %loop, label %exit
1545 exit:
1546   %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
1547   ret i32 %result
1551 ; This is a case where the length information tells us that the guard
1552 ; must trigger on some iteration.
1553 define i32 @provably_taken(i32* %array, i32* %length.ptr) {
1554 ; CHECK-LABEL: @provably_taken(
1555 ; CHECK-NEXT:  loop.preheader:
1556 ; CHECK-NEXT:    [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG1:![0-9]+]]
1557 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[LENGTH]]
1558 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], false
1559 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1560 ; CHECK:       loop:
1561 ; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1562 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1563 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
1564 ; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1565 ; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1566 ; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1567 ; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1568 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1569 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], 200
1570 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1571 ; CHECK:       exit:
1572 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1573 ; CHECK-NEXT:    ret i32 [[RESULT]]
1575 loop.preheader:
1576   %length = load i32, i32* %length.ptr, !range !{i32 0, i32 50}
1577   br label %loop
1579 loop:
1580   %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1581   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1582   %within.bounds = icmp ult i32 %i, %length
1583   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
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
1590   %i.next = add nuw i32 %i, 1
1591   %continue = icmp slt i32 %i.next, 200
1592   br i1 %continue, label %loop, label %exit
1594 exit:
1595   %result = phi i32 [ %loop.acc.next, %loop ]
1596   ret i32 %result
1599 ; NE Check (as produced by LFTR) where we can prove Start < End via simple
1600 ; instruction analysis
1601 define i32 @ne_latch_zext(i32* %array, i32 %length, i16 %n16) {
1602 ; CHECK-LABEL: @ne_latch_zext(
1603 ; CHECK-NEXT:  loop.preheader:
1604 ; CHECK-NEXT:    [[N:%.*]] = zext i16 [[N16:%.*]] to i32
1605 ; CHECK-NEXT:    [[NPLUS1:%.*]] = add i32 [[N]], 1
1606 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ule i32 [[NPLUS1]], [[LENGTH:%.*]]
1607 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
1608 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
1609 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1610 ; CHECK:       loop:
1611 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1612 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 9) [ "deopt"() ]
1613 ; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1
1614 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]]
1615 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1616 ; CHECK:       exit:
1617 ; CHECK-NEXT:    ret i32 0
1619 loop.preheader:
1620   %n = zext i16 %n16 to i32
1621   %nplus1 = add nsw nuw i32 %n, 1
1622   br label %loop
1624 loop:
1625   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1626   %within.bounds = icmp ult i32 %i, %length
1627   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1629   %i.next = add nsw nuw i32 %i, 1
1630   %continue = icmp ne i32 %i.next, %nplus1
1631   br i1 %continue, label %loop, label %exit
1633 exit:
1634   ret i32 0
1637 ; Same as previous, but with a pre-increment test since this is easier to match
1638 define i32 @ne_latch_zext_preinc(i32* %array, i32 %length, i16 %n16) {
1639 ; CHECK-LABEL: @ne_latch_zext_preinc(
1640 ; CHECK-NEXT:  loop.preheader:
1641 ; CHECK-NEXT:    [[N:%.*]] = zext i16 [[N16:%.*]] to i32
1642 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
1643 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1644 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
1645 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1646 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1647 ; CHECK:       loop:
1648 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1649 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1650 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1651 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]
1652 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1653 ; CHECK:       exit:
1654 ; CHECK-NEXT:    ret i32 0
1656 loop.preheader:
1657   %n = zext i16 %n16 to i32
1658   br label %loop
1660 loop:
1661   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1662   %within.bounds = icmp ult i32 %i, %length
1663   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1665   %i.next = add nuw i32 %i, 1
1666   %continue = icmp ne i32 %i, %n
1667   br i1 %continue, label %loop, label %exit
1669 exit:
1670   ret i32 0
1673 ; NE Check (as produced by LFTR) where we can prove Start < End via the
1674 ; condition guarding the loop entry.
1675 define i32 @ne_latch_dom_check(i32* %array, i32 %length, i32 %n) {
1676 ; CHECK-LABEL: @ne_latch_dom_check(
1677 ; CHECK-NEXT:  entry:
1678 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1679 ; CHECK-NEXT:    [[NPLUS1:%.*]] = add nuw i32 [[N]], 1
1680 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1681 ; CHECK:       loop.preheader:
1682 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1683 ; CHECK:       loop:
1684 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1685 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1686 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1687 ; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1
1688 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[NPLUS1]]
1689 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1690 ; CHECK:       exit.loopexit:
1691 ; CHECK-NEXT:    br label [[EXIT]]
1692 ; CHECK:       exit:
1693 ; CHECK-NEXT:    ret i32 0
1695 entry:
1696   %tmp5 = icmp sle i32 %n, 0
1697   %nplus1 = add nuw i32 %n, 1
1698   br i1 %tmp5, label %exit, label %loop.preheader
1700 loop.preheader:
1701   br label %loop
1703 loop:
1704   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1705   %within.bounds = icmp ult i32 %i, %length
1706   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1708   %i.next = add nsw nuw i32 %i, 1
1709   %continue = icmp ne i32 %i.next, %nplus1
1710   br i1 %continue, label %loop, label %exit
1712 exit:
1713   ret i32 0
1716 ; Same as previous, but easier to match
1717 define i32 @ne_latch_dom_check_preinc(i32* %array, i32 %length, i32 %n) {
1718 ; CHECK-LABEL: @ne_latch_dom_check_preinc(
1719 ; CHECK-NEXT:  entry:
1720 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1721 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1722 ; CHECK:       loop.preheader:
1723 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
1724 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1725 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
1726 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1727 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1728 ; CHECK:       loop:
1729 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1730 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1731 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1732 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]
1733 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1734 ; CHECK:       exit.loopexit:
1735 ; CHECK-NEXT:    br label [[EXIT]]
1736 ; CHECK:       exit:
1737 ; CHECK-NEXT:    ret i32 0
1739 entry:
1740   %tmp5 = icmp sle i32 %n, 0
1741   br i1 %tmp5, label %exit, label %loop.preheader
1743 loop.preheader:
1744   br label %loop
1746 loop:
1747   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1748   %within.bounds = icmp ult i32 %i, %length
1749   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1751   %i.next = add nuw i32 %i, 1
1752   %continue = icmp ne i32 %i, %n
1753   br i1 %continue, label %loop, label %exit
1755 exit:
1756   ret i32 0
1759 ; Same as previous, except swapped br/cmp
1760 define i32 @eq_latch_dom_check_preinc(i32* %array, i32 %length, i32 %n) {
1761 ; CHECK-LABEL: @eq_latch_dom_check_preinc(
1762 ; CHECK-NEXT:  entry:
1763 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
1764 ; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1765 ; CHECK:       loop.preheader:
1766 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
1767 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
1768 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
1769 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
1770 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1771 ; CHECK:       loop:
1772 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1773 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 9) [ "deopt"() ]
1774 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1775 ; CHECK-NEXT:    [[DONE:%.*]] = icmp eq i32 [[I]], [[N]]
1776 ; CHECK-NEXT:    br i1 [[DONE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]]
1777 ; CHECK:       exit.loopexit:
1778 ; CHECK-NEXT:    br label [[EXIT]]
1779 ; CHECK:       exit:
1780 ; CHECK-NEXT:    ret i32 0
1782 entry:
1783   %tmp5 = icmp sle i32 %n, 0
1784   br i1 %tmp5, label %exit, label %loop.preheader
1786 loop.preheader:
1787   br label %loop
1789 loop:
1790   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1791   %within.bounds = icmp ult i32 %i, %length
1792   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1794   %i.next = add nuw i32 %i, 1
1795   %done = icmp eq i32 %i, %n
1796   br i1 %done, label %exit, label %loop
1798 exit:
1799   ret i32 0
1803 ; NE latch - can't prove (end-start) mod step == 0 (i.e. might wrap
1804 ; around several times or even be infinite)
1805 define i32 @neg_ne_latch_mod_step(i32* %array, i32 %length, i16 %n16) {
1806 ; CHECK-LABEL: @neg_ne_latch_mod_step(
1807 ; CHECK-NEXT:  loop.preheader:
1808 ; CHECK-NEXT:    [[N:%.*]] = zext i16 [[N16:%.*]] to i32
1809 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1810 ; CHECK:       loop:
1811 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1812 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1813 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1814 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 3
1815 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], [[N]]
1816 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1817 ; CHECK:       exit:
1818 ; CHECK-NEXT:    ret i32 0
1820 loop.preheader:
1821   %n = zext i16 %n16 to i32
1822   br label %loop
1824 loop:
1825   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1826   %within.bounds = icmp ult i32 %i, %length
1827   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1829   %i.next = add i32 %i, 3
1830   %continue = icmp ne i32 %i, %n
1831   br i1 %continue, label %loop, label %exit
1833 exit:
1834   ret i32 0
1837 ; NE latch - TODO: could prove (end-start) mod step == 0
1838 define i32 @ne_latch_mod_step(i32* %array, i32 %length) {
1839 ; CHECK-LABEL: @ne_latch_mod_step(
1840 ; CHECK-NEXT:  loop.preheader:
1841 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1842 ; CHECK:       loop:
1843 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1844 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1845 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1846 ; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 2
1847 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], 400
1848 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1849 ; CHECK:       exit:
1850 ; CHECK-NEXT:    ret i32 0
1852 loop.preheader:
1853   br label %loop
1855 loop:
1856   %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1857   %within.bounds = icmp ult i32 %i, %length
1858   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1860   %i.next = add nuw i32 %i, 2
1861   %continue = icmp ne i32 %i, 400
1862   br i1 %continue, label %loop, label %exit
1864 exit:
1865   ret i32 0
1868 ; NE Latch - but end > start so wraps around and not equivelent to a ult
1869 define i32 @neg_ne_latch_swapped_order(i32* %array, i32 %length) {
1870 ; CHECK-LABEL: @neg_ne_latch_swapped_order(
1871 ; CHECK-NEXT:  loop.preheader:
1872 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1873 ; CHECK:       loop:
1874 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ]
1875 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1876 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1877 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1878 ; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ne i32 [[I]], 0
1879 ; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1880 ; CHECK:       exit:
1881 ; CHECK-NEXT:    ret i32 0
1883 loop.preheader:
1884   br label %loop
1886 loop:
1887   %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ]
1888   %within.bounds = icmp ult i32 %i, %length
1889   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1891   %i.next = add i32 %i, 1
1892   %continue = icmp ne i32 %i, 0
1893   br i1 %continue, label %loop, label %exit
1895 exit:
1896   ret i32 0
1899 ; Negative test, make sure we don't crash on unconditional latches
1900 ; TODO: there's no reason we shouldn't be able to predicate the
1901 ; condition for an statically infinite loop.
1902 define i32 @unconditional_latch(i32* %a, i32 %length) {
1903 ; CHECK-LABEL: @unconditional_latch(
1904 ; CHECK-NEXT:  loop.preheader:
1905 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1906 ; CHECK:       loop:
1907 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 400, [[LOOP_PREHEADER:%.*]] ]
1908 ; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1909 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WITHIN_BOUNDS]], i32 9) [ "deopt"() ]
1910 ; CHECK-NEXT:    store volatile i32 0, i32* [[A:%.*]], align 4
1911 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1912 ; CHECK-NEXT:    br label [[LOOP]]
1914 loop.preheader:
1915   br label %loop
1917 loop:
1918   %i = phi i32 [ %i.next, %loop ], [ 400, %loop.preheader ]
1919   %within.bounds = icmp ult i32 %i, %length
1920   call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1921   store volatile i32 0, i32* %a
1922   %i.next = add i32 %i, 1
1923   br label %loop