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