tcg: Remove CONFIG_VECTOR16

The comment in tcg-runtime-gvec.c about CONFIG_VECTOR16 says that
tcg-op-gvec.c has eliminated size 8 vectors, and only passes on
multiples of 16. This may have been true of the first few operations,
but is not true of all operations.

In particular, multiply, shift by scalar, and compare of 8- and 16-bit
elements are not expanded inline if host vector operations are not
supported.

For an x86_64 host that does not support AVX, this means that we will
fall back to the helper, which will attempt to use SSE instructions,
which will SEGV on an invalid 8-byte aligned memory operation.

This patch simply removes the CONFIG_VECTOR16 code and configuration
without further simplification.

Buglink: https://bugs.launchpad.net/bugs/1863508

Backports commit 43d1ccd2a02fadf3c36b46a8c31125a28864d141 from qemu
This commit is contained in:
Richard Henderson 2020-04-30 06:28:42 -04:00 committed by Lioncash
parent b358f771f6
commit 72d8af5282
2 changed files with 1 additions and 90 deletions

View file

@ -24,32 +24,6 @@
#include "tcg-gvec-desc.h" #include "tcg-gvec-desc.h"
/* Virtually all hosts support 16-byte vectors. Those that don't can emulate
* them via GCC's generic vector extension. This turns out to be simpler and
* more reliable than getting the compiler to autovectorize.
*
* In tcg-op-gvec.c, we asserted that both the size and alignment of the data
* are multiples of 16.
*
* When the compiler does not support all of the operations we require, the
* loops are written so that we can always fall back on the base types.
*/
#ifdef CONFIG_VECTOR16
typedef uint8_t vec8 __attribute__((vector_size(16)));
typedef uint16_t vec16 __attribute__((vector_size(16)));
typedef uint32_t vec32 __attribute__((vector_size(16)));
typedef uint64_t vec64 __attribute__((vector_size(16)));
typedef int8_t svec8 __attribute__((vector_size(16)));
typedef int16_t svec16 __attribute__((vector_size(16)));
typedef int32_t svec32 __attribute__((vector_size(16)));
typedef int64_t svec64 __attribute__((vector_size(16)));
#define DUP16(X) { X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X }
#define DUP8(X) { X, X, X, X, X, X, X, X }
#define DUP4(X) { X, X, X, X }
#define DUP2(X) { X, X }
#else
typedef uint8_t vec8; typedef uint8_t vec8;
typedef uint16_t vec16; typedef uint16_t vec16;
typedef uint32_t vec32; typedef uint32_t vec32;
@ -64,7 +38,6 @@ typedef int64_t svec64;
#define DUP8(X) X #define DUP8(X) X
#define DUP4(X) X #define DUP4(X) X
#define DUP2(X) X #define DUP2(X) X
#endif /* CONFIG_VECTOR16 */
static inline void clear_high(void *d, intptr_t oprsz, uint32_t desc) static inline void clear_high(void *d, intptr_t oprsz, uint32_t desc)
{ {
@ -917,13 +890,7 @@ void HELPER(gvec_sar64v)(void *d, void *a, void *b, uint32_t desc)
clear_high(d, oprsz, desc); clear_high(d, oprsz, desc);
} }
/* If vectors are enabled, the compiler fills in -1 for true. #define DO_CMP0(X) -(X)
Otherwise, we must take care of this by hand. */
#ifdef CONFIG_VECTOR16
# define DO_CMP0(X) X
#else
# define DO_CMP0(X) -(X)
#endif
#define DO_CMP1(NAME, TYPE, OP) \ #define DO_CMP1(NAME, TYPE, OP) \
void HELPER(NAME)(void *d, void *a, void *b, uint32_t desc) \ void HELPER(NAME)(void *d, void *a, void *b, uint32_t desc) \

56
qemu/configure vendored
View file

@ -1174,58 +1174,6 @@ if compile_prog "" "" ; then
int128=yes int128=yes
fi fi
########################################
# See if 16-byte vector operations are supported.
# Even without a vector unit the compiler may expand these.
# There is a bug in old GCC for PPC that crashes here.
# Unfortunately it's the system compiler for Centos 7.
cat > $TMPC << EOF
typedef unsigned char U1 __attribute__((vector_size(16)));
typedef unsigned short U2 __attribute__((vector_size(16)));
typedef unsigned int U4 __attribute__((vector_size(16)));
typedef unsigned long long U8 __attribute__((vector_size(16)));
typedef signed char S1 __attribute__((vector_size(16)));
typedef signed short S2 __attribute__((vector_size(16)));
typedef signed int S4 __attribute__((vector_size(16)));
typedef signed long long S8 __attribute__((vector_size(16)));
static U1 a1, b1;
static U2 a2, b2;
static U4 a4, b4;
static U8 a8, b8;
static S1 c1;
static S2 c2;
static S4 c4;
static S8 c8;
static int i;
void helper(void *d, void *a, int shift, int i);
void helper(void *d, void *a, int shift, int i)
{
*(U1 *)(d + i) = *(U1 *)(a + i) << shift;
*(U2 *)(d + i) = *(U2 *)(a + i) << shift;
*(U4 *)(d + i) = *(U4 *)(a + i) << shift;
*(U8 *)(d + i) = *(U8 *)(a + i) << shift;
}
int main(void)
{
a1 += b1; a2 += b2; a4 += b4; a8 += b8;
a1 -= b1; a2 -= b2; a4 -= b4; a8 -= b8;
a1 *= b1; a2 *= b2; a4 *= b4; a8 *= b8;
a1 &= b1; a2 &= b2; a4 &= b4; a8 &= b8;
a1 |= b1; a2 |= b2; a4 |= b4; a8 |= b8;
a1 ^= b1; a2 ^= b2; a4 ^= b4; a8 ^= b8;
a1 <<= i; a2 <<= i; a4 <<= i; a8 <<= i;
a1 >>= i; a2 >>= i; a4 >>= i; a8 >>= i;
c1 >>= i; c2 >>= i; c4 >>= i; c8 >>= i;
return 0;
}
EOF
vector16=no
if compile_prog "" "" ; then
vector16=yes
fi
########################################## ##########################################
# check for usable membarrier system call # check for usable membarrier system call
if test "$membarrier" = "yes"; then if test "$membarrier" = "yes"; then
@ -1564,10 +1512,6 @@ if test "$atomic64" = "yes" ; then
echo "CONFIG_ATOMIC64=y" >> $config_host_mak echo "CONFIG_ATOMIC64=y" >> $config_host_mak
fi fi
if test "$vector16" = "yes" ; then
echo "CONFIG_VECTOR16=y" >> $config_host_mak
fi
if test "$have_static_assert" = "yes" ; then if test "$have_static_assert" = "yes" ; then
echo "CONFIG_STATIC_ASSERT=y" >> $config_host_mak echo "CONFIG_STATIC_ASSERT=y" >> $config_host_mak
fi fi