Skip to content

Commit e25187b

Browse files
authored
LLVM/Test: Add vectorizing testcases for fminimumnum and fminimumnum (#133843)
Vectorizing of fminimumnum and fminimumnum have not support yet. Let's add the testcase for it now, and we will update the testcase when we support it.
1 parent ad1ca5f commit e25187b

File tree

6 files changed

+2307
-0
lines changed

6 files changed

+2307
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; FIXME: fmaximumnum/fminimumnum have no vectorizing support yet.
3+
; RUN: opt --passes=loop-vectorize --mtriple=aarch64 -mattr="+neon" -S < %s | FileCheck %s
4+
5+
define void @fmin32(ptr noundef readonly captures(none) %input1, ptr noundef readonly captures(none) %input2, ptr noundef writeonly captures(none) %output) {
6+
; CHECK-LABEL: define void @fmin32(
7+
; CHECK-SAME: ptr noundef readonly captures(none) [[INPUT1:%.*]], ptr noundef readonly captures(none) [[INPUT2:%.*]], ptr noundef writeonly captures(none) [[OUTPUT:%.*]]) #[[ATTR0:[0-9]+]] {
8+
; CHECK-NEXT: [[ENTRY:.*]]:
9+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
10+
; CHECK: [[FOR_BODY]]:
11+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
12+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4096 x float], ptr [[INPUT1]], i64 0, i64 [[INDVARS_IV]]
13+
; CHECK-NEXT: [[IN1:%.*]] = load float, ptr [[ARRAYIDX]], align 4
14+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4096 x float], ptr [[INPUT2]], i64 0, i64 [[INDVARS_IV]]
15+
; CHECK-NEXT: [[IN2:%.*]] = load float, ptr [[ARRAYIDX2]], align 4
16+
; CHECK-NEXT: [[OUT:%.*]] = tail call float @llvm.minimumnum.f32(float [[IN1]], float [[IN2]])
17+
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw [4096 x float], ptr [[OUTPUT]], i64 0, i64 [[INDVARS_IV]]
18+
; CHECK-NEXT: store float [[OUT]], ptr [[ARRAYIDX4]], align 4
19+
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
20+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 4096
21+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
22+
; CHECK: [[EXIT]]:
23+
; CHECK-NEXT: ret void
24+
;
25+
entry:
26+
br label %for.body
27+
28+
for.body:
29+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
30+
%arrayidx = getelementptr inbounds nuw [4096 x float], ptr %input1, i64 0, i64 %iv
31+
%in1 = load float, ptr %arrayidx, align 4
32+
%arrayidx2 = getelementptr inbounds nuw [4096 x float], ptr %input2, i64 0, i64 %iv
33+
%in2 = load float, ptr %arrayidx2, align 4
34+
%out = tail call float @llvm.minimumnum.f32(float %in1, float %in2)
35+
%arrayidx4 = getelementptr inbounds nuw [4096 x float], ptr %output, i64 0, i64 %iv
36+
store float %out, ptr %arrayidx4, align 4
37+
%iv.next = add nuw nsw i64 %iv, 1
38+
%exitcond.not = icmp eq i64 %iv.next, 4096
39+
br i1 %exitcond.not, label %exit, label %for.body
40+
41+
exit:
42+
ret void
43+
}
44+
45+
declare float @llvm.minimumnum.f32(float, float)
46+
47+
define void @fmax32(ptr noundef readonly captures(none) %input1, ptr noundef readonly captures(none) %input2, ptr noundef writeonly captures(none) %output) {
48+
; CHECK-LABEL: define void @fmax32(
49+
; CHECK-SAME: ptr noundef readonly captures(none) [[INPUT1:%.*]], ptr noundef readonly captures(none) [[INPUT2:%.*]], ptr noundef writeonly captures(none) [[OUTPUT:%.*]]) #[[ATTR0]] {
50+
; CHECK-NEXT: [[ENTRY:.*]]:
51+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
52+
; CHECK: [[FOR_BODY]]:
53+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
54+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4096 x float], ptr [[INPUT1]], i64 0, i64 [[INDVARS_IV]]
55+
; CHECK-NEXT: [[IN1:%.*]] = load float, ptr [[ARRAYIDX]], align 4
56+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4096 x float], ptr [[INPUT2]], i64 0, i64 [[INDVARS_IV]]
57+
; CHECK-NEXT: [[IN2:%.*]] = load float, ptr [[ARRAYIDX2]], align 4
58+
; CHECK-NEXT: [[OUT:%.*]] = tail call float @llvm.maximumnum.f32(float [[IN1]], float [[IN2]])
59+
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw [4096 x float], ptr [[OUTPUT]], i64 0, i64 [[INDVARS_IV]]
60+
; CHECK-NEXT: store float [[OUT]], ptr [[ARRAYIDX4]], align 4
61+
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
62+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 4096
63+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
64+
; CHECK: [[EXIT]]:
65+
; CHECK-NEXT: ret void
66+
;
67+
entry:
68+
br label %for.body
69+
70+
for.body:
71+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
72+
%arrayidx = getelementptr inbounds nuw [4096 x float], ptr %input1, i64 0, i64 %iv
73+
%in1 = load float, ptr %arrayidx, align 4
74+
%arrayidx2 = getelementptr inbounds nuw [4096 x float], ptr %input2, i64 0, i64 %iv
75+
%in2 = load float, ptr %arrayidx2, align 4
76+
%out = tail call float @llvm.maximumnum.f32(float %in1, float %in2)
77+
%arrayidx4 = getelementptr inbounds nuw [4096 x float], ptr %output, i64 0, i64 %iv
78+
store float %out, ptr %arrayidx4, align 4
79+
%iv.next = add nuw nsw i64 %iv, 1
80+
%exitcond.not = icmp eq i64 %iv.next, 4096
81+
br i1 %exitcond.not, label %exit, label %for.body
82+
83+
exit:
84+
ret void
85+
}
86+
87+
declare float @llvm.maximumnum.f32(float, float)
88+
89+
define void @fmin64(ptr noundef readonly captures(none) %input1, ptr noundef readonly captures(none) %input2, ptr noundef writeonly captures(none) %output) {
90+
; CHECK-LABEL: define void @fmin64(
91+
; CHECK-SAME: ptr noundef readonly captures(none) [[INPUT1:%.*]], ptr noundef readonly captures(none) [[INPUT2:%.*]], ptr noundef writeonly captures(none) [[OUTPUT:%.*]]) #[[ATTR0]] {
92+
; CHECK-NEXT: [[ENTRY:.*]]:
93+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
94+
; CHECK: [[FOR_BODY]]:
95+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
96+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4096 x double], ptr [[INPUT1]], i64 0, i64 [[INDVARS_IV]]
97+
; CHECK-NEXT: [[IN1:%.*]] = load double, ptr [[ARRAYIDX]], align 8
98+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4096 x double], ptr [[INPUT2]], i64 0, i64 [[INDVARS_IV]]
99+
; CHECK-NEXT: [[IN2:%.*]] = load double, ptr [[ARRAYIDX2]], align 8
100+
; CHECK-NEXT: [[OUT:%.*]] = tail call double @llvm.minimumnum.f64(double [[IN1]], double [[IN2]])
101+
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw [4096 x double], ptr [[OUTPUT]], i64 0, i64 [[INDVARS_IV]]
102+
; CHECK-NEXT: store double [[OUT]], ptr [[ARRAYIDX4]], align 8
103+
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
104+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 4096
105+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
106+
; CHECK: [[EXIT]]:
107+
; CHECK-NEXT: ret void
108+
;
109+
entry:
110+
br label %for.body
111+
112+
for.body:
113+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
114+
%arrayidx = getelementptr inbounds nuw [4096 x double], ptr %input1, i64 0, i64 %iv
115+
%in1 = load double, ptr %arrayidx, align 8
116+
%arrayidx2 = getelementptr inbounds nuw [4096 x double], ptr %input2, i64 0, i64 %iv
117+
%in2 = load double, ptr %arrayidx2, align 8
118+
%out = tail call double @llvm.minimumnum.f64(double %in1, double %in2)
119+
%arrayidx4 = getelementptr inbounds nuw [4096 x double], ptr %output, i64 0, i64 %iv
120+
store double %out, ptr %arrayidx4, align 8
121+
%iv.next = add nuw nsw i64 %iv, 1
122+
%exitcond.not = icmp eq i64 %iv.next, 4096
123+
br i1 %exitcond.not, label %exit, label %for.body
124+
125+
exit:
126+
ret void
127+
}
128+
129+
declare double @llvm.minimumnum.f64(double, double)
130+
131+
define void @fmax64(ptr noundef readonly captures(none) %input1, ptr noundef readonly captures(none) %input2, ptr noundef writeonly captures(none) %output) {
132+
; CHECK-LABEL: define void @fmax64(
133+
; CHECK-SAME: ptr noundef readonly captures(none) [[INPUT1:%.*]], ptr noundef readonly captures(none) [[INPUT2:%.*]], ptr noundef writeonly captures(none) [[OUTPUT:%.*]]) #[[ATTR0]] {
134+
; CHECK-NEXT: [[ENTRY:.*]]:
135+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
136+
; CHECK: [[FOR_BODY]]:
137+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
138+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4096 x double], ptr [[INPUT1]], i64 0, i64 [[INDVARS_IV]]
139+
; CHECK-NEXT: [[IN1:%.*]] = load double, ptr [[ARRAYIDX]], align 8
140+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4096 x double], ptr [[INPUT2]], i64 0, i64 [[INDVARS_IV]]
141+
; CHECK-NEXT: [[IN2:%.*]] = load double, ptr [[ARRAYIDX2]], align 8
142+
; CHECK-NEXT: [[OUT:%.*]] = tail call double @llvm.maximumnum.f64(double [[IN1]], double [[IN2]])
143+
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw [4096 x double], ptr [[OUTPUT]], i64 0, i64 [[INDVARS_IV]]
144+
; CHECK-NEXT: store double [[OUT]], ptr [[ARRAYIDX4]], align 8
145+
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
146+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 4096
147+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
148+
; CHECK: [[EXIT]]:
149+
; CHECK-NEXT: ret void
150+
;
151+
entry:
152+
br label %for.body
153+
154+
for.body:
155+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
156+
%arrayidx = getelementptr inbounds nuw [4096 x double], ptr %input1, i64 0, i64 %iv
157+
%in1 = load double, ptr %arrayidx, align 8
158+
%arrayidx2 = getelementptr inbounds nuw [4096 x double], ptr %input2, i64 0, i64 %iv
159+
%in2 = load double, ptr %arrayidx2, align 8
160+
%out = tail call double @llvm.maximumnum.f64(double %in1, double %in2)
161+
%arrayidx4 = getelementptr inbounds nuw [4096 x double], ptr %output, i64 0, i64 %iv
162+
store double %out, ptr %arrayidx4, align 8
163+
%iv.next = add nuw nsw i64 %iv, 1
164+
%exitcond.not = icmp eq i64 %iv.next, 4096
165+
br i1 %exitcond.not, label %exit, label %for.body
166+
167+
exit:
168+
ret void
169+
}
170+
171+
declare double @llvm.maximumnum.f64(double, double)
172+
173+
define void @fmin16(ptr noundef readonly captures(none) %input1, ptr noundef readonly captures(none) %input2, ptr noundef writeonly captures(none) %output) {
174+
; CHECK-LABEL: define void @fmin16(
175+
; CHECK-SAME: ptr noundef readonly captures(none) [[INPUT1:%.*]], ptr noundef readonly captures(none) [[INPUT2:%.*]], ptr noundef writeonly captures(none) [[OUTPUT:%.*]]) #[[ATTR0]] {
176+
; CHECK-NEXT: [[ENTRY:.*]]:
177+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
178+
; CHECK: [[FOR_BODY]]:
179+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
180+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4096 x half], ptr [[INPUT1]], i64 0, i64 [[INDVARS_IV]]
181+
; CHECK-NEXT: [[IN1:%.*]] = load half, ptr [[ARRAYIDX]], align 2
182+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4096 x half], ptr [[INPUT2]], i64 0, i64 [[INDVARS_IV]]
183+
; CHECK-NEXT: [[IN2:%.*]] = load half, ptr [[ARRAYIDX2]], align 2
184+
; CHECK-NEXT: [[OUT:%.*]] = tail call half @llvm.minimumnum.f16(half [[IN1]], half [[IN2]])
185+
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw [4096 x half], ptr [[OUTPUT]], i64 0, i64 [[INDVARS_IV]]
186+
; CHECK-NEXT: store half [[OUT]], ptr [[ARRAYIDX4]], align 2
187+
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
188+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 4096
189+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
190+
; CHECK: [[EXIT]]:
191+
; CHECK-NEXT: ret void
192+
;
193+
entry:
194+
br label %for.body
195+
196+
for.body:
197+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
198+
%arrayidx = getelementptr inbounds nuw [4096 x half], ptr %input1, i64 0, i64 %iv
199+
%in1 = load half, ptr %arrayidx, align 2
200+
%arrayidx2 = getelementptr inbounds nuw [4096 x half], ptr %input2, i64 0, i64 %iv
201+
%in2 = load half, ptr %arrayidx2, align 2
202+
%out = tail call half @llvm.minimumnum.f16(half %in1, half %in2)
203+
%arrayidx4 = getelementptr inbounds nuw [4096 x half], ptr %output, i64 0, i64 %iv
204+
store half %out, ptr %arrayidx4, align 2
205+
%iv.next = add nuw nsw i64 %iv, 1
206+
%exitcond.not = icmp eq i64 %iv.next, 4096
207+
br i1 %exitcond.not, label %exit, label %for.body
208+
209+
exit:
210+
ret void
211+
}
212+
213+
declare half @llvm.minimumnum.f16(half, half)
214+
215+
define void @fmax16(ptr noundef readonly captures(none) %input1, ptr noundef readonly captures(none) %input2, ptr noundef writeonly captures(none) %output) {
216+
; CHECK-LABEL: define void @fmax16(
217+
; CHECK-SAME: ptr noundef readonly captures(none) [[INPUT1:%.*]], ptr noundef readonly captures(none) [[INPUT2:%.*]], ptr noundef writeonly captures(none) [[OUTPUT:%.*]]) #[[ATTR0]] {
218+
; CHECK-NEXT: [[ENTRY:.*]]:
219+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
220+
; CHECK: [[FOR_BODY]]:
221+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
222+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [4096 x half], ptr [[INPUT1]], i64 0, i64 [[INDVARS_IV]]
223+
; CHECK-NEXT: [[IN1:%.*]] = load half, ptr [[ARRAYIDX]], align 2
224+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4096 x half], ptr [[INPUT2]], i64 0, i64 [[INDVARS_IV]]
225+
; CHECK-NEXT: [[IN2:%.*]] = load half, ptr [[ARRAYIDX2]], align 2
226+
; CHECK-NEXT: [[OUT:%.*]] = tail call half @llvm.maximumnum.f16(half [[IN1]], half [[IN2]])
227+
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw [4096 x half], ptr [[OUTPUT]], i64 0, i64 [[INDVARS_IV]]
228+
; CHECK-NEXT: store half [[OUT]], ptr [[ARRAYIDX4]], align 2
229+
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
230+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 4096
231+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
232+
; CHECK: [[EXIT]]:
233+
; CHECK-NEXT: ret void
234+
;
235+
entry:
236+
br label %for.body
237+
238+
for.body:
239+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
240+
%arrayidx = getelementptr inbounds nuw [4096 x half], ptr %input1, i64 0, i64 %iv
241+
%in1 = load half, ptr %arrayidx, align 2
242+
%arrayidx2 = getelementptr inbounds nuw [4096 x half], ptr %input2, i64 0, i64 %iv
243+
%in2 = load half, ptr %arrayidx2, align 2
244+
%out = tail call half @llvm.maximumnum.f16(half %in1, half %in2)
245+
%arrayidx4 = getelementptr inbounds nuw [4096 x half], ptr %output, i64 0, i64 %iv
246+
store half %out, ptr %arrayidx4, align 2
247+
%iv.next = add nuw nsw i64 %iv, 1
248+
%exitcond.not = icmp eq i64 %iv.next, 4096
249+
br i1 %exitcond.not, label %exit, label %for.body
250+
251+
exit:
252+
ret void
253+
}
254+
255+
declare half @llvm.maximumnum.f16(half, half)

0 commit comments

Comments
 (0)