Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / backedge-on-min-max.ll
blob77b7cdaa0a5066c44998deca5815e30163544ea9
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt < %s -passes=indvars -S | FileCheck %s
3 ; RUN: opt -passes=lcssa,loop-simplify -S < %s | opt -S -passes='require<targetir>,require<scalar-evolution>,require<domtree>,loop(indvars)'
5 ;; --- signed ---
7 define void @min.signed.1(ptr %a, i32 %a_len, i32 %n) {
8 ; CHECK-LABEL: define void @min.signed.1(
9 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    [[SMIN_CMP:%.*]] = icmp slt i32 [[A_LEN]], [[N]]
12 ; CHECK-NEXT:    [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
13 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
14 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
15 ; CHECK:       loop.preheader:
16 ; CHECK-NEXT:    br label [[LOOP:%.*]]
17 ; CHECK:       loop:
18 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
19 ; CHECK-NEXT:    [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
20 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
21 ; CHECK:       ok:
22 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
23 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
24 ; CHECK-NEXT:    br label [[LATCH]]
25 ; CHECK:       latch:
26 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
27 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
28 ; CHECK:       exit.loopexit:
29 ; CHECK-NEXT:    br label [[EXIT]]
30 ; CHECK:       exit:
31 ; CHECK-NEXT:    ret void
33 entry:
34   %smin.cmp = icmp slt i32 %a_len, %n
35   %smin = select i1 %smin.cmp, i32 %a_len, i32 %n
36   %entry.cond = icmp slt i32 0, %smin
37   br i1 %entry.cond, label %loop, label %exit
39 loop:
40   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
41   %idx.inc = add i32 %idx, 1
42   %in.bounds = icmp slt i32 %idx, %a_len
43   br i1 %in.bounds, label %ok, label %latch
45 ok:
46   %addr = getelementptr i32, ptr %a, i32 %idx
47   store i32 %idx, ptr %addr
48   br label %latch
50 latch:
51   %be.cond = icmp slt i32 %idx.inc, %smin
52   br i1 %be.cond, label %loop, label %exit
54 exit:
55   ret void
58 define void @min.signed.2(ptr %a, i32 %a_len, i32 %n) {
59 ; CHECK-LABEL: define void @min.signed.2(
60 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
61 ; CHECK-NEXT:  entry:
62 ; CHECK-NEXT:    [[SMIN_CMP:%.*]] = icmp slt i32 [[A_LEN]], [[N]]
63 ; CHECK-NEXT:    [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
64 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
65 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
66 ; CHECK:       loop.preheader:
67 ; CHECK-NEXT:    br label [[LOOP:%.*]]
68 ; CHECK:       loop:
69 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
70 ; CHECK-NEXT:    [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
71 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
72 ; CHECK:       ok:
73 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
74 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
75 ; CHECK-NEXT:    br label [[LATCH]]
76 ; CHECK:       latch:
77 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
78 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
79 ; CHECK:       exit.loopexit:
80 ; CHECK-NEXT:    br label [[EXIT]]
81 ; CHECK:       exit:
82 ; CHECK-NEXT:    ret void
84 entry:
85   %smin.cmp = icmp slt i32 %a_len, %n
86   %smin = select i1 %smin.cmp, i32 %a_len, i32 %n
87   %entry.cond = icmp slt i32 0, %smin
88   br i1 %entry.cond, label %loop, label %exit
90 loop:
91   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
92   %idx.inc = add i32 %idx, 1
93   %in.bounds = icmp sgt i32 %a_len, %idx
94   br i1 %in.bounds, label %ok, label %latch
96 ok:
97   %addr = getelementptr i32, ptr %a, i32 %idx
98   store i32 %idx, ptr %addr
99   br label %latch
101 latch:
102   %be.cond = icmp slt i32 %idx.inc, %smin
103   br i1 %be.cond, label %loop, label %exit
105 exit:
106   ret void
109 define void @min.signed.3(ptr %a, i32 %n) {
110 ; CHECK-LABEL: define void @min.signed.3(
111 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
112 ; CHECK-NEXT:  entry:
113 ; CHECK-NEXT:    [[SMIN_CMP:%.*]] = icmp slt i32 42, [[N]]
114 ; CHECK-NEXT:    [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 42, i32 [[N]]
115 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
116 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
117 ; CHECK:       loop.preheader:
118 ; CHECK-NEXT:    br label [[LOOP:%.*]]
119 ; CHECK:       loop:
120 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
121 ; CHECK-NEXT:    [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
122 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
123 ; CHECK:       ok:
124 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
125 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
126 ; CHECK-NEXT:    br label [[LATCH]]
127 ; CHECK:       latch:
128 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
129 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
130 ; CHECK:       exit.loopexit:
131 ; CHECK-NEXT:    br label [[EXIT]]
132 ; CHECK:       exit:
133 ; CHECK-NEXT:    ret void
135 entry:
136   %smin.cmp = icmp slt i32 42, %n
137   %smin = select i1 %smin.cmp, i32 42, i32 %n
138   %entry.cond = icmp slt i32 0, %smin
139   br i1 %entry.cond, label %loop, label %exit
141 loop:
142   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
143   %idx.inc = add i32 %idx, 1
144   %in.bounds = icmp slt i32 %idx, 42
145   br i1 %in.bounds, label %ok, label %latch
148   %addr = getelementptr i32, ptr %a, i32 %idx
149   store i32 %idx, ptr %addr
150   br label %latch
152 latch:
153   %be.cond = icmp slt i32 %idx.inc, %smin
154   br i1 %be.cond, label %loop, label %exit
156 exit:
157   ret void
160 define void @min.signed.4(ptr %a, i32 %n) {
161 ; CHECK-LABEL: define void @min.signed.4(
162 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
163 ; CHECK-NEXT:  entry:
164 ; CHECK-NEXT:    [[SMIN_CMP:%.*]] = icmp slt i32 42, [[N]]
165 ; CHECK-NEXT:    [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 42, i32 [[N]]
166 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
167 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
168 ; CHECK:       loop.preheader:
169 ; CHECK-NEXT:    br label [[LOOP:%.*]]
170 ; CHECK:       loop:
171 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
172 ; CHECK-NEXT:    [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
173 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
174 ; CHECK:       ok:
175 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
176 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
177 ; CHECK-NEXT:    br label [[LATCH]]
178 ; CHECK:       latch:
179 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
180 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
181 ; CHECK:       exit.loopexit:
182 ; CHECK-NEXT:    br label [[EXIT]]
183 ; CHECK:       exit:
184 ; CHECK-NEXT:    ret void
186 entry:
187   %smin.cmp = icmp slt i32 42, %n
188   %smin = select i1 %smin.cmp, i32 42, i32 %n
189   %entry.cond = icmp slt i32 0, %smin
190   br i1 %entry.cond, label %loop, label %exit
192 loop:
193   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
194   %idx.inc = add i32 %idx, 1
195   %in.bounds = icmp sgt i32 42, %idx
196   br i1 %in.bounds, label %ok, label %latch
199   %addr = getelementptr i32, ptr %a, i32 %idx
200   store i32 %idx, ptr %addr
201   br label %latch
203 latch:
204   %be.cond = icmp slt i32 %idx.inc, %smin
205   br i1 %be.cond, label %loop, label %exit
207 exit:
208   ret void
211 define void @max.signed.1(ptr %a, i32 %a_len, i32 %n) {
212 ; CHECK-LABEL: define void @max.signed.1(
213 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
214 ; CHECK-NEXT:  entry:
215 ; CHECK-NEXT:    [[SMAX_CMP:%.*]] = icmp sgt i32 [[A_LEN]], [[N]]
216 ; CHECK-NEXT:    [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
217 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp sgt i32 0, [[SMAX]]
218 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
219 ; CHECK:       loop.preheader:
220 ; CHECK-NEXT:    br label [[LOOP:%.*]]
221 ; CHECK:       loop:
222 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
223 ; CHECK-NEXT:    [[IDX_INC]] = add i32 [[IDX]], 1
224 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
225 ; CHECK:       ok:
226 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
227 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
228 ; CHECK-NEXT:    br label [[LATCH]]
229 ; CHECK:       latch:
230 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
231 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
232 ; CHECK:       exit.loopexit:
233 ; CHECK-NEXT:    br label [[EXIT]]
234 ; CHECK:       exit:
235 ; CHECK-NEXT:    ret void
237 entry:
238   %smax.cmp = icmp sgt i32 %a_len, %n
239   %smax = select i1 %smax.cmp, i32 %a_len, i32 %n
240   %entry.cond = icmp sgt i32 0, %smax
241   br i1 %entry.cond, label %loop, label %exit
243 loop:
244   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
245   %idx.inc = add i32 %idx, 1
246   %in.bounds = icmp sgt i32 %idx, %a_len
247   br i1 %in.bounds, label %ok, label %latch
250   %addr = getelementptr i32, ptr %a, i32 %idx
251   store i32 %idx, ptr %addr
252   br label %latch
254 latch:
255   %be.cond = icmp sgt i32 %idx.inc, %smax
256   br i1 %be.cond, label %loop, label %exit
258 exit:
259   ret void
262 define void @max.signed.2(ptr %a, i32 %a_len, i32 %n) {
263 ; CHECK-LABEL: define void @max.signed.2(
264 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
265 ; CHECK-NEXT:  entry:
266 ; CHECK-NEXT:    [[SMAX_CMP:%.*]] = icmp sgt i32 [[A_LEN]], [[N]]
267 ; CHECK-NEXT:    [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
268 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp sgt i32 0, [[SMAX]]
269 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
270 ; CHECK:       loop.preheader:
271 ; CHECK-NEXT:    br label [[LOOP:%.*]]
272 ; CHECK:       loop:
273 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
274 ; CHECK-NEXT:    [[IDX_INC]] = add i32 [[IDX]], 1
275 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
276 ; CHECK:       ok:
277 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
278 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
279 ; CHECK-NEXT:    br label [[LATCH]]
280 ; CHECK:       latch:
281 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
282 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
283 ; CHECK:       exit.loopexit:
284 ; CHECK-NEXT:    br label [[EXIT]]
285 ; CHECK:       exit:
286 ; CHECK-NEXT:    ret void
288 entry:
289   %smax.cmp = icmp sgt i32 %a_len, %n
290   %smax = select i1 %smax.cmp, i32 %a_len, i32 %n
291   %entry.cond = icmp sgt i32 0, %smax
292   br i1 %entry.cond, label %loop, label %exit
294 loop:
295   %idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
296   %idx.inc = add i32 %idx, 1
297   %in.bounds = icmp slt i32 %a_len, %idx
298   br i1 %in.bounds, label %ok, label %latch
301   %addr = getelementptr i32, ptr %a, i32 %idx
302   store i32 %idx, ptr %addr
303   br label %latch
305 latch:
306   %be.cond = icmp sgt i32 %idx.inc, %smax
307   br i1 %be.cond, label %loop, label %exit
309 exit:
310   ret void
313 define void @max.signed.3(ptr %a, i32 %n, i32 %init) {
314 ; CHECK-LABEL: define void @max.signed.3(
315 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
316 ; CHECK-NEXT:  entry:
317 ; CHECK-NEXT:    [[SMAX_CMP:%.*]] = icmp sgt i32 42, [[N]]
318 ; CHECK-NEXT:    [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 42, i32 [[N]]
319 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp sgt i32 [[INIT]], [[SMAX]]
320 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
321 ; CHECK:       loop.preheader:
322 ; CHECK-NEXT:    br label [[LOOP:%.*]]
323 ; CHECK:       loop:
324 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
325 ; CHECK-NEXT:    [[IDX_INC]] = add nuw i32 [[IDX]], 1
326 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
327 ; CHECK:       ok:
328 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
329 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
330 ; CHECK-NEXT:    br label [[LATCH]]
331 ; CHECK:       latch:
332 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
333 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
334 ; CHECK:       exit.loopexit:
335 ; CHECK-NEXT:    br label [[EXIT]]
336 ; CHECK:       exit:
337 ; CHECK-NEXT:    ret void
339 entry:
340   %smax.cmp = icmp sgt i32 42, %n
341   %smax = select i1 %smax.cmp, i32 42, i32 %n
342   %entry.cond = icmp sgt i32 %init, %smax
343   br i1 %entry.cond, label %loop, label %exit
345 loop:
346   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
347   %idx.inc = add i32 %idx, 1
348   %in.bounds = icmp sgt i32 %idx, 42
349   br i1 %in.bounds, label %ok, label %latch
352   %addr = getelementptr i32, ptr %a, i32 %idx
353   store i32 %idx, ptr %addr
354   br label %latch
356 latch:
357   %be.cond = icmp sgt i32 %idx.inc, %smax
358   br i1 %be.cond, label %loop, label %exit
360 exit:
361   ret void
364 define void @max.signed.4(ptr %a, i32 %n, i32 %init) {
365 ; CHECK-LABEL: define void @max.signed.4(
366 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
367 ; CHECK-NEXT:  entry:
368 ; CHECK-NEXT:    [[SMAX_CMP:%.*]] = icmp sgt i32 42, [[N]]
369 ; CHECK-NEXT:    [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 42, i32 [[N]]
370 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp sgt i32 [[INIT]], [[SMAX]]
371 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
372 ; CHECK:       loop.preheader:
373 ; CHECK-NEXT:    br label [[LOOP:%.*]]
374 ; CHECK:       loop:
375 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
376 ; CHECK-NEXT:    [[IDX_INC]] = add nuw i32 [[IDX]], 1
377 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
378 ; CHECK:       ok:
379 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
380 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
381 ; CHECK-NEXT:    br label [[LATCH]]
382 ; CHECK:       latch:
383 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
384 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
385 ; CHECK:       exit.loopexit:
386 ; CHECK-NEXT:    br label [[EXIT]]
387 ; CHECK:       exit:
388 ; CHECK-NEXT:    ret void
390 entry:
391   %smax.cmp = icmp sgt i32 42, %n
392   %smax = select i1 %smax.cmp, i32 42, i32 %n
393   %entry.cond = icmp sgt i32 %init, %smax
394   br i1 %entry.cond, label %loop, label %exit
396 loop:
397   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
398   %idx.inc = add i32 %idx, 1
399   %in.bounds = icmp slt i32 42, %idx
400   br i1 %in.bounds, label %ok, label %latch
403   %addr = getelementptr i32, ptr %a, i32 %idx
404   store i32 %idx, ptr %addr
405   br label %latch
407 latch:
408   %be.cond = icmp sgt i32 %idx.inc, %smax
409   br i1 %be.cond, label %loop, label %exit
411 exit:
412   ret void
415 ;; --- unsigned ---
417 define void @min.unsigned.1(ptr %a, i32 %a_len, i32 %n) {
418 ; CHECK-LABEL: define void @min.unsigned.1(
419 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
420 ; CHECK-NEXT:  entry:
421 ; CHECK-NEXT:    [[UMIN_CMP:%.*]] = icmp ult i32 [[A_LEN]], [[N]]
422 ; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
423 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
424 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
425 ; CHECK:       loop.preheader:
426 ; CHECK-NEXT:    br label [[LOOP:%.*]]
427 ; CHECK:       loop:
428 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
429 ; CHECK-NEXT:    [[IDX_INC]] = add nuw i32 [[IDX]], 1
430 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
431 ; CHECK:       ok:
432 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
433 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
434 ; CHECK-NEXT:    br label [[LATCH]]
435 ; CHECK:       latch:
436 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
437 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
438 ; CHECK:       exit.loopexit:
439 ; CHECK-NEXT:    br label [[EXIT]]
440 ; CHECK:       exit:
441 ; CHECK-NEXT:    ret void
443 entry:
444   %umin.cmp = icmp ult i32 %a_len, %n
445   %umin = select i1 %umin.cmp, i32 %a_len, i32 %n
446   %entry.cond = icmp ult i32 5, %umin
447   br i1 %entry.cond, label %loop, label %exit
449 loop:
450   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
451   %idx.inc = add i32 %idx, 1
452   %in.bounds = icmp ult i32 %idx, %a_len
453   br i1 %in.bounds, label %ok, label %latch
456   %addr = getelementptr i32, ptr %a, i32 %idx
457   store i32 %idx, ptr %addr
458   br label %latch
460 latch:
461   %be.cond = icmp ult i32 %idx.inc, %umin
462   br i1 %be.cond, label %loop, label %exit
464 exit:
465   ret void
468 define void @min.unsigned.2(ptr %a, i32 %a_len, i32 %n) {
469 ; CHECK-LABEL: define void @min.unsigned.2(
470 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
471 ; CHECK-NEXT:  entry:
472 ; CHECK-NEXT:    [[UMIN_CMP:%.*]] = icmp ult i32 [[A_LEN]], [[N]]
473 ; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
474 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
475 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
476 ; CHECK:       loop.preheader:
477 ; CHECK-NEXT:    br label [[LOOP:%.*]]
478 ; CHECK:       loop:
479 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
480 ; CHECK-NEXT:    [[IDX_INC]] = add nuw i32 [[IDX]], 1
481 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
482 ; CHECK:       ok:
483 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
484 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
485 ; CHECK-NEXT:    br label [[LATCH]]
486 ; CHECK:       latch:
487 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
488 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
489 ; CHECK:       exit.loopexit:
490 ; CHECK-NEXT:    br label [[EXIT]]
491 ; CHECK:       exit:
492 ; CHECK-NEXT:    ret void
494 entry:
495   %umin.cmp = icmp ult i32 %a_len, %n
496   %umin = select i1 %umin.cmp, i32 %a_len, i32 %n
497   %entry.cond = icmp ult i32 5, %umin
498   br i1 %entry.cond, label %loop, label %exit
500 loop:
501   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
502   %idx.inc = add i32 %idx, 1
503   %in.bounds = icmp ugt i32 %a_len, %idx
504   br i1 %in.bounds, label %ok, label %latch
507   %addr = getelementptr i32, ptr %a, i32 %idx
508   store i32 %idx, ptr %addr
509   br label %latch
511 latch:
512   %be.cond = icmp ult i32 %idx.inc, %umin
513   br i1 %be.cond, label %loop, label %exit
515 exit:
516   ret void
519 define void @min.unsigned.3(ptr %a, i32 %n) {
520 ; CHECK-LABEL: define void @min.unsigned.3(
521 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
522 ; CHECK-NEXT:  entry:
523 ; CHECK-NEXT:    [[UMIN_CMP:%.*]] = icmp ult i32 42, [[N]]
524 ; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 42, i32 [[N]]
525 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
526 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
527 ; CHECK:       loop.preheader:
528 ; CHECK-NEXT:    br label [[LOOP:%.*]]
529 ; CHECK:       loop:
530 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
531 ; CHECK-NEXT:    [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
532 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
533 ; CHECK:       ok:
534 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
535 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
536 ; CHECK-NEXT:    br label [[LATCH]]
537 ; CHECK:       latch:
538 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
539 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
540 ; CHECK:       exit.loopexit:
541 ; CHECK-NEXT:    br label [[EXIT]]
542 ; CHECK:       exit:
543 ; CHECK-NEXT:    ret void
545 entry:
546   %umin.cmp = icmp ult i32 42, %n
547   %umin = select i1 %umin.cmp, i32 42, i32 %n
548   %entry.cond = icmp ult i32 5, %umin
549   br i1 %entry.cond, label %loop, label %exit
551 loop:
552   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
553   %idx.inc = add i32 %idx, 1
554   %in.bounds = icmp ult i32 %idx, 42
555   br i1 %in.bounds, label %ok, label %latch
558   %addr = getelementptr i32, ptr %a, i32 %idx
559   store i32 %idx, ptr %addr
560   br label %latch
562 latch:
563   %be.cond = icmp ult i32 %idx.inc, %umin
564   br i1 %be.cond, label %loop, label %exit
566 exit:
567   ret void
570 define void @min.unsigned.4(ptr %a, i32 %n) {
571 ; CHECK-LABEL: define void @min.unsigned.4(
572 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
573 ; CHECK-NEXT:  entry:
574 ; CHECK-NEXT:    [[UMIN_CMP:%.*]] = icmp ult i32 42, [[N]]
575 ; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 42, i32 [[N]]
576 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
577 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
578 ; CHECK:       loop.preheader:
579 ; CHECK-NEXT:    br label [[LOOP:%.*]]
580 ; CHECK:       loop:
581 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
582 ; CHECK-NEXT:    [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
583 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
584 ; CHECK:       ok:
585 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
586 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
587 ; CHECK-NEXT:    br label [[LATCH]]
588 ; CHECK:       latch:
589 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
590 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
591 ; CHECK:       exit.loopexit:
592 ; CHECK-NEXT:    br label [[EXIT]]
593 ; CHECK:       exit:
594 ; CHECK-NEXT:    ret void
596 entry:
597   %umin.cmp = icmp ult i32 42, %n
598   %umin = select i1 %umin.cmp, i32 42, i32 %n
599   %entry.cond = icmp ult i32 5, %umin
600   br i1 %entry.cond, label %loop, label %exit
602 loop:
603   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
604   %idx.inc = add i32 %idx, 1
605   %in.bounds = icmp ugt i32 42, %idx
606   br i1 %in.bounds, label %ok, label %latch
609   %addr = getelementptr i32, ptr %a, i32 %idx
610   store i32 %idx, ptr %addr
611   br label %latch
613 latch:
614   %be.cond = icmp ult i32 %idx.inc, %umin
615   br i1 %be.cond, label %loop, label %exit
617 exit:
618   ret void
621 define void @max.unsigned.1(ptr %a, i32 %a_len, i32 %n) {
622 ; CHECK-LABEL: define void @max.unsigned.1(
623 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
624 ; CHECK-NEXT:  entry:
625 ; CHECK-NEXT:    [[UMAX_CMP:%.*]] = icmp ugt i32 [[A_LEN]], [[N]]
626 ; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
627 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ugt i32 5, [[UMAX]]
628 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
629 ; CHECK:       loop.preheader:
630 ; CHECK-NEXT:    br label [[LOOP:%.*]]
631 ; CHECK:       loop:
632 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
633 ; CHECK-NEXT:    [[IDX_INC]] = add i32 [[IDX]], 1
634 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
635 ; CHECK:       ok:
636 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
637 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
638 ; CHECK-NEXT:    br label [[LATCH]]
639 ; CHECK:       latch:
640 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
641 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
642 ; CHECK:       exit.loopexit:
643 ; CHECK-NEXT:    br label [[EXIT]]
644 ; CHECK:       exit:
645 ; CHECK-NEXT:    ret void
647 entry:
648   %umax.cmp = icmp ugt i32 %a_len, %n
649   %umax = select i1 %umax.cmp, i32 %a_len, i32 %n
650   %entry.cond = icmp ugt i32 5, %umax
651   br i1 %entry.cond, label %loop, label %exit
653 loop:
654   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
655   %idx.inc = add i32 %idx, 1
656   %in.bounds = icmp ugt i32 %idx, %a_len
657   br i1 %in.bounds, label %ok, label %latch
660   %addr = getelementptr i32, ptr %a, i32 %idx
661   store i32 %idx, ptr %addr
662   br label %latch
664 latch:
665   %be.cond = icmp ugt i32 %idx.inc, %umax
666   br i1 %be.cond, label %loop, label %exit
668 exit:
669   ret void
672 define void @max.unsigned.2(ptr %a, i32 %a_len, i32 %n) {
673 ; CHECK-LABEL: define void @max.unsigned.2(
674 ; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
675 ; CHECK-NEXT:  entry:
676 ; CHECK-NEXT:    [[UMAX_CMP:%.*]] = icmp ugt i32 [[A_LEN]], [[N]]
677 ; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
678 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ugt i32 5, [[UMAX]]
679 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
680 ; CHECK:       loop.preheader:
681 ; CHECK-NEXT:    br label [[LOOP:%.*]]
682 ; CHECK:       loop:
683 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
684 ; CHECK-NEXT:    [[IDX_INC]] = add i32 [[IDX]], 1
685 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
686 ; CHECK:       ok:
687 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
688 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
689 ; CHECK-NEXT:    br label [[LATCH]]
690 ; CHECK:       latch:
691 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
692 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
693 ; CHECK:       exit.loopexit:
694 ; CHECK-NEXT:    br label [[EXIT]]
695 ; CHECK:       exit:
696 ; CHECK-NEXT:    ret void
698 entry:
699   %umax.cmp = icmp ugt i32 %a_len, %n
700   %umax = select i1 %umax.cmp, i32 %a_len, i32 %n
701   %entry.cond = icmp ugt i32 5, %umax
702   br i1 %entry.cond, label %loop, label %exit
704 loop:
705   %idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
706   %idx.inc = add i32 %idx, 1
707   %in.bounds = icmp ult i32 %a_len, %idx
708   br i1 %in.bounds, label %ok, label %latch
711   %addr = getelementptr i32, ptr %a, i32 %idx
712   store i32 %idx, ptr %addr
713   br label %latch
715 latch:
716   %be.cond = icmp ugt i32 %idx.inc, %umax
717   br i1 %be.cond, label %loop, label %exit
719 exit:
720   ret void
723 define void @max.unsigned.3(ptr %a, i32 %n, i32 %init) {
724 ; CHECK-LABEL: define void @max.unsigned.3(
725 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
726 ; CHECK-NEXT:  entry:
727 ; CHECK-NEXT:    [[UMAX_CMP:%.*]] = icmp ugt i32 42, [[N]]
728 ; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 42, i32 [[N]]
729 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ugt i32 [[INIT]], [[UMAX]]
730 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
731 ; CHECK:       loop.preheader:
732 ; CHECK-NEXT:    br label [[LOOP:%.*]]
733 ; CHECK:       loop:
734 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
735 ; CHECK-NEXT:    [[IDX_INC]] = add i32 [[IDX]], 1
736 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
737 ; CHECK:       ok:
738 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
739 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
740 ; CHECK-NEXT:    br label [[LATCH]]
741 ; CHECK:       latch:
742 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
743 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
744 ; CHECK:       exit.loopexit:
745 ; CHECK-NEXT:    br label [[EXIT]]
746 ; CHECK:       exit:
747 ; CHECK-NEXT:    ret void
749 entry:
750   %umax.cmp = icmp ugt i32 42, %n
751   %umax = select i1 %umax.cmp, i32 42, i32 %n
752   %entry.cond = icmp ugt i32 %init, %umax
753   br i1 %entry.cond, label %loop, label %exit
755 loop:
756   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
757   %idx.inc = add i32 %idx, 1
758   %in.bounds = icmp ugt i32 %idx, 42
759   br i1 %in.bounds, label %ok, label %latch
762   %addr = getelementptr i32, ptr %a, i32 %idx
763   store i32 %idx, ptr %addr
764   br label %latch
766 latch:
767   %be.cond = icmp ugt i32 %idx.inc, %umax
768   br i1 %be.cond, label %loop, label %exit
770 exit:
771   ret void
774 define void @max.unsigned.4(ptr %a, i32 %n, i32 %init) {
775 ; CHECK-LABEL: define void @max.unsigned.4(
776 ; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
777 ; CHECK-NEXT:  entry:
778 ; CHECK-NEXT:    [[UMAX_CMP:%.*]] = icmp ugt i32 42, [[N]]
779 ; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 42, i32 [[N]]
780 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp ugt i32 [[INIT]], [[UMAX]]
781 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
782 ; CHECK:       loop.preheader:
783 ; CHECK-NEXT:    br label [[LOOP:%.*]]
784 ; CHECK:       loop:
785 ; CHECK-NEXT:    [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
786 ; CHECK-NEXT:    [[IDX_INC]] = add i32 [[IDX]], 1
787 ; CHECK-NEXT:    br i1 true, label [[OK:%.*]], label [[LATCH]]
788 ; CHECK:       ok:
789 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
790 ; CHECK-NEXT:    store i32 [[IDX]], ptr [[ADDR]], align 4
791 ; CHECK-NEXT:    br label [[LATCH]]
792 ; CHECK:       latch:
793 ; CHECK-NEXT:    [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
794 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
795 ; CHECK:       exit.loopexit:
796 ; CHECK-NEXT:    br label [[EXIT]]
797 ; CHECK:       exit:
798 ; CHECK-NEXT:    ret void
800 entry:
801   %umax.cmp = icmp ugt i32 42, %n
802   %umax = select i1 %umax.cmp, i32 42, i32 %n
803   %entry.cond = icmp ugt i32 %init, %umax
804   br i1 %entry.cond, label %loop, label %exit
806 loop:
807   %idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
808   %idx.inc = add i32 %idx, 1
809   %in.bounds = icmp ult i32 42, %idx
810   br i1 %in.bounds, label %ok, label %latch
813   %addr = getelementptr i32, ptr %a, i32 %idx
814   store i32 %idx, ptr %addr
815   br label %latch
817 latch:
818   %be.cond = icmp ugt i32 %idx.inc, %umax
819   br i1 %be.cond, label %loop, label %exit
821 exit:
822   ret void