The RTL expansion code for CTORs doesn't handle VECTOR_BOOLEAN_TYPE_P with bit-precision elements correctly as the testcase shows before the PR97085 fix. The following makes it do the correct thing (not 100% sure for CTOR of sub-vectors due to the lack of a testcase).
The alternative would be to assert such CTORs do not happen (and also add IL verification for this). The GIMPLE FE needs a way to declare the VECTOR_BOOLEAN_TYPE_P vectors (thus the C FE needs that), thus test coverage is quite limited (zero) now and I didn't manage to convince GCC to create such CTOR for SVE VnBImode vectors. Bootstrapped and tested on x86_64-unknown-linux-gnu. Does this look sensible? Thanks, Richard. 2020-09-25 Richard Biener <rguent...@suse.de> PR middle-end/96814 * expr.c (store_constructor): Handle VECTOR_BOOLEAN_TYPE_P CTORs correctly. * gcc.target/i386/pr96814.c: New testcase. --- gcc/expr.c | 28 ++++++++++++++++++------- gcc/testsuite/gcc.target/i386/pr96814.c | 19 +++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr96814.c diff --git a/gcc/expr.c b/gcc/expr.c index 1a15f24b397..fb42e485089 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6922,7 +6922,9 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, insn_code icode = CODE_FOR_nothing; tree elt; tree elttype = TREE_TYPE (type); - int elt_size = tree_to_uhwi (TYPE_SIZE (elttype)); + int elt_size + = (VECTOR_BOOLEAN_TYPE_P (type) ? TYPE_PRECISION (elttype) + : tree_to_uhwi (TYPE_SIZE (elttype))); machine_mode eltmode = TYPE_MODE (elttype); HOST_WIDE_INT bitsize; HOST_WIDE_INT bitpos; @@ -6987,6 +6989,23 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, } } + /* Compute the size of the elements in the CTOR. */ + tree val_type = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value); + if (VECTOR_BOOLEAN_TYPE_P (type)) + { + if (VECTOR_TYPE_P (val_type)) + { + /* ??? Never seen such beast, but it's not disallowed. */ + gcc_assert (VECTOR_BOOLEAN_TYPE_P (val_type)); + bitsize = (TYPE_PRECISION (TREE_TYPE (val_type)) + * TYPE_VECTOR_SUBPARTS (val_type).to_constant ()); + } + else + bitsize = TYPE_PRECISION (val_type); + } + else + bitsize = tree_to_uhwi (TYPE_SIZE (val_type)); + /* If the constructor has fewer elements than the vector, clear the whole array first. Similarly if this is static constructor of a non-BLKmode object. */ @@ -7001,11 +7020,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) { - tree sz = TYPE_SIZE (TREE_TYPE (value)); - int n_elts_here - = tree_to_uhwi (int_const_binop (TRUNC_DIV_EXPR, sz, - TYPE_SIZE (elttype))); - + int n_elts_here = bitsize / elt_size; count += n_elts_here; if (mostly_zeros_p (value)) zero_count += n_elts_here; @@ -7045,7 +7060,6 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, HOST_WIDE_INT eltpos; tree value = ce->value; - bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (value))); if (cleared && initializer_zerop (value)) continue; diff --git a/gcc/testsuite/gcc.target/i386/pr96814.c b/gcc/testsuite/gcc.target/i386/pr96814.c new file mode 100644 index 00000000000..b280c737130 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr96814.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-mavx512vl -mavx512bw" } */ +/* { dg-require-effective-target avx512bw } */ +/* { dg-require-effective-target avx512vl } */ + +typedef unsigned char __attribute__ ((__vector_size__ (32))) V; + +void +test (void) +{ + V x = ((V){8} > 0) == 0; + for (unsigned i = 0; i < sizeof (x); i++) + if (x[i] != (i ? 0xff : 0)) __builtin_abort(); +} + +#define DO_TEST test +#define AVX512VL +#define AVX512BW +#include "avx512-check.h" -- 2.26.2