[PPC] Make altivec conversion function macros.

The second argument must be a constant, otherwise instruction selection
will fail. always_inline is not enough for isel to always fold
everything away at -O0.

Sadly the overloading turned this into a big macro mess. Fixes PR33212.

llvm-svn: 304205
This commit is contained in:
Benjamin Kramer 2017-05-30 11:37:29 +00:00
parent d8fe3eb9cb
commit c796245431
2 changed files with 129 additions and 57 deletions

View File

@ -2887,87 +2887,79 @@ static __inline__ vector double __ATTRS_o_ai vec_cpsgn(vector double __a,
/* vec_ctf */
static __inline__ vector float __ATTRS_o_ai vec_ctf(vector int __a, int __b) {
return __builtin_altivec_vcfsx(__a, __b);
}
static __inline__ vector float __ATTRS_o_ai vec_ctf(vector unsigned int __a,
int __b) {
return __builtin_altivec_vcfux((vector int)__a, __b);
}
#ifdef __VSX__
static __inline__ vector double __ATTRS_o_ai
vec_ctf(vector unsigned long long __a, int __b) {
vector double __ret = __builtin_convertvector(__a, vector double);
__ret *= (vector double)(vector unsigned long long)((0x3ffULL - __b) << 52);
return __ret;
}
static __inline__ vector double __ATTRS_o_ai
vec_ctf(vector signed long long __a, int __b) {
vector double __ret = __builtin_convertvector(__a, vector double);
__ret *= (vector double)(vector unsigned long long)((0x3ffULL - __b) << 52);
return __ret;
}
#define vec_ctf(__a, __b) \
_Generic((__a), vector int \
: (vector float)__builtin_altivec_vcfsx((__a), (__b)), \
vector unsigned int \
: (vector float)__builtin_altivec_vcfux((vector int)(__a), (__b)), \
vector unsigned long long \
: (__builtin_convertvector((vector unsigned long long)(__a), \
vector double) * \
(vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
<< 52)), \
vector signed long long \
: (__builtin_convertvector((vector signed long long)(__a), \
vector double) * \
(vector double)(vector unsigned long long)((0x3ffULL - (__b)) \
<< 52)))
#else
#define vec_ctf(__a, __b) \
_Generic((__a), vector int \
: (vector float)__builtin_altivec_vcfsx((__a), (__b)), \
vector unsigned int \
: (vector float)__builtin_altivec_vcfux((vector int)(__a), (__b)))
#endif
/* vec_vcfsx */
static __inline__ vector float __attribute__((__always_inline__))
vec_vcfsx(vector int __a, int __b) {
return __builtin_altivec_vcfsx(__a, __b);
}
#define vec_vcfux __builtin_altivec_vcfux
/* vec_vcfux */
static __inline__ vector float __attribute__((__always_inline__))
vec_vcfux(vector unsigned int __a, int __b) {
return __builtin_altivec_vcfux((vector int)__a, __b);
}
#define vec_vcfsx(__a, __b) __builtin_altivec_vcfsx((vector int)(__a), (__b))
/* vec_cts */
static __inline__ vector int __ATTRS_o_ai vec_cts(vector float __a, int __b) {
return __builtin_altivec_vctsxs(__a, __b);
}
#ifdef __VSX__
static __inline__ vector signed long long __ATTRS_o_ai
vec_cts(vector double __a, int __b) {
__a *= (vector double)(vector unsigned long long)((0x3ffULL + __b) << 52);
return __builtin_convertvector(__a, vector signed long long);
}
#define vec_cts(__a, __b) \
_Generic((__a), vector float \
: __builtin_altivec_vctsxs((__a), (__b)), vector double \
: __extension__({ \
vector double __ret = \
(__a) * \
(vector double)(vector unsigned long long)((0x3ffULL + (__b)) \
<< 52); \
__builtin_convertvector(__ret, vector signed long long); \
}))
#else
#define vec_cts __builtin_altivec_vctsxs
#endif
/* vec_vctsxs */
static __inline__ vector int __attribute__((__always_inline__))
vec_vctsxs(vector float __a, int __b) {
return __builtin_altivec_vctsxs(__a, __b);
}
#define vec_vctsxs __builtin_altivec_vctsxs
/* vec_ctu */
static __inline__ vector unsigned int __ATTRS_o_ai vec_ctu(vector float __a,
int __b) {
return __builtin_altivec_vctuxs(__a, __b);
}
#ifdef __VSX__
static __inline__ vector unsigned long long __ATTRS_o_ai
vec_ctu(vector double __a, int __b) {
__a *= (vector double)(vector unsigned long long)((0x3ffULL + __b) << 52);
return __builtin_convertvector(__a, vector unsigned long long);
}
#define vec_ctu(__a, __b) \
_Generic((__a), vector float \
: __builtin_altivec_vctuxs((__a), (__b)), vector double \
: __extension__({ \
vector double __ret = \
(__a) * \
(vector double)(vector unsigned long long)((0x3ffULL + __b) \
<< 52); \
__builtin_convertvector(__ret, vector unsigned long long); \
}))
#else
#define vec_ctu __builtin_altivec_vctuxs
#endif
/* vec_vctuxs */
static __inline__ vector unsigned int __attribute__((__always_inline__))
vec_vctuxs(vector float __a, int __b) {
return __builtin_altivec_vctuxs(__a, __b);
}
#define vec_vctuxs __builtin_altivec_vctuxs
/* vec_signed */

View File

@ -0,0 +1,80 @@
// RUN: %clang_cc1 -triple powerpc64le-linux-gnu -S -O0 -o - %s -target-feature +altivec -target-feature +vsx | FileCheck %s -check-prefix=CHECK -check-prefix=VSX
// RUN: %clang_cc1 -triple powerpc-linux-gnu -S -O0 -o - %s -target-feature +altivec -target-feature -vsx | FileCheck %s
#include <altivec.h>
// CHECK-LABEL: test1
// CHECK: vcfsx
vector float test1(vector int x) {
return vec_ctf(x, 0);
}
// CHECK-LABEL: test2
// CHECK: vcfux
vector float test2(vector unsigned int x) {
return vec_ctf(x, 0);
}
#ifdef __VSX__
// VSX-LABEL: test3
vector double test3(vector signed long long x) {
return vec_ctf(x, 0);
}
// VSX-LABEL: test4
vector double test4(vector unsigned long long x) {
return vec_ctf(x, 0);
}
#endif
// CHECK-LABEL: test5
// CHECK: vcfsx
vector float test5(vector int x) {
return vec_vcfsx(x, 0);
}
// CHECK-LABEL: test6
// CHECK: vcfux
vector float test6(vector unsigned int x) {
return vec_vcfux(x, 0);
}
// CHECK-LABEL: test7
// CHECK: vctsxs
vector int test7(vector float x) {
return vec_cts(x, 0);
}
#ifdef __VSX__
// VSX-LABEL: test8
vector signed long long test8(vector double x) {
return vec_cts(x, 0);
}
#endif
// CHECK-LABEL: test9
// CHECK: vctsxs
vector int test9(vector float x) {
return vec_vctsxs(x, 0);
}
// CHECK-LABEL: test10
// CHECK: vctuxs
vector unsigned test10(vector float x) {
return vec_ctu(x, 0);
}
#ifdef __VSX__
// VSX-LABEL: test11
vector unsigned long long test11(vector double x) {
return vec_ctu(x, 0);
}
#endif
// CHECK-LABEL: test12
// CHECK: vctuxs
vector unsigned test12(vector float x) {
return vec_vctuxs(x, 0);
}