Skip to content

Commit 4dc29b8

Browse files
committed
[LV] Add additional argmin/argmax tests for llvm#141431.
Apply suggestions for tests from llvm#141431 and add additional missing coverage.
1 parent a941e15 commit 4dc29b8

File tree

9 files changed

+568
-173
lines changed

9 files changed

+568
-173
lines changed

llvm/test/Transforms/LoopVectorize/AArch64/select-index.ll

Lines changed: 135 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ define i64 @test_vectorize_select_umin_first_idx(ptr %src, i64 %n) {
99
; CHECK: [[LOOP]]:
1010
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
1111
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
12-
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
12+
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 100, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
1313
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
1414
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
1515
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
@@ -28,15 +28,15 @@ entry:
2828
loop:
2929
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
3030
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
31-
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
31+
%min.val = phi i64 [ 100, %entry ], [ %min.val.next, %loop ]
3232
%gep = getelementptr i64, ptr %src, i64 %iv
3333
%l = load i64, ptr %gep
3434
%cmp = icmp ugt i64 %min.val, %l
3535
%min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
3636
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
3737
%iv.next = add nuw nsw i64 %iv, 1
38-
%exitcond.not = icmp eq i64 %iv.next, %n
39-
br i1 %exitcond.not, label %exit, label %loop
38+
%ec = icmp eq i64 %iv.next, %n
39+
br i1 %ec, label %exit, label %loop
4040

4141
exit:
4242
%res = phi i64 [ %min.idx.next, %loop ]
@@ -49,15 +49,15 @@ define i64 @test_vectorize_select_umin_last_idx(ptr %src, i64 %n) {
4949
; CHECK-NEXT: [[ENTRY:.*]]:
5050
; CHECK-NEXT: br label %[[LOOP:.*]]
5151
; CHECK: [[LOOP]]:
52-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
52+
; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
5353
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
54-
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
55-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
56-
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
54+
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 100, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
55+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]
56+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP1]], align 8
5757
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[MIN_VAL]], [[L]]
5858
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
59-
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
60-
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
59+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV1]], i64 [[MIN_IDX]]
60+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1
6161
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
6262
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
6363
; CHECK: [[EXIT]]:
@@ -70,15 +70,15 @@ entry:
7070
loop:
7171
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
7272
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
73-
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
73+
%min.val = phi i64 [ 100, %entry ], [ %min.val.next, %loop ]
7474
%gep = getelementptr i64, ptr %src, i64 %iv
7575
%l = load i64, ptr %gep
7676
%cmp = icmp uge i64 %min.val, %l
7777
%min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
7878
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
7979
%iv.next = add nuw nsw i64 %iv, 1
80-
%exitcond.not = icmp eq i64 %iv.next, %n
81-
br i1 %exitcond.not, label %exit, label %loop
80+
%ec = icmp eq i64 %iv.next, %n
81+
br i1 %ec, label %exit, label %loop
8282

8383
exit:
8484
%res = phi i64 [ %min.idx.next, %loop ]
@@ -119,8 +119,8 @@ loop:
119119
%min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)
120120
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
121121
%iv.next = add nuw nsw i64 %iv, 1
122-
%exitcond.not = icmp eq i64 %iv.next, %n
123-
br i1 %exitcond.not, label %exit, label %loop
122+
%ec = icmp eq i64 %iv.next, %n
123+
br i1 %ec, label %exit, label %loop
124124

125125
exit:
126126
%res = phi i64 [ %min.idx.next, %loop ]
@@ -133,15 +133,15 @@ define i64 @test_vectorize_select_smin_last_idx(ptr %src, i64 %n) {
133133
; CHECK-NEXT: [[ENTRY:.*]]:
134134
; CHECK-NEXT: br label %[[LOOP:.*]]
135135
; CHECK: [[LOOP]]:
136-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
136+
; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
137137
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
138138
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
139-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
140-
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
139+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]
140+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP1]], align 8
141141
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]
142142
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])
143-
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
144-
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
143+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV1]], i64 [[MIN_IDX]]
144+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1
145145
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
146146
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
147147
; CHECK: [[EXIT]]:
@@ -161,8 +161,8 @@ loop:
161161
%min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)
162162
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
163163
%iv.next = add nuw nsw i64 %iv, 1
164-
%exitcond.not = icmp eq i64 %iv.next, %n
165-
br i1 %exitcond.not, label %exit, label %loop
164+
%ec = icmp eq i64 %iv.next, %n
165+
br i1 %ec, label %exit, label %loop
166166

167167
exit:
168168
%res = phi i64 [ %min.idx.next, %loop ]
@@ -203,8 +203,8 @@ loop:
203203
%min.val.next = tail call i64 @llvm.umax.i64(i64 %min.val, i64 %l)
204204
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
205205
%iv.next = add nuw nsw i64 %iv, 1
206-
%exitcond.not = icmp eq i64 %iv.next, %n
207-
br i1 %exitcond.not, label %exit, label %loop
206+
%ec = icmp eq i64 %iv.next, %n
207+
br i1 %ec, label %exit, label %loop
208208

209209
exit:
210210
%res = phi i64 [ %min.idx.next, %loop ]
@@ -217,15 +217,15 @@ define i64 @test_vectorize_select_umax_last_idx(ptr %src, i64 %n) {
217217
; CHECK-NEXT: [[ENTRY:.*]]:
218218
; CHECK-NEXT: br label %[[LOOP:.*]]
219219
; CHECK: [[LOOP]]:
220-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
220+
; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
221221
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
222222
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
223-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
224-
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
223+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]
224+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP1]], align 8
225225
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[MIN_VAL]], [[L]]
226226
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.umax.i64(i64 [[MIN_VAL]], i64 [[L]])
227-
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
228-
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
227+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV1]], i64 [[MIN_IDX]]
228+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1
229229
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
230230
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
231231
; CHECK: [[EXIT]]:
@@ -245,8 +245,8 @@ loop:
245245
%min.val.next = tail call i64 @llvm.umax.i64(i64 %min.val, i64 %l)
246246
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
247247
%iv.next = add nuw nsw i64 %iv, 1
248-
%exitcond.not = icmp eq i64 %iv.next, %n
249-
br i1 %exitcond.not, label %exit, label %loop
248+
%ec = icmp eq i64 %iv.next, %n
249+
br i1 %ec, label %exit, label %loop
250250

251251
exit:
252252
%res = phi i64 [ %min.idx.next, %loop ]
@@ -287,8 +287,8 @@ loop:
287287
%min.val.next = tail call i64 @llvm.smax.i64(i64 %min.val, i64 %l)
288288
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
289289
%iv.next = add nuw nsw i64 %iv, 1
290-
%exitcond.not = icmp eq i64 %iv.next, %n
291-
br i1 %exitcond.not, label %exit, label %loop
290+
%ec = icmp eq i64 %iv.next, %n
291+
br i1 %ec, label %exit, label %loop
292292

293293
exit:
294294
%res = phi i64 [ %min.idx.next, %loop ]
@@ -301,15 +301,15 @@ define i64 @test_vectorize_select_smax_last_idx(ptr %src, i64 %n) {
301301
; CHECK-NEXT: [[ENTRY:.*]]:
302302
; CHECK-NEXT: br label %[[LOOP:.*]]
303303
; CHECK: [[LOOP]]:
304-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
304+
; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
305305
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
306306
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
307-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
308-
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
307+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV1]]
308+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP1]], align 8
309309
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[MIN_VAL]], [[L]]
310310
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smax.i64(i64 [[MIN_VAL]], i64 [[L]])
311-
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
312-
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
311+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV1]], i64 [[MIN_IDX]]
312+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1
313313
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
314314
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
315315
; CHECK: [[EXIT]]:
@@ -329,10 +329,105 @@ loop:
329329
%min.val.next = tail call i64 @llvm.smax.i64(i64 %min.val, i64 %l)
330330
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
331331
%iv.next = add nuw nsw i64 %iv, 1
332-
%exitcond.not = icmp eq i64 %iv.next, %n
333-
br i1 %exitcond.not, label %exit, label %loop
332+
%ec = icmp eq i64 %iv.next, %n
333+
br i1 %ec, label %exit, label %loop
334334

335335
exit:
336336
%res = phi i64 [ %min.idx.next, %loop ]
337337
ret i64 %res
338338
}
339+
340+
define i32 @test_select_no_iv_operand_optsize(ptr %s) #0 {
341+
; CHECK-LABEL: define i32 @test_select_no_iv_operand_optsize(
342+
; CHECK-SAME: ptr [[S:%.*]]) #[[ATTR0:[0-9]+]] {
343+
; CHECK-NEXT: [[ENTRY:.*]]:
344+
; CHECK-NEXT: br label %[[LOOP:.*]]
345+
; CHECK: [[LOOP]]:
346+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
347+
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
348+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
349+
; CHECK-NEXT: [[C_0:%.*]] = icmp eq i64 [[MIN_VAL]], 0
350+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[C_0]], i32 [[MIN_IDX]], i32 0
351+
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[IV]], i64 [[MIN_VAL]])
352+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
353+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 19
354+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
355+
; CHECK: [[EXIT]]:
356+
; CHECK-NEXT: [[MIN_IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
357+
; CHECK-NEXT: ret i32 [[MIN_IDX_NEXT_LCSSA]]
358+
;
359+
entry:
360+
br label %loop
361+
362+
loop:
363+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
364+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
365+
%min.idx = phi i32 [ 0, %entry ], [ %min.idx.next, %loop ]
366+
%c.0 = icmp eq i64 %min.val, 0
367+
%min.idx.next = select i1 %c.0, i32 %min.idx, i32 0
368+
%min.val.next = tail call i64 @llvm.umin.i64(i64 %iv, i64 %min.val)
369+
%iv.next = add i64 %iv, 1
370+
%ec = icmp eq i64 %iv, 19
371+
br i1 %ec, label %exit, label %loop
372+
373+
exit:
374+
ret i32 %min.idx.next
375+
}
376+
377+
; The reduction phi is used in a comparison that feeds a select with a truncated IV.
378+
define i32 @test_multi_use_reduction_with_trunc_iv(ptr %src, i32 %n) {
379+
; CHECK-LABEL: define i32 @test_multi_use_reduction_with_trunc_iv(
380+
; CHECK-SAME: ptr [[SRC:%.*]], i32 [[N:%.*]]) {
381+
; CHECK-NEXT: [[ENTRY:.*]]:
382+
; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i64
383+
; CHECK-NEXT: [[PRE:%.*]] = icmp eq i32 [[N]], 0
384+
; CHECK-NEXT: br i1 [[PRE]], label %[[EXIT:.*]], label %[[LOOP_PREHEADER:.*]]
385+
; CHECK: [[LOOP_PREHEADER]]:
386+
; CHECK-NEXT: br label %[[LOOP:.*]]
387+
; CHECK: [[LOOP]]:
388+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ 1, %[[LOOP_PREHEADER]] ]
389+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i32 [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[LOOP_PREHEADER]] ]
390+
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i32 [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ], [ 0, %[[LOOP_PREHEADER]] ]
391+
; CHECK-NEXT: [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV]]
392+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 4
393+
; CHECK-NEXT: [[C_0:%.*]] = icmp ugt i32 [[L]], [[MIN_VAL]]
394+
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i32 @llvm.umin.i32(i32 [[L]], i32 [[MIN_VAL]])
395+
; CHECK-NEXT: [[IV_TRUNC:%.*]] = trunc i64 [[IV]] to i32
396+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[C_0]], i32 [[MIN_IDX]], i32 [[IV_TRUNC]]
397+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
398+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[N_EXT]]
399+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP]]
400+
; CHECK: [[EXIT_LOOPEXIT]]:
401+
; CHECK-NEXT: [[MIN_IDX_NEXT_LCSSA:%.*]] = phi i32 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
402+
; CHECK-NEXT: br label %[[EXIT]]
403+
; CHECK: [[EXIT]]:
404+
; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT_LCSSA]], %[[EXIT_LOOPEXIT]] ]
405+
; CHECK-NEXT: ret i32 [[RES]]
406+
;
407+
entry:
408+
%n.ext = zext i32 %n to i64
409+
%pre = icmp eq i32 %n, 0
410+
br i1 %pre, label %exit, label %loop
411+
412+
loop:
413+
%iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
414+
%min.idx = phi i32 [ 0, %entry ], [ %min.idx.next, %loop ]
415+
%min.val = phi i32 [ 0, %entry ], [ %min.val.next, %loop ]
416+
%gep.src = getelementptr i32, ptr %src, i64 %iv
417+
%l = load i32, ptr %gep.src, align 4
418+
%c.0 = icmp ugt i32 %l, %min.val
419+
%min.val.next = tail call i32 @llvm.umin.i32(i32 %l, i32 %min.val)
420+
%iv.trunc = trunc i64 %iv to i32
421+
%min.idx.next = select i1 %c.0, i32 %min.idx, i32 %iv.trunc
422+
%iv.next = add i64 %iv, 1
423+
%ec = icmp eq i64 %iv, %n.ext
424+
br i1 %ec, label %exit, label %loop
425+
426+
exit:
427+
%res = phi i32 [ 0, %entry ], [ %min.idx.next, %loop ]
428+
ret i32 %res
429+
}
430+
431+
declare i32 @llvm.umin.i32(i32, i32)
432+
433+
attributes #0 = { optsize "target-cpu"="neoverse-v2" }

0 commit comments

Comments
 (0)