From 9cfd37242c4f5b8f93bcdb4566accee79b0ece6f Mon Sep 17 00:00:00 2001 From: Kit Barton Date: Mon, 25 May 2015 15:52:45 +0000 Subject: [PATCH] This patch adds support for the vector quadword add/sub instructions introduced in POWER8. These are the Clang-related changes for http://reviews.llvm.org/D9081 vadduqm vaddeuqm vaddcuq vaddecuq vsubuqm vsubeuqm vsubcuq vsubecuq All builtins are added in altivec.h, and guarded with the POWER8_VECTOR and powerpc64 macros. http://reviews.llvm.org/D9903 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@238145 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/BuiltinsPPC.def | 6 + lib/Headers/altivec.h | 178 ++++++++++++++++++++++++++- test/CodeGen/builtins-ppc-quadword.c | 159 ++++++++++++++++++++++++ test/Headers/altivec-intrin.c | 4 +- 4 files changed, 343 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/builtins-ppc-quadword.c diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def index a916289469..57ae63e634 100644 --- a/include/clang/Basic/BuiltinsPPC.def +++ b/include/clang/Basic/BuiltinsPPC.def @@ -26,6 +26,9 @@ BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "") BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "") BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vaddeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vaddcuq, "V1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vaddecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "") BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "") @@ -33,6 +36,9 @@ BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "") BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "") BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vsubeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vsubcuq, "V1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vsubecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "") BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "") diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h index 2bce9e7653..1f8c831bb7 100644 --- a/lib/Headers/altivec.h +++ b/lib/Headers/altivec.h @@ -257,6 +257,20 @@ vec_add(vector unsigned int __a, vector bool int __b) return __a + (vector unsigned int)__b; } +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_add(vector signed __int128 __a, vector signed __int128 __b) +{ + return __a + __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_add(vector unsigned __int128 __a, vector unsigned __int128 __b) +{ + return __a + __b; +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + static vector float __ATTRS_o_ai vec_add(vector float __a, vector float __b) { @@ -395,12 +409,24 @@ vec_vaddfp(vector float __a, vector float __b) /* vec_addc */ -static vector unsigned int __attribute__((__always_inline__)) +static vector unsigned int __ATTRS_o_ai vec_addc(vector unsigned int __a, vector unsigned int __b) { return __builtin_altivec_vaddcuw(__a, __b); } +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_addc(vector signed __int128 __a, vector signed __int128 __b) { + return __builtin_altivec_vaddcuq(__a, __b); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_addc(vector unsigned __int128 __a, vector unsigned __int128 __b) { + return __builtin_altivec_vaddcuq(__a, __b); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + /* vec_vaddcuw */ static vector unsigned int __attribute__((__always_inline__)) @@ -639,6 +665,64 @@ vec_vadduws(vector unsigned int __a, vector bool int __b) return __builtin_altivec_vadduws(__a, (vector unsigned int)__b); } +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +/* vec_vadduqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vadduqm(vector signed __int128 __a, vector signed __int128 __b) +{ + return __a + __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vadduqm(vector unsigned __int128 __a, vector unsigned __int128 __b) +{ + return __a + __b; +} + +/* vec_vaddeuqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vaddeuqm(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vaddeuqm(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} + +/* vec_vaddcuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vaddcuq(vector signed __int128 __a, vector signed __int128 __b) +{ + return __builtin_altivec_vaddcuq(__a, __b); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vaddcuq(vector unsigned __int128 __a, vector unsigned __int128 __b) +{ + return __builtin_altivec_vaddcuq(__a, __b); +} + +/* vec_vaddecuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vaddecuq(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vaddecuq(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + /* vec_and */ #define __builtin_altivec_vand vec_and @@ -8531,6 +8615,20 @@ vec_sub(vector unsigned int __a, vector bool int __b) return __a - (vector unsigned int)__b; } +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_sub(vector signed __int128 __a, vector signed __int128 __b) +{ + return __a - __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_sub(vector unsigned __int128 __a, vector unsigned __int128 __b) +{ + return __a - __b; +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + static vector float __ATTRS_o_ai vec_sub(vector float __a, vector float __b) { @@ -8669,12 +8767,26 @@ vec_vsubfp(vector float __a, vector float __b) /* vec_subc */ -static vector unsigned int __attribute__((__always_inline__)) +static vector unsigned int __ATTRS_o_ai vec_subc(vector unsigned int __a, vector unsigned int __b) { return __builtin_altivec_vsubcuw(__a, __b); } +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector unsigned __int128 __ATTRS_o_ai +vec_subc(vector unsigned __int128 __a, vector unsigned __int128 __b) +{ + return __builtin_altivec_vsubcuq(__a, __b); +} + +static vector signed __int128 __ATTRS_o_ai +vec_subc(vector signed __int128 __a, vector signed __int128 __b) +{ + return __builtin_altivec_vsubcuq(__a, __b); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + /* vec_vsubcuw */ static vector unsigned int __attribute__((__always_inline__)) @@ -8913,6 +9025,68 @@ vec_vsubuws(vector unsigned int __a, vector bool int __b) return __builtin_altivec_vsubuws(__a, (vector unsigned int)__b); } +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +/* vec_vsubuqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubuqm(vector signed __int128 __a, vector signed __int128 __b) +{ + return __a - __b; +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubuqm(vector unsigned __int128 __a, vector unsigned __int128 __b) +{ + return __a - __b; +} + +/* vec_vsubeuqm */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubeuqm(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) +{ + return __builtin_altivec_vsubeuqm(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubeuqm(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) +{ + return __builtin_altivec_vsubeuqm(__a, __b, __c); +} + +/* vec_vsubcuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubcuq(vector signed __int128 __a, vector signed __int128 __b) +{ + return __builtin_altivec_vsubcuq(__a, __b); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubcuq(vector unsigned __int128 __a, vector unsigned __int128 __b) +{ + return __builtin_altivec_vsubcuq(__a, __b); +} + +/* vec_vsubecuq */ + +static vector signed __int128 __ATTRS_o_ai +vec_vsubecuq(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) +{ + return __builtin_altivec_vsubecuq(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_vsubecuq(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) +{ + return __builtin_altivec_vsubecuq(__a, __b, __c); +} +#endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) + /* vec_sum4s */ static vector int __ATTRS_o_ai diff --git a/test/CodeGen/builtins-ppc-quadword.c b/test/CodeGen/builtins-ppc-quadword.c new file mode 100644 index 0000000000..e17b6791d5 --- /dev/null +++ b/test/CodeGen/builtins-ppc-quadword.c @@ -0,0 +1,159 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -faltivec -target-feature +power8-vector \ +// RUN: -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// RUN: %clang_cc1 -faltivec -target-feature +power8-vector \ +// RUN: -triple powerpc64le-unknown-unknown -emit-llvm %s -o - \ +// RUN: | FileCheck %s -check-prefix=CHECK-LE + +// RUN: not %clang_cc1 -faltivec -triple powerpc-unknown-unknown \ +// RUN: -emit-llvm %s -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PPC + +// CHECK-PPC: error: __int128 is not supported on this target +vector signed __int128 vlll = { -1 }; +// CHECK-PPC: error: __int128 is not supported on this target +vector unsigned __int128 vulll = { 1 }; + +// CHECK-PPC: error: __int128 is not supported on this target +vector signed __int128 res_vlll; +// CHECK-PPC: error: __int128 is not supported on this target +vector unsigned __int128 res_vulll; + + +// CHECK-LABEL: define void @test1 +void test1() { + + /* vec_add */ + res_vlll = vec_add(vlll, vlll); +// CHECK: add <1 x i128> +// CHECK-LE: add <1 x i128> +// CHECK-PPC: error: call to 'vec_add' is ambiguous + + res_vulll = vec_add(vulll, vulll); +// CHECK: add <1 x i128> +// CHECK-LE: add <1 x i128> +// CHECK-PPC: error: call to 'vec_add' is ambiguous + + /* vec_vadduqm */ + res_vlll = vec_vadduqm(vlll, vlll); +// CHECK: add <1 x i128> +// CHECK-LE: add <1 x i128> +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vadduqm(vulll, vulll); +// CHECK: add <1 x i128> +// CHECK-LE: add <1 x i128> +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + + /* vec_vaddeuqm */ + res_vlll = vec_vaddeuqm(vlll, vlll, vlll); +// CHECK: @llvm.ppc.altivec.vaddeuqm +// CHECK-LE: @llvm.ppc.altivec.vaddeuqm +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vaddeuqm(vulll, vulll, vulll); +// CHECK: @llvm.ppc.altivec.vaddeuqm +// CHECK-LE: @llvm.ppc.altivec.vaddeuqm +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + + /* vec_addc */ + res_vlll = vec_addc(vlll, vlll); +// CHECK: @llvm.ppc.altivec.vaddcuq +// CHECK-LE: @llvm.ppc.altivec.vaddcuq +// KCHECK-PPC: error: call to 'vec_addc' is ambiguous + + res_vulll = vec_addc(vulll, vulll); +// CHECK: @llvm.ppc.altivec.vaddcuq +// CHECK-LE: @llvm.ppc.altivec.vaddcuq +// KCHECK-PPC: error: call to 'vec_addc' is ambiguous + + + /* vec_vaddcuq */ + res_vlll = vec_vaddcuq(vlll, vlll); +// CHECK: @llvm.ppc.altivec.vaddcuq +// CHECK-LE: @llvm.ppc.altivec.vaddcuq +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vaddcuq(vulll, vulll); +// CHECK: @llvm.ppc.altivec.vaddcuq +// CHECK-LE: @llvm.ppc.altivec.vaddcuq +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + + /* vec_vaddecuq */ + res_vlll = vec_vaddecuq(vlll, vlll, vlll); +// CHECK: @llvm.ppc.altivec.vaddecuq +// CHECK-LE: @llvm.ppc.altivec.vaddecuq +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vaddecuq(vulll, vulll, vulll); +// CHECK: @llvm.ppc.altivec.vaddecuq +// CHECK-LE: @llvm.ppc.altivec.vaddecuq +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + + /* vec_sub */ + res_vlll = vec_sub(vlll, vlll); +// CHECK: sub <1 x i128> +// CHECK-LE: sub <1 x i128> +// CHECK-PPC: error: call to 'vec_sub' is ambiguous + + res_vulll = vec_sub(vulll, vulll); +// CHECK: sub <1 x i128> +// CHECK-LE: sub <1 x i128> +// CHECK-PPC: error: call to 'vec_sub' is ambiguous + + /* vec_vsubuqm */ + res_vlll = vec_vsubuqm(vlll, vlll); +// CHECK: sub <1 x i128> +// CHECK-LE: sub <1 x i128> +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vsubuqm(vulll, vulll); +// CHECK: sub <1 x i128> +// CHECK-LE: sub <1 x i128> +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + + /* vec_vsubeuqm */ + res_vlll = vec_vsubeuqm(vlll, vlll, vlll); +// CHECK: @llvm.ppc.altivec.vsubeuqm +// CHECK-LE: @llvm.ppc.altivec.vsubeuqm +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vsubeuqm(vulll, vulll, vulll); +// CHECK: @llvm.ppc.altivec.vsubeuqm +// CHECK-LE: @llvm.ppc.altivec.vsubeuqm +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + + /* vec_subc */ + res_vlll = vec_subc(vlll, vlll); +// CHECK: @llvm.ppc.altivec.vsubcuq +// CHECK-LE: @llvm.ppc.altivec.vsubcuq +// KCHECK-PPC: error: call to 'vec_subc' is ambiguous + + res_vulll = vec_subc(vulll, vulll); +// CHECK: @llvm.ppc.altivec.vsubcuq +// CHECK-LE: @llvm.ppc.altivec.vsubcuq +// KCHECK-PPC: error: call to 'vec_subc' is ambiguous + + /* vec_vsubcuq */ + res_vlll = vec_vsubcuq(vlll, vlll); +// CHECK: @llvm.ppc.altivec.vsubcuq +// CHECK-LE: @llvm.ppc.altivec.vsubcuq +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vsubcuq(vulll, vulll); +// CHECK: @llvm.ppc.altivec.vsubcuq +// CHECK-LE: @llvm.ppc.altivec.vsubcuq +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + + /* vec_vsubecuq */ + res_vlll = vec_vsubecuq(vlll, vlll, vlll); +// CHECK: @llvm.ppc.altivec.vsubecuq +// CHECK-LE: @llvm.ppc.altivec.vsubecuq +// CHECK-PPC: error: assigning to '__vector __int128' (vector of 1 '__int128' value) from incompatible type 'int' + + res_vulll = vec_vsubecuq(vulll, vulll, vulll); +// CHECK: @llvm.ppc.altivec.vsubecuq +// CHECK-LE: @llvm.ppc.altivec.vsubecuq +// CHECK-PPC: error: assigning to '__vector unsigned __int128' (vector of 1 'unsigned __int128' value) from incompatible type 'int' + +} diff --git a/test/Headers/altivec-intrin.c b/test/Headers/altivec-intrin.c index a732b6772d..1577d7e566 100644 --- a/test/Headers/altivec-intrin.c +++ b/test/Headers/altivec-intrin.c @@ -14,5 +14,5 @@ int main() } // FIXME: As noted in ms-intrin.cpp, it would be nice if we didn't have to // hard-code the line number from altivec.h here. -// expected-note@altivec.h:2430 {{deprecated here}} -// expected-note@altivec.h:2565 {{deprecated here}} +// expected-note@altivec.h:2514 {{deprecated here}} +// expected-note@altivec.h:2649 {{deprecated here}} -- 2.40.0