diff --git a/clang/lib/Headers/altivec.h b/clang/lib/Headers/altivec.h --- a/clang/lib/Headers/altivec.h +++ b/clang/lib/Headers/altivec.h @@ -3055,6 +3055,23 @@ /* vec_ctf */ #ifdef __VSX__ +// There are some functions that have different signatures with the XL compiler +// from those in Clang/GCC and documented in the PVIPR. This macro ensures that +// the XL-compatible signatures are used for those functions. +#ifdef __XL_COMPAT_ALTIVEC__ +#define vec_ctf(__a, __b) \ + _Generic((__a), vector int \ + : (vector float)__builtin_altivec_vcfsx((vector int)(__a), (__b)), \ + vector unsigned int \ + : (vector float)__builtin_altivec_vcfux((vector unsigned int)(__a), \ + (__b)), \ + vector unsigned long long \ + : (__builtin_vsx_xvcvuxdsp((vector unsigned long long)(__a)) * \ + (vector float)(vector unsigned)((0x7f - (__b)) << 23)), \ + vector signed long long \ + : (__builtin_vsx_xvcvsxdsp((vector signed long long)(__a)) * \ + (vector float)(vector unsigned)((0x7f - (__b)) << 23))) +#else // __XL_COMPAT_ALTIVEC__ #define vec_ctf(__a, __b) \ _Generic((__a), vector int \ : (vector float)__builtin_altivec_vcfsx((vector int)(__a), (__b)), \ @@ -3071,6 +3088,7 @@ vector double) * \ (vector double)(vector unsigned long long)((0x3ffULL - (__b)) \ << 52))) +#endif // __XL_COMPAT_ALTIVEC__ #else #define vec_ctf(__a, __b) \ _Generic((__a), vector int \ @@ -3113,6 +3131,19 @@ /* vec_cts */ #ifdef __VSX__ +#ifdef __XL_COMPAT_ALTIVEC__ +#define vec_cts(__a, __b) \ + _Generic((__a), vector float \ + : __builtin_altivec_vctsxs((vector float)(__a), (__b)), \ + vector double \ + : __extension__({ \ + vector double __ret = \ + (vector double)(__a) * \ + (vector double)(vector unsigned long long)((0x3ffULL + (__b)) \ + << 52); \ + __builtin_vsx_xvcvdpsxws(__ret); \ + })) +#else // __XL_COMPAT_ALTIVEC__ #define vec_cts(__a, __b) \ _Generic((__a), vector float \ : __builtin_altivec_vctsxs((vector float)(__a), (__b)), \ @@ -3124,6 +3155,7 @@ << 52); \ __builtin_convertvector(__ret, vector signed long long); \ })) +#endif // __XL_COMPAT_ALTIVEC__ #else #define vec_cts __builtin_altivec_vctsxs #endif @@ -3135,6 +3167,19 @@ /* vec_ctu */ #ifdef __VSX__ +#ifdef __XL_COMPAT_ALTIVEC__ +#define vec_ctu(__a, __b) \ + _Generic((__a), vector float \ + : __builtin_altivec_vctuxs((vector float)(__a), (__b)), \ + vector double \ + : __extension__({ \ + vector double __ret = \ + (vector double)(__a) * \ + (vector double)(vector unsigned long long)((0x3ffULL + __b) \ + << 52); \ + __builtin_vsx_xvcvdpuxws(__ret); \ + })) +#else // __XL_COMPAT_ALTIVEC__ #define vec_ctu(__a, __b) \ _Generic((__a), vector float \ : __builtin_altivec_vctuxs((vector float)(__a), (__b)), \ @@ -3146,6 +3191,7 @@ << 52); \ __builtin_convertvector(__ret, vector unsigned long long); \ })) +#endif // __XL_COMPAT_ALTIVEC__ #else #define vec_ctu __builtin_altivec_vctuxs #endif diff --git a/clang/test/CodeGen/builtins-ppc-xlcompat.c b/clang/test/CodeGen/builtins-ppc-xlcompat.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-xlcompat.c @@ -0,0 +1,41 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \ +// RUN: -triple powerpc64-unknown-unknown -emit-llvm %s -o - \ +// RUN: -D__XL_COMPAT_ALTIVEC__ -target-cpu pwr7 | FileCheck %s +// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \ +// RUN: -triple powerpc64le-unknown-unknown -emit-llvm %s -o - \ +// RUN: -D__XL_COMPAT_ALTIVEC__ -target-cpu pwr8 | FileCheck %s +#include +vector double vd = { 3.4e22, 1.8e-3 }; +vector signed long long vsll = { -12345678999ll, 12345678999 }; +vector unsigned long long vull = { 11547229456923630743llu, 18014402265226391llu }; +vector float res_vf; +vector signed int res_vsi; +vector unsigned int res_vui; + +void test() { +// CHECK-LABEL: @test( +// CHECK-NEXT: entry: +// CHECK-LE-LABEL: @test( +// CHECK-LE-NEXT: entry: + + res_vf = vec_ctf(vsll, 4); +// CHECK: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* @vsll, align 16 +// CHECK-NEXT: [[TMP1:%.*]] = call <4 x float> @llvm.ppc.vsx.xvcvsxdsp(<2 x i64> [[TMP0]]) +// CHECK-NEXT: fmul <4 x float> [[TMP1]], + + res_vf = vec_ctf(vull, 4); +// CHECK: [[TMP2:%.*]] = load <2 x i64>, <2 x i64>* @vull, align 16 +// CHECK-NEXT: [[TMP3:%.*]] = call <4 x float> @llvm.ppc.vsx.xvcvuxdsp(<2 x i64> [[TMP2]]) +// CHECK-NEXT: fmul <4 x float> [[TMP3]], + + res_vsi = vec_cts(vd, 4); +// CHECK: [[TMP4:%.*]] = load <2 x double>, <2 x double>* @vd, align 16 +// CHECK-NEXT: fmul <2 x double> [[TMP4]], +// CHECK: call <4 x i32> @llvm.ppc.vsx.xvcvdpsxws(<2 x double> + + res_vui = vec_ctu(vd, 4); +// CHECK: [[TMP8:%.*]] = load <2 x double>, <2 x double>* @vd, align 16 +// CHECK-NEXT: fmul <2 x double> [[TMP8]], +// CHECK: call <4 x i32> @llvm.ppc.vsx.xvcvdpuxws(<2 x double> +}