1 // REQUIRES: systemz-registered-target
2 // RUN: %clang_cc1 -target-cpu z13 -triple s390x-linux-gnu \
3 // RUN: -O2 -fzvector -flax-vector-conversions=none \
4 // RUN: -ffp-exception-behavior=strict \
5 // RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
6 // RUN: %clang_cc1 -target-cpu z13 -triple s390x-linux-gnu \
7 // RUN: -O2 -fzvector -flax-vector-conversions=none \
8 // RUN: -ffp-exception-behavior=strict \
9 // RUN: -Wall -Wno-unused -Werror -S %s -o - | FileCheck %s --check-prefix=CHECK-ASM
10
11 #include <vecintrin.h>
12
13 volatile vector signed long long vsl;
14 volatile vector unsigned long long vul;
15 volatile vector bool long long vbl;
16 volatile vector double vd;
17
18 volatile double d;
19
20 const float * volatile cptrf;
21 const double * volatile cptrd;
22
23 float * volatile ptrf;
24 double * volatile ptrd;
25
26 volatile int idx;
27
test_core(void)28 void test_core(void) {
29 // CHECK-ASM-LABEL: test_core
30
31 d = vec_extract(vd, idx);
32 // CHECK: extractelement <2 x double> %{{.*}}, i32 %{{.*}}
33 // CHECK-ASM: vlgvg
34
35 vd = vec_insert(d, vd, idx);
36 // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 %{{.*}}
37 // CHECK-ASM: vlvgg
38
39 vd = vec_promote(d, idx);
40 // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 %{{.*}}
41 // CHECK-ASM: vlvgg
42
43 vd = vec_insert_and_zero(cptrd);
44 // CHECK: [[ZVEC:%[^ ]+]] = insertelement <2 x double> <double undef, double 0.000000e+00>, double {{.*}}, i32 0
45 // CHECK-ASM: vllezg
46
47 vd = vec_revb(vd);
48 // CHECK-ASM: vperm
49
50 vd = vec_reve(vd);
51 // CHECK-ASM: {{vperm|vpdi}}
52
53 vd = vec_sel(vd, vd, vul);
54 // CHECK-ASM: vsel
55 vd = vec_sel(vd, vd, vbl);
56 // CHECK-ASM: vsel
57
58 vd = vec_gather_element(vd, vul, cptrd, 0);
59 // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 0
60 vd = vec_gather_element(vd, vul, cptrd, 1);
61 // CHECK-ASM: vgeg %{{.*}}, 0(%{{.*}},%{{.*}}), 1
62
63 vec_scatter_element(vd, vul, ptrd, 0);
64 // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 0
65 vec_scatter_element(vd, vul, ptrd, 1);
66 // CHECK-ASM: vsceg %{{.*}}, 0(%{{.*}},%{{.*}}), 1
67
68 vd = vec_xl(idx, cptrd);
69 // CHECK-ASM: vl
70
71 vd = vec_xld2(idx, cptrd);
72 // CHECK-ASM: vl
73
74 vec_xst(vd, idx, ptrd);
75 // CHECK-ASM: vst
76
77 vec_xstd2(vd, idx, ptrd);
78 // CHECK-ASM: vst
79
80 vd = vec_splat(vd, 0);
81 // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer
82 // CHECK-ASM: vrepg
83 vd = vec_splat(vd, 1);
84 // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> <i32 1, i32 1>
85 // CHECK-ASM: vrepg
86
87 vd = vec_splats(d);
88 // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer
89 // CHECK-ASM: vlrepg
90
91 vd = vec_mergeh(vd, vd);
92 // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> <i32 0, i32 2>
93 // CHECK-ASM: vmrhg
94
95 vd = vec_mergel(vd, vd);
96 // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <i32 1, i32 3>
97 // CHECK-ASM: vmrlg
98 }
99
test_compare(void)100 void test_compare(void) {
101 // CHECK-ASM-LABEL: test_compare
102
103 vbl = vec_cmpeq(vd, vd);
104 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmp.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"oeq", metadata !{{.*}})
105 // CHECK-ASM: vfcedb
106
107 vbl = vec_cmpge(vd, vd);
108 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"oge", metadata !{{.*}})
109 // CHECK-ASM: kdbr
110 // CHECK-ASM: kdbr
111 // CHECK-ASM: vst
112
113 vbl = vec_cmpgt(vd, vd);
114 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"ogt", metadata !{{.*}})
115 // CHECK-ASM: kdbr
116 // CHECK-ASM: kdbr
117 // CHECK-ASM: vst
118
119 vbl = vec_cmple(vd, vd);
120 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"ole", metadata !{{.*}})
121 // CHECK-ASM: kdbr
122 // CHECK-ASM: kdbr
123 // CHECK-ASM: vst
124
125 vbl = vec_cmplt(vd, vd);
126 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"olt", metadata !{{.*}})
127 // CHECK-ASM: kdbr
128 // CHECK-ASM: kdbr
129 // CHECK-ASM: vst
130
131 idx = vec_all_lt(vd, vd);
132 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
133 // CHECK-ASM: vfchdbs
134
135 idx = vec_all_nge(vd, vd);
136 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
137 // CHECK-ASM: vfchedbs
138 idx = vec_all_ngt(vd, vd);
139 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
140 // CHECK-ASM: vfchdbs
141 idx = vec_all_nle(vd, vd);
142 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
143 // CHECK-ASM: vfchedbs
144 idx = vec_all_nlt(vd, vd);
145 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
146 // CHECK-ASM: vfchdbs
147
148 idx = vec_all_nan(vd);
149 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
150 // CHECK-ASM: vftcidb
151 idx = vec_all_numeric(vd);
152 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
153 // CHECK-ASM: vftcidb
154
155 idx = vec_any_eq(vd, vd);
156 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
157 // CHECK-ASM: vfcedbs
158
159 idx = vec_any_ne(vd, vd);
160 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
161 // CHECK-ASM: vfcedbs
162
163 idx = vec_any_ge(vd, vd);
164 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
165 // CHECK-ASM: vfchedbs
166
167 idx = vec_any_gt(vd, vd);
168 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
169 // CHECK-ASM: vfchdbs
170
171 idx = vec_any_le(vd, vd);
172 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
173 // CHECK-ASM: vfchedbs
174
175 idx = vec_any_lt(vd, vd);
176 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
177 // CHECK-ASM: vfchdbs
178
179 idx = vec_any_nge(vd, vd);
180 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
181 // CHECK-ASM: vfchedbs
182 idx = vec_any_ngt(vd, vd);
183 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
184 // CHECK-ASM: vfchdbs
185 idx = vec_any_nle(vd, vd);
186 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
187 // CHECK-ASM: vfchedbs
188 idx = vec_any_nlt(vd, vd);
189 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
190 // CHECK-ASM: vfchdbs
191
192 idx = vec_any_nan(vd);
193 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
194 // CHECK-ASM: vftcidb
195 idx = vec_any_numeric(vd);
196 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
197 // CHECK-ASM: vftcidb
198 }
199
test_float(void)200 void test_float(void) {
201 // CHECK-ASM-LABEL: test_float
202
203 vd = vec_abs(vd);
204 // CHECK: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
205 // CHECK-ASM: vflpdb
206
207 vd = vec_nabs(vd);
208 // CHECK: [[ABS:%[^ ]+]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
209 // CHECK-NEXT: fneg <2 x double> [[ABS]]
210 // CHECK-ASM: vflndb
211
212 vd = vec_madd(vd, vd, vd);
213 // CHECK: call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !{{.*}})
214 // CHECK-ASM: vfmadb
215 vd = vec_msub(vd, vd, vd);
216 // CHECK: [[NEG:%[^ ]+]] = fneg <2 x double> %{{.*}}
217 // CHECK: call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]], metadata !{{.*}})
218 // CHECK-ASM: vfmsdb
219 vd = vec_sqrt(vd);
220 // CHECK: call <2 x double> @llvm.experimental.constrained.sqrt.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
221 // CHECK-ASM: vfsqdb
222
223 vd = vec_ld2f(cptrf);
224 // CHECK: [[VAL:%[^ ]+]] = load <2 x float>, <2 x float>* %{{.*}}
225 // CHECK: call <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f32(<2 x float> [[VAL]], metadata !{{.*}})
226 // (emulated)
227 vec_st2f(vd, ptrf);
228 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x float> @llvm.experimental.constrained.fptrunc.v2f32.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
229 // CHECK: store <2 x float> [[VAL]], <2 x float>* %{{.*}}
230 // (emulated)
231
232 vd = vec_ctd(vsl, 0);
233 // CHECK: call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
234 // (emulated)
235 vd = vec_ctd(vul, 0);
236 // CHECK: call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
237 // (emulated)
238 vd = vec_ctd(vsl, 1);
239 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
240 // CHECK: call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> [[VAL]], <2 x double> <double 5.000000e-01, double 5.000000e-01>, metadata !{{.*}})
241 // (emulated)
242 vd = vec_ctd(vul, 1);
243 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
244 // CHECK: call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> [[VAL]], <2 x double> <double 5.000000e-01, double 5.000000e-01>, metadata !{{.*}})
245 // (emulated)
246 vd = vec_ctd(vsl, 31);
247 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
248 // CHECK: call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> [[VAL]], <2 x double> <double 0x3E00000000000000, double 0x3E00000000000000>, metadata !{{.*}})
249 // (emulated)
250 vd = vec_ctd(vul, 31);
251 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
252 // CHECK: call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> [[VAL]], <2 x double> <double 0x3E00000000000000, double 0x3E00000000000000>, metadata !{{.*}})
253 // (emulated)
254
255 vsl = vec_ctsl(vd, 0);
256 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
257 // (emulated)
258 vul = vec_ctul(vd, 0);
259 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
260 // (emulated)
261 vsl = vec_ctsl(vd, 1);
262 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> {{.*}}, <2 x double> <double 2.000000e+00, double 2.000000e+00>, metadata !{{.*}})
263 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}})
264 // (emulated)
265 vul = vec_ctul(vd, 1);
266 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> %{{.*}}, <2 x double> <double 2.000000e+00, double 2.000000e+00>, metadata !{{.*}})
267 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}})
268 // (emulated)
269 vsl = vec_ctsl(vd, 31);
270 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> %{{.*}}, <2 x double> <double 0x41E0000000000000, double 0x41E0000000000000>, metadata !{{.*}})
271 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}})
272 // (emulated)
273 vul = vec_ctul(vd, 31);
274 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> %{{.*}}, <2 x double> <double 0x41E0000000000000, double 0x41E0000000000000>, metadata !{{.*}})
275 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}})
276 // (emulated)
277
278 vd = vec_double(vsl);
279 // CHECK: call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
280 // CHECK-ASM: vcdgb
281 vd = vec_double(vul);
282 // CHECK: call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}})
283 // CHECK-ASM: vcdlgb
284
285 vsl = vec_signed(vd);
286 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
287 // CHECK-ASM: vcgdb
288 vul = vec_unsigned(vd);
289 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
290 // CHECK-ASM: vclgdb
291
292 vd = vec_roundp(vd);
293 // CHECK: call <2 x double> @llvm.experimental.constrained.ceil.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
294 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6
295 vd = vec_ceil(vd);
296 // CHECK: call <2 x double> @llvm.experimental.constrained.ceil.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
297 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6
298 vd = vec_roundm(vd);
299 // CHECK: call <2 x double> @llvm.experimental.constrained.floor.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
300 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7
301 vd = vec_floor(vd);
302 // CHECK: call <2 x double> @llvm.experimental.constrained.floor.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
303 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7
304 vd = vec_roundz(vd);
305 // CHECK: call <2 x double> @llvm.experimental.constrained.trunc.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
306 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5
307 vd = vec_trunc(vd);
308 // CHECK: call <2 x double> @llvm.experimental.constrained.trunc.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
309 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5
310 vd = vec_roundc(vd);
311 // CHECK: call <2 x double> @llvm.experimental.constrained.nearbyint.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
312 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 0
313 vd = vec_rint(vd);
314 // CHECK: call <2 x double> @llvm.experimental.constrained.rint.v2f64(<2 x double> %{{.*}}, metadata !{{.*}})
315 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0
316 vd = vec_round(vd);
317 }
318