From 1818d2490417fbbca8516454514e59888682f1e2 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Mon, 6 Oct 2014 19:02:20 +0000 Subject: [PATCH] [PATCH][Power] Fix (and deprecate) vec_lvsl and vec_lvsr for little endian The use of the vec_lvsl and vec_lvsr interfaces are discouraged for little endian targets since Power8 hardware is a minimum requirement, and Power8 provides reasonable performance for unaligned vector loads and stores. Up till now we have not provided "correct" (i.e., big- endian-compatible) code generation for these interfaces, as to do so produces poorly performing code. However, this has become the source of too many questions. With this patch, LLVM will now produce compatible code for these interfaces, but will also produce a deprecation warning message for PPC64LE when one of them is used. This should make the porting direction clearer to programmers. A similar patch has recently been committed to GCC. This patch includes a test for the warning message. There is a companion patch that adds two unit tests to projects/test-suite. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219137 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Headers/altivec.h | 182 ++++++++++++++++++++++++++++++++++ test/Headers/altivec-intrin.c | 18 ++++ 2 files changed, 200 insertions(+) create mode 100644 test/Headers/altivec-intrin.c diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h index f9fc64af3e..373eded482 100644 --- a/lib/Headers/altivec.h +++ b/lib/Headers/altivec.h @@ -2253,91 +2253,273 @@ vec_vlogefp(vector float __a) /* vec_lvsl */ +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsl(int __a, const signed char *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const signed char *__b) { return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsl(int __a, const unsigned char *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const unsigned char *__b) { return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsl(int __a, const short *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const short *__b) { return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsl(int __a, const unsigned short *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const unsigned short *__b) { return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsl(int __a, const int *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const int *__b) { return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsl(int __a, const unsigned int *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const unsigned int *__b) { return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsl(int __a, const float *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsl(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsl(int __a, const float *__b) { return (vector unsigned char)__builtin_altivec_lvsl(__a, __b); } +#endif /* vec_lvsr */ +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsr(int __a, const signed char *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const signed char *__b) { return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsr(int __a, const unsigned char *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const unsigned char *__b) { return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsr(int __a, const short *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const short *__b) { return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsr(int __a, const unsigned short *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const unsigned short *__b) { return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsr(int __a, const int *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const int *__b) { return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsr(int __a, const unsigned int *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const unsigned int *__b) { return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); } +#endif +#ifdef __LITTLE_ENDIAN__ +static vector unsigned char __ATTRS_o_ai +__attribute__((deprecated("use assignment for unaligned little endian \ +loads/stores"))) +vec_lvsr(int __a, const float *__b) +{ + vector unsigned char mask = + (vector unsigned char)__builtin_altivec_lvsr(__a, __b); + vector unsigned char reverse = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; + return vec_perm(mask, mask, reverse); +} +#else static vector unsigned char __ATTRS_o_ai vec_lvsr(int __a, const float *__b) { return (vector unsigned char)__builtin_altivec_lvsr(__a, __b); } +#endif /* vec_madd */ diff --git a/test/Headers/altivec-intrin.c b/test/Headers/altivec-intrin.c new file mode 100644 index 0000000000..5ec4e9d3e7 --- /dev/null +++ b/test/Headers/altivec-intrin.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -target-cpu power8 \ +// RUN: -faltivec -verify %s + +// Test special behavior of Altivec intrinsics in this file. + +#include + +__attribute__((__aligned__(16))) float x[20]; + +int main() +{ + vector unsigned char l = vec_lvsl (0, &x[1]); // expected-warning {{is deprecated: use assignment for unaligned little endian loads/stores}} + vector unsigned char r = vec_lvsr (0, &x[1]); // expected-warning {{is deprecated: use assignment for unaligned little endian loads/stores}} +} +// 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:2374 {{deprecated here}} +// expected-note@altivec.h:2509 {{deprecated here}} -- 2.40.0