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

llvm-svn: 238145
This commit is contained in:
Kit Barton 2015-05-25 15:52:45 +00:00
parent 6646033e6e
commit 5944ee2179
4 changed files with 343 additions and 4 deletions

View File

@ -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", "")

View File

@ -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

View File

@ -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'
}

View File

@ -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}}