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 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 poison, 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-NEXT: lgfrl %r3, idx 70 // CHECK-ASM-NEXT: lgrl %r4, cptrd 71 // CHECK-ASM-NEXT: vl %v0, 0(%r3,%r4){{$}} 72 // CHECK-ASM-NEXT: vst 73 74 vd = vec_xld2(idx, cptrd); 75 // CHECK-ASM-NEXT: lgfrl %r3, idx 76 // CHECK-ASM-NEXT: lgrl %r4, cptrd 77 // CHECK-ASM-NEXT: vl %v0, 0(%r3,%r4){{$}} 78 // CHECK-ASM-NEXT: vst 79 80 vec_xst(vd, idx, ptrd); 81 // CHECK-ASM-NEXT: vl 82 // CHECK-ASM-NEXT: lgfrl %r3, idx 83 // CHECK-ASM-NEXT: lgrl %r4, ptrd 84 // CHECK-ASM-NEXT: vst %v0, 0(%r3,%r4){{$}} 85 86 vec_xstd2(vd, idx, ptrd); 87 // CHECK-ASM-NEXT: vl 88 // CHECK-ASM-NEXT: lgfrl %r3, idx 89 // CHECK-ASM-NEXT: lgrl %r4, ptrd 90 // CHECK-ASM-NEXT: vst %v0, 0(%r3,%r4){{$}} 91 92 vd = vec_splat(vd, 0); 93 // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> zeroinitializer 94 // CHECK-ASM: vrepg 95 vd = vec_splat(vd, 1); 96 // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> <i32 1, i32 1> 97 // CHECK-ASM: vrepg 98 99 vd = vec_splats(d); 100 // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> poison, <2 x i32> zeroinitializer 101 // CHECK-ASM: vlrepg 102 103 vd = vec_mergeh(vd, vd); 104 // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> <i32 0, i32 2> 105 // CHECK-ASM: vmrhg 106 107 vd = vec_mergel(vd, vd); 108 // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <i32 1, i32 3> 109 // CHECK-ASM: vmrlg 110 } 111 112 void test_compare(void) { 113 // CHECK-ASM-LABEL: test_compare 114 115 vbl = vec_cmpeq(vd, vd); 116 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmp.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"oeq", metadata !{{.*}}) 117 // CHECK-ASM: vfcedb 118 119 vbl = vec_cmpge(vd, vd); 120 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"oge", metadata !{{.*}}) 121 // CHECK-ASM: kdbr 122 // CHECK-ASM: kdbr 123 // CHECK-ASM: vst 124 125 vbl = vec_cmpgt(vd, vd); 126 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"ogt", metadata !{{.*}}) 127 // CHECK-ASM: kdbr 128 // CHECK-ASM: kdbr 129 // CHECK-ASM: vst 130 131 vbl = vec_cmple(vd, vd); 132 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"ole", metadata !{{.*}}) 133 // CHECK-ASM: kdbr 134 // CHECK-ASM: kdbr 135 // CHECK-ASM: vst 136 137 vbl = vec_cmplt(vd, vd); 138 // CHECK: call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !"olt", metadata !{{.*}}) 139 // CHECK-ASM: kdbr 140 // CHECK-ASM: kdbr 141 // CHECK-ASM: vst 142 143 idx = vec_all_lt(vd, vd); 144 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 145 // CHECK-ASM: vfchdbs 146 147 idx = vec_all_nge(vd, vd); 148 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 149 // CHECK-ASM: vfchedbs 150 idx = vec_all_ngt(vd, vd); 151 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 152 // CHECK-ASM: vfchdbs 153 idx = vec_all_nle(vd, vd); 154 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 155 // CHECK-ASM: vfchedbs 156 idx = vec_all_nlt(vd, vd); 157 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 158 // CHECK-ASM: vfchdbs 159 160 idx = vec_all_nan(vd); 161 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) 162 // CHECK-ASM: vftcidb 163 idx = vec_all_numeric(vd); 164 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) 165 // CHECK-ASM: vftcidb 166 167 idx = vec_any_eq(vd, vd); 168 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 169 // CHECK-ASM: vfcedbs 170 171 idx = vec_any_ne(vd, vd); 172 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 173 // CHECK-ASM: vfcedbs 174 175 idx = vec_any_ge(vd, vd); 176 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 177 // CHECK-ASM: vfchedbs 178 179 idx = vec_any_gt(vd, vd); 180 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 181 // CHECK-ASM: vfchdbs 182 183 idx = vec_any_le(vd, vd); 184 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 185 // CHECK-ASM: vfchedbs 186 187 idx = vec_any_lt(vd, vd); 188 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 189 // CHECK-ASM: vfchdbs 190 191 idx = vec_any_nge(vd, vd); 192 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 193 // CHECK-ASM: vfchedbs 194 idx = vec_any_ngt(vd, vd); 195 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 196 // CHECK-ASM: vfchdbs 197 idx = vec_any_nle(vd, vd); 198 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 199 // CHECK-ASM: vfchedbs 200 idx = vec_any_nlt(vd, vd); 201 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}}) 202 // CHECK-ASM: vfchdbs 203 204 idx = vec_any_nan(vd); 205 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) 206 // CHECK-ASM: vftcidb 207 idx = vec_any_numeric(vd); 208 // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15) 209 // CHECK-ASM: vftcidb 210 } 211 212 void test_float(void) { 213 // CHECK-ASM-LABEL: test_float 214 215 vd = vec_abs(vd); 216 // CHECK: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) 217 // CHECK-ASM: vflpdb 218 219 vd = vec_nabs(vd); 220 // CHECK: [[ABS:%[^ ]+]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}}) 221 // CHECK-NEXT: fneg <2 x double> [[ABS]] 222 // CHECK-ASM: vflndb 223 224 vd = vec_madd(vd, vd, vd); 225 // CHECK: call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}, metadata !{{.*}}) 226 // CHECK-ASM: vfmadb 227 vd = vec_msub(vd, vd, vd); 228 // CHECK: [[NEG:%[^ ]+]] = fneg <2 x double> %{{.*}} 229 // CHECK: call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]], metadata !{{.*}}) 230 // CHECK-ASM: vfmsdb 231 vd = vec_sqrt(vd); 232 // CHECK: call <2 x double> @llvm.experimental.constrained.sqrt.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 233 // CHECK-ASM: vfsqdb 234 235 vd = vec_ld2f(cptrf); 236 // CHECK: [[VAL:%[^ ]+]] = load <2 x float>, <2 x float>* %{{.*}} 237 // CHECK: call <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f32(<2 x float> [[VAL]], metadata !{{.*}}) 238 // (emulated) 239 vec_st2f(vd, ptrf); 240 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x float> @llvm.experimental.constrained.fptrunc.v2f32.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 241 // CHECK: store <2 x float> [[VAL]], <2 x float>* %{{.*}} 242 // (emulated) 243 244 vd = vec_ctd(vsl, 0); 245 // CHECK: call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}}) 246 // (emulated) 247 vd = vec_ctd(vul, 0); 248 // CHECK: call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}}) 249 // (emulated) 250 vd = vec_ctd(vsl, 1); 251 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.sitofp.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 5.000000e-01, double 5.000000e-01>, metadata !{{.*}}) 253 // (emulated) 254 vd = vec_ctd(vul, 1); 255 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}}) 256 // 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 !{{.*}}) 257 // (emulated) 258 vd = vec_ctd(vsl, 31); 259 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}}) 260 // CHECK: call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> [[VAL]], <2 x double> <double 0x3E00000000000000, double 0x3E00000000000000>, metadata !{{.*}}) 261 // (emulated) 262 vd = vec_ctd(vul, 31); 263 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}}) 264 // CHECK: call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> [[VAL]], <2 x double> <double 0x3E00000000000000, double 0x3E00000000000000>, metadata !{{.*}}) 265 // (emulated) 266 267 vsl = vec_ctsl(vd, 0); 268 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 269 // (emulated) 270 vul = vec_ctul(vd, 0); 271 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 272 // (emulated) 273 vsl = vec_ctsl(vd, 1); 274 // 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 !{{.*}}) 275 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}}) 276 // (emulated) 277 vul = vec_ctul(vd, 1); 278 // 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 !{{.*}}) 279 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}}) 280 // (emulated) 281 vsl = vec_ctsl(vd, 31); 282 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> %{{.*}}, <2 x double> <double 0x41E0000000000000, double 0x41E0000000000000>, metadata !{{.*}}) 283 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}}) 284 // (emulated) 285 vul = vec_ctul(vd, 31); 286 // CHECK: [[VAL:%[^ ]+]] = tail call <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double> %{{.*}}, <2 x double> <double 0x41E0000000000000, double 0x41E0000000000000>, metadata !{{.*}}) 287 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> [[VAL]], metadata !{{.*}}) 288 // (emulated) 289 290 vd = vec_double(vsl); 291 // CHECK: call <2 x double> @llvm.experimental.constrained.sitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}}) 292 // CHECK-ASM: vcdgb 293 vd = vec_double(vul); 294 // CHECK: call <2 x double> @llvm.experimental.constrained.uitofp.v2f64.v2i64(<2 x i64> %{{.*}}, metadata !{{.*}}) 295 // CHECK-ASM: vcdlgb 296 297 vsl = vec_signed(vd); 298 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptosi.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 299 // CHECK-ASM: vcgdb 300 vul = vec_unsigned(vd); 301 // CHECK: call <2 x i64> @llvm.experimental.constrained.fptoui.v2i64.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 302 // CHECK-ASM: vclgdb 303 304 vd = vec_roundp(vd); 305 // CHECK: call <2 x double> @llvm.experimental.constrained.ceil.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 306 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6 307 vd = vec_ceil(vd); 308 // CHECK: call <2 x double> @llvm.experimental.constrained.ceil.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 309 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 6 310 vd = vec_roundm(vd); 311 // CHECK: call <2 x double> @llvm.experimental.constrained.floor.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 312 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7 313 vd = vec_floor(vd); 314 // CHECK: call <2 x double> @llvm.experimental.constrained.floor.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 315 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 7 316 vd = vec_roundz(vd); 317 // CHECK: call <2 x double> @llvm.experimental.constrained.trunc.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 318 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5 319 vd = vec_trunc(vd); 320 // CHECK: call <2 x double> @llvm.experimental.constrained.trunc.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 321 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 5 322 vd = vec_roundc(vd); 323 // CHECK: call <2 x double> @llvm.experimental.constrained.nearbyint.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 324 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 4, 0 325 vd = vec_rint(vd); 326 // CHECK: call <2 x double> @llvm.experimental.constrained.rint.v2f64(<2 x double> %{{.*}}, metadata !{{.*}}) 327 // CHECK-ASM: vfidb %{{.*}}, %{{.*}}, 0, 0 328 vd = vec_round(vd); 329 } 330