From 1ff93618e58df210def48d26878c20a1b414d900 Mon Sep 17 00:00:00 2001 From: Nemanja Ivanovic Date: Mon, 1 Mar 2021 21:38:41 -0600 Subject: [PATCH] [PowerPC] Add missing overloads of vec_promote to altivec.h The VSX-only overloads (for 8-byte element vectors) are missing. Add the missing overloads and convert element numbering to modulo arithmetic to match GCC and XLC. --- clang/lib/Headers/altivec.h | 36 +++++++++++++++++++++------ clang/test/CodeGen/builtins-ppc-vsx.c | 19 ++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h index 402f3b389496..935eac3c8672 100644 --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -14024,49 +14024,71 @@ static __inline__ void __ATTRS_o_ai vec_stvrxl(vector float __a, int __b, static __inline__ vector signed char __ATTRS_o_ai vec_promote(signed char __a, int __b) { vector signed char __res = (vector signed char)(0); - __res[__b] = __a; + __res[__b & 0x7] = __a; return __res; } static __inline__ vector unsigned char __ATTRS_o_ai vec_promote(unsigned char __a, int __b) { vector unsigned char __res = (vector unsigned char)(0); - __res[__b] = __a; + __res[__b & 0x7] = __a; return __res; } static __inline__ vector short __ATTRS_o_ai vec_promote(short __a, int __b) { vector short __res = (vector short)(0); - __res[__b] = __a; + __res[__b & 0x7] = __a; return __res; } static __inline__ vector unsigned short __ATTRS_o_ai vec_promote(unsigned short __a, int __b) { vector unsigned short __res = (vector unsigned short)(0); - __res[__b] = __a; + __res[__b & 0x7] = __a; return __res; } static __inline__ vector int __ATTRS_o_ai vec_promote(int __a, int __b) { vector int __res = (vector int)(0); - __res[__b] = __a; + __res[__b & 0x3] = __a; return __res; } static __inline__ vector unsigned int __ATTRS_o_ai vec_promote(unsigned int __a, int __b) { vector unsigned int __res = (vector unsigned int)(0); - __res[__b] = __a; + __res[__b & 0x3] = __a; return __res; } static __inline__ vector float __ATTRS_o_ai vec_promote(float __a, int __b) { vector float __res = (vector float)(0); - __res[__b] = __a; + __res[__b & 0x3] = __a; return __res; } +#ifdef __VSX__ +static __inline__ vector double __ATTRS_o_ai vec_promote(double __a, int __b) { + vector double __res = (vector double)(0); + __res[__b & 0x1] = __a; + return __res; +} + +static __inline__ vector signed long long __ATTRS_o_ai +vec_promote(signed long long __a, int __b) { + vector signed long long __res = (vector signed long long)(0); + __res[__b & 0x1] = __a; + return __res; +} + +static __inline__ vector unsigned long long __ATTRS_o_ai +vec_promote(unsigned long long __a, int __b) { + vector unsigned long long __res = (vector unsigned long long)(0); + __res[__b & 0x1] = __a; + return __res; +} +#endif + /* vec_splats */ static __inline__ vector signed char __ATTRS_o_ai vec_splats(signed char __a) { diff --git a/clang/test/CodeGen/builtins-ppc-vsx.c b/clang/test/CodeGen/builtins-ppc-vsx.c index bd0e66e69800..53370cb3949e 100644 --- a/clang/test/CodeGen/builtins-ppc-vsx.c +++ b/clang/test/CodeGen/builtins-ppc-vsx.c @@ -22,6 +22,7 @@ vector signed long long vsll = { 255LL, -937LL }; vector unsigned long long vull = { 1447LL, 2894LL }; double d = 23.4; signed long long sll = 618LL; +unsigned long long ull = 618ULL; float af[4] = {23.4f, 56.7f, 89.0f, 12.3f}; double ad[2] = {23.4, 56.7}; signed char asc[16] = { -8, 9, -10, 11, -12, 13, -14, 15, @@ -1851,6 +1852,24 @@ res_vsc = vec_xxsldwi(vsc, vsc, 0); res_vuc = vec_xxsldwi(vuc, vuc, 1); // CHECK: shufflevector <4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}}, <4 x i32> // CHECK-LE: shufflevector <4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}}, <4 x i32> + +res_vd = vec_promote(d, 0); +// CHECK: store <2 x double> zeroinitializer +// CHECK: insertelement <2 x double> +// CHECK-LE: store <2 x double> zeroinitializer +// CHECK-LE: insertelement <2 x double> + +res_vsll = vec_promote(sll, 0); +// CHECK: store <2 x i64> zeroinitializer +// CHECK: insertelement <2 x i64> +// CHECK-LE: store <2 x i64> zeroinitializer +// CHECK-LE: insertelement <2 x i64> + +res_vull = vec_promote(ull, 0); +// CHECK: store <2 x i64> zeroinitializer +// CHECK: insertelement <2 x i64> +// CHECK-LE: store <2 x i64> zeroinitializer +// CHECK-LE: insertelement <2 x i64> } // The return type of the call expression may be different from the return type of the shufflevector.