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<target-ir>,require<scalar-evolution>,require<domtree>,loop(indvars)'
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
31 ; CHECK-NEXT: ret void
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
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
46 %addr = getelementptr i32, ptr %a, i32 %idx
47 store i32 %idx, ptr %addr
51 %be.cond = icmp slt i32 %idx.inc, %smin
52 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
82 ; CHECK-NEXT: ret void
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
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
97 %addr = getelementptr i32, ptr %a, i32 %idx
98 store i32 %idx, ptr %addr
102 %be.cond = icmp slt i32 %idx.inc, %smin
103 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
133 ; CHECK-NEXT: ret void
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
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
153 %be.cond = icmp slt i32 %idx.inc, %smin
154 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
184 ; CHECK-NEXT: ret void
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
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
204 %be.cond = icmp slt i32 %idx.inc, %smin
205 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
235 ; CHECK-NEXT: ret void
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
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
255 %be.cond = icmp sgt i32 %idx.inc, %smax
256 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
286 ; CHECK-NEXT: ret void
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
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
306 %be.cond = icmp sgt i32 %idx.inc, %smax
307 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
337 ; CHECK-NEXT: ret void
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
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
357 %be.cond = icmp sgt i32 %idx.inc, %smax
358 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
388 ; CHECK-NEXT: ret void
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
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
408 %be.cond = icmp sgt i32 %idx.inc, %smax
409 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
441 ; CHECK-NEXT: ret void
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
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
461 %be.cond = icmp ult i32 %idx.inc, %umin
462 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
492 ; CHECK-NEXT: ret void
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
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
512 %be.cond = icmp ult i32 %idx.inc, %umin
513 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
543 ; CHECK-NEXT: ret void
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
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
563 %be.cond = icmp ult i32 %idx.inc, %umin
564 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
594 ; CHECK-NEXT: ret void
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
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
614 %be.cond = icmp ult i32 %idx.inc, %umin
615 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
645 ; CHECK-NEXT: ret void
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
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
665 %be.cond = icmp ugt i32 %idx.inc, %umax
666 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
696 ; CHECK-NEXT: ret void
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
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
716 %be.cond = icmp ugt i32 %idx.inc, %umax
717 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
747 ; CHECK-NEXT: ret void
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
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
767 %be.cond = icmp ugt i32 %idx.inc, %umax
768 br i1 %be.cond, label %loop, label %exit
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:%.*]]) {
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:%.*]]
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]]
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]]
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]]
798 ; CHECK-NEXT: ret void
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
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
818 %be.cond = icmp ugt i32 %idx.inc, %umax
819 br i1 %be.cond, label %loop, label %exit