Index: clang/lib/Headers/altivec.h =================================================================== --- clang/lib/Headers/altivec.h +++ clang/lib/Headers/altivec.h @@ -16881,6 +16881,76 @@ return __builtin_altivec_vctzdm(__a, __b); } +#ifdef __VSX__ + +/* vec_splati */ + +#define vec_splati(__a) \ + _Generic((__a), signed int \ + : ((vector signed int)__a), unsigned int \ + : ((vector unsigned int)__a), float \ + : ((vector float)__a)) + + +/* vec_spatid */ + +static __inline__ vector double __ATTRS_o_ai vec_splatid(const float __a) { + return ((vector double)((double)__a)); +} + +/* vec_splati_ins */ + +#ifdef __LITTLE_ENDIAN__ +static __inline__ vector signed int __ATTRS_o_ai vec_splati_ins( + vector signed int __a, const unsigned int __b, const signed int __c) { + assert((__b == 0 || __b == 1) && "The second argument must be 0 or 1"); + __a[1 - __b] = __c; + __a[3 - __b] = __c; + return __a; +} + +static __inline__ vector unsigned int __ATTRS_o_ai vec_splati_ins( + vector unsigned int __a, const unsigned int __b, const unsigned int __c) { + assert((__b == 0 || __b == 1) && "The second argument must be 0 or 1"); + __a[1 - __b] = __c; + __a[3 - __b] = __c; + return __a; +} + +static __inline__ vector float __ATTRS_o_ai +vec_splati_ins(vector float __a, const unsigned int __b, const float __c) { + assert((__b == 0 || __b == 1) && "The second argument must be 0 or 1"); + __a[1 - __b] = __c; + __a[3 - __b] = __c; + return __a; +} +#else +static __inline__ vector signed int __ATTRS_o_ai vec_splati_ins( + vector signed int __a, const unsigned int __b, const signed int __c) { + assert((__b == 0 || __b == 1) && "The second argument must be 0 or 1"); + __a[__b] = __c; + __a[2 + __b] = __c; + return __a; +} + +static __inline__ vector unsigned int __ATTRS_o_ai vec_splati_ins( + vector unsigned int __a, const unsigned int __b, const unsigned int __c) { + assert((__b == 0 || __b == 1) && "The second argument must be 0 or 1"); + __a[__b] = __c; + __a[2 + __b] = __c; + return __a; +} + +static __inline__ vector float __ATTRS_o_ai +vec_splati_ins(vector float __a, const unsigned int __b, const float __c) { + assert((__b == 0 || __b == 1) && "The second argument must be 0 or 1"); + __a[__b] = __c; + __a[2 + __b] = __c; + return __a; +} +#endif + +#endif /* __VSX__ */ #endif /* __POWER10_VECTOR__ */ #undef __ATTRS_o_ai Index: clang/test/CodeGen/builtins-ppc-p10vector.c =================================================================== --- clang/test/CodeGen/builtins-ppc-p10vector.c +++ clang/test/CodeGen/builtins-ppc-p10vector.c @@ -3,14 +3,24 @@ // RUN: -target-cpu pwr10 -triple powerpc64le-unknown-unknown -emit-llvm %s \ // RUN: -o - | FileCheck %s +// RUN: %clang_cc1 -target-feature +vsx -target-feature +altivec \ +// RUN: -target-cpu pwr10 -triple powerpc64-unknown-unknown -emit-llvm %s \ +// RUN: -o - | FileCheck %s -check-prefix=CHECK-BE + +// RUN: %clang_cc1 -target-feature +vsx -target-feature +altivec \ +// RUN: -target-cpu pwr10 -triple powerpc64le-unknown-unknown -emit-llvm %s \ +// RUN: -o - | FileCheck %s -check-prefix=CHECK-LE + #include vector signed char vsca; vector unsigned char vuca, vucb, vucc; vector unsigned short vusa, vusb, vusc; +vector signed int vsia; vector unsigned int vuia, vuib, vuic; vector unsigned long long vulla, vullb, vullc; vector unsigned __int128 vui128a, vui128b, vui128c; +vector float vfa; unsigned int uia; vector unsigned long long test_vpdepd(void) { @@ -146,3 +156,50 @@ // CHECK-NEXT: ret <2 x i64> return vec_cnttzm(vulla, vullb); } + +vector signed int test_vec_vec_splati_si(void) { + // CHECK: ret <4 x i32> + return vec_splati(-17); +} + +vector unsigned int test_vec_vec_splati_ui(void) { + // CHECK: ret <4 x i32> + return vec_splati(16U); +} + +vector float test_vec_vec_splati_f(void) { + // CHECK: ret <4 x float> + return vec_splati(1.0f); +} + +vector double test_vec_vec_splatid(void) { + // CHECK: [[T1:%.+]] = fpext float %{{.+}} to double + // CHECK-NEXT: [[T2:%.+]] = insertelement <2 x double> undef, double [[T1:%.+]], i32 0 + // CHECK-NEXT: [[T3:%.+]] = shufflevector <2 x double> [[T2:%.+]], <2 x double> undef, <2 x i32> zeroinitialize + // CHECK-NEXT: ret <2 x double> [[T3:%.+]] + return vec_splatid(1.0); +} + +vector signed int test_vec_vec_splati_ins_si(void) { + // CHECK-BE: insertelement <4 x i32> + // CHECK-BE: ret <4 x i32> + // CHECK-LE: insertelement <4 x i32> + // CHECK-LE: ret <4 x i32> + return vec_splati_ins(vsia, 0, -17); +} + +vector unsigned int test_vec_vec_splati_ins_ui(void) { + // CHECK-BE: insertelement <4 x i32> + // CHECK-BE: ret <4 x i32> + // CHECK-LE: insertelement <4 x i32> + // CHECK-LE: ret <4 x i32> + return vec_splati_ins(vuia, 0, 16U); +} + +vector float test_vec_vec_splati_ins_f(void) { + // CHECK-BE: insertelement <4 x float> + // CHECK-BE: ret <4 x float> + // CHECK-LE: insertelement <4 x float> + // CHECK-LE: ret <4 x float> + return vec_splati_ins(vfa, 0, 1.0f); +}