Skip to content

Commit 9ee4b35

Browse files
committed
[LV] Reorganize index select tests (NFC).
This reorganizes the test coverage for selecting the min/max index. It adds coverage for umin,umax,smin,smax variants, including test-coverage for interleave codegen and cost-model driven tests.
1 parent 414590b commit 9ee4b35

File tree

8 files changed

+3457
-1084
lines changed

8 files changed

+3457
-1084
lines changed
Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 5
2+
; RUN: opt -passes=loop-vectorize -mtriple=arm64-apple-macosx -S %s | FileCheck %s
3+
4+
define i64 @test_vectorize_select_umin_first_idx(ptr %src, i64 %n) {
5+
; CHECK-LABEL: define i64 @test_vectorize_select_umin_first_idx(
6+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*]]:
8+
; CHECK-NEXT: br label %[[LOOP:.*]]
9+
; CHECK: [[LOOP]]:
10+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
11+
; 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]] ]
13+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
14+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
15+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[MIN_VAL]], [[L]]
16+
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.umin.i64(i64 [[MIN_VAL]], i64 [[L]])
17+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
18+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
19+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
20+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
21+
; CHECK: [[EXIT]]:
22+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
23+
; CHECK-NEXT: ret i64 [[RES]]
24+
;
25+
entry:
26+
br label %loop
27+
28+
loop:
29+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
30+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
31+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
32+
%gep = getelementptr i64, ptr %src, i64 %iv
33+
%l = load i64, ptr %gep
34+
%cmp = icmp ugt i64 %min.val, %l
35+
%min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
36+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
37+
%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
40+
41+
exit:
42+
%res = phi i64 [ %min.idx.next, %loop ]
43+
ret i64 %res
44+
}
45+
46+
define i64 @test_vectorize_select_umin_last_idx(ptr %src, i64 %n) {
47+
; CHECK-LABEL: define i64 @test_vectorize_select_umin_last_idx(
48+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
49+
; CHECK-NEXT: [[ENTRY:.*]]:
50+
; CHECK-NEXT: br label %[[LOOP:.*]]
51+
; CHECK: [[LOOP]]:
52+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
53+
; 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
57+
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[MIN_VAL]], [[L]]
58+
; 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
61+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
62+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
63+
; CHECK: [[EXIT]]:
64+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
65+
; CHECK-NEXT: ret i64 [[RES]]
66+
;
67+
entry:
68+
br label %loop
69+
70+
loop:
71+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
72+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
73+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
74+
%gep = getelementptr i64, ptr %src, i64 %iv
75+
%l = load i64, ptr %gep
76+
%cmp = icmp uge i64 %min.val, %l
77+
%min.val.next = tail call i64 @llvm.umin.i64(i64 %min.val, i64 %l)
78+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
79+
%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
82+
83+
exit:
84+
%res = phi i64 [ %min.idx.next, %loop ]
85+
ret i64 %res
86+
}
87+
88+
define i64 @test_vectorize_select_smin_first_idx(ptr %src, i64 %n) {
89+
; CHECK-LABEL: define i64 @test_vectorize_select_smin_first_idx(
90+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
91+
; CHECK-NEXT: [[ENTRY:.*]]:
92+
; CHECK-NEXT: br label %[[LOOP:.*]]
93+
; CHECK: [[LOOP]]:
94+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
95+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
96+
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
97+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
98+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
99+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[MIN_VAL]], [[L]]
100+
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smin.i64(i64 [[MIN_VAL]], i64 [[L]])
101+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
102+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
103+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
104+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
105+
; CHECK: [[EXIT]]:
106+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
107+
; CHECK-NEXT: ret i64 [[RES]]
108+
;
109+
entry:
110+
br label %loop
111+
112+
loop:
113+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
114+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
115+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
116+
%gep = getelementptr i64, ptr %src, i64 %iv
117+
%l = load i64, ptr %gep
118+
%cmp = icmp sgt i64 %min.val, %l
119+
%min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)
120+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
121+
%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
124+
125+
exit:
126+
%res = phi i64 [ %min.idx.next, %loop ]
127+
ret i64 %res
128+
}
129+
130+
define i64 @test_vectorize_select_smin_last_idx(ptr %src, i64 %n) {
131+
; CHECK-LABEL: define i64 @test_vectorize_select_smin_last_idx(
132+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
133+
; CHECK-NEXT: [[ENTRY:.*]]:
134+
; CHECK-NEXT: br label %[[LOOP:.*]]
135+
; CHECK: [[LOOP]]:
136+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
137+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
138+
; 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
141+
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i64 [[MIN_VAL]], [[L]]
142+
; 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
145+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
146+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
147+
; CHECK: [[EXIT]]:
148+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
149+
; CHECK-NEXT: ret i64 [[RES]]
150+
;
151+
entry:
152+
br label %loop
153+
154+
loop:
155+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
156+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
157+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
158+
%gep = getelementptr i64, ptr %src, i64 %iv
159+
%l = load i64, ptr %gep
160+
%cmp = icmp sge i64 %min.val, %l
161+
%min.val.next = tail call i64 @llvm.smin.i64(i64 %min.val, i64 %l)
162+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
163+
%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
166+
167+
exit:
168+
%res = phi i64 [ %min.idx.next, %loop ]
169+
ret i64 %res
170+
}
171+
172+
define i64 @test_vectorize_select_umax_first_idx(ptr %src, i64 %n) {
173+
; CHECK-LABEL: define i64 @test_vectorize_select_umax_first_idx(
174+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
175+
; CHECK-NEXT: [[ENTRY:.*]]:
176+
; CHECK-NEXT: br label %[[LOOP:.*]]
177+
; CHECK: [[LOOP]]:
178+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
179+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
180+
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
181+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
182+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
183+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[MIN_VAL]], [[L]]
184+
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.umax.i64(i64 [[MIN_VAL]], i64 [[L]])
185+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
186+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
187+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
188+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
189+
; CHECK: [[EXIT]]:
190+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
191+
; CHECK-NEXT: ret i64 [[RES]]
192+
;
193+
entry:
194+
br label %loop
195+
196+
loop:
197+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
198+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
199+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
200+
%gep = getelementptr i64, ptr %src, i64 %iv
201+
%l = load i64, ptr %gep
202+
%cmp = icmp ult i64 %min.val, %l
203+
%min.val.next = tail call i64 @llvm.umax.i64(i64 %min.val, i64 %l)
204+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
205+
%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
208+
209+
exit:
210+
%res = phi i64 [ %min.idx.next, %loop ]
211+
ret i64 %res
212+
}
213+
214+
define i64 @test_vectorize_select_umax_last_idx(ptr %src, i64 %n) {
215+
; CHECK-LABEL: define i64 @test_vectorize_select_umax_last_idx(
216+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
217+
; CHECK-NEXT: [[ENTRY:.*]]:
218+
; CHECK-NEXT: br label %[[LOOP:.*]]
219+
; CHECK: [[LOOP]]:
220+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
221+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
222+
; 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
225+
; CHECK-NEXT: [[CMP:%.*]] = icmp ule i64 [[MIN_VAL]], [[L]]
226+
; 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
229+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
230+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
231+
; CHECK: [[EXIT]]:
232+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
233+
; CHECK-NEXT: ret i64 [[RES]]
234+
;
235+
entry:
236+
br label %loop
237+
238+
loop:
239+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
240+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
241+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
242+
%gep = getelementptr i64, ptr %src, i64 %iv
243+
%l = load i64, ptr %gep
244+
%cmp = icmp ule i64 %min.val, %l
245+
%min.val.next = tail call i64 @llvm.umax.i64(i64 %min.val, i64 %l)
246+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
247+
%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
250+
251+
exit:
252+
%res = phi i64 [ %min.idx.next, %loop ]
253+
ret i64 %res
254+
}
255+
256+
define i64 @test_vectorize_select_smax_first_idx(ptr %src, i64 %n) {
257+
; CHECK-LABEL: define i64 @test_vectorize_select_smax_first_idx(
258+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
259+
; CHECK-NEXT: [[ENTRY:.*]]:
260+
; CHECK-NEXT: br label %[[LOOP:.*]]
261+
; CHECK: [[LOOP]]:
262+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
263+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
264+
; CHECK-NEXT: [[MIN_VAL:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_VAL_NEXT:%.*]], %[[LOOP]] ]
265+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i64, ptr [[SRC]], i64 [[IV]]
266+
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8
267+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[MIN_VAL]], [[L]]
268+
; CHECK-NEXT: [[MIN_VAL_NEXT]] = tail call i64 @llvm.smax.i64(i64 [[MIN_VAL]], i64 [[L]])
269+
; CHECK-NEXT: [[MIN_IDX_NEXT]] = select i1 [[CMP]], i64 [[IV]], i64 [[MIN_IDX]]
270+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
271+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
272+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
273+
; CHECK: [[EXIT]]:
274+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
275+
; CHECK-NEXT: ret i64 [[RES]]
276+
;
277+
entry:
278+
br label %loop
279+
280+
loop:
281+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
282+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
283+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
284+
%gep = getelementptr i64, ptr %src, i64 %iv
285+
%l = load i64, ptr %gep
286+
%cmp = icmp slt i64 %min.val, %l
287+
%min.val.next = tail call i64 @llvm.smax.i64(i64 %min.val, i64 %l)
288+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
289+
%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
292+
293+
exit:
294+
%res = phi i64 [ %min.idx.next, %loop ]
295+
ret i64 %res
296+
}
297+
298+
define i64 @test_vectorize_select_smax_last_idx(ptr %src, i64 %n) {
299+
; CHECK-LABEL: define i64 @test_vectorize_select_smax_last_idx(
300+
; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {
301+
; CHECK-NEXT: [[ENTRY:.*]]:
302+
; CHECK-NEXT: br label %[[LOOP:.*]]
303+
; CHECK: [[LOOP]]:
304+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
305+
; CHECK-NEXT: [[MIN_IDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[MIN_IDX_NEXT:%.*]], %[[LOOP]] ]
306+
; 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
309+
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[MIN_VAL]], [[L]]
310+
; 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
313+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
314+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP]]
315+
; CHECK: [[EXIT]]:
316+
; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[MIN_IDX_NEXT]], %[[LOOP]] ]
317+
; CHECK-NEXT: ret i64 [[RES]]
318+
;
319+
entry:
320+
br label %loop
321+
322+
loop:
323+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
324+
%min.idx = phi i64 [ 0, %entry ], [ %min.idx.next, %loop ]
325+
%min.val = phi i64 [ 0, %entry ], [ %min.val.next, %loop ]
326+
%gep = getelementptr i64, ptr %src, i64 %iv
327+
%l = load i64, ptr %gep
328+
%cmp = icmp sle i64 %min.val, %l
329+
%min.val.next = tail call i64 @llvm.smax.i64(i64 %min.val, i64 %l)
330+
%min.idx.next = select i1 %cmp, i64 %iv, i64 %min.idx
331+
%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
334+
335+
exit:
336+
%res = phi i64 [ %min.idx.next, %loop ]
337+
ret i64 %res
338+
}

0 commit comments

Comments
 (0)