Richard Biener <[email protected]> writes:
> 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 <[email protected]>
>
> 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)));
FWIW, we now have vector_element_bits for this.
> 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));
> +
What do we allow for non-boolean constructors. E.g. for:
v2hi = 0xf001;
do we allow the CONSTRUCTOR to be { 0xf001 }? Is the type of an
initialiser value allowed to be arbitrarily different from the type
of the elements being initialised?
Or is there requirement that (say) each constructor element is either:
- a scalar that initialises one element of the constructed vector
- a vector of N elements that initialises N elements of the constructed vector
?
Like you say, it mostly seems like guesswork how booleans would be
handled here, but personally I don't know the answer for non-booleans
either :-)
Thanks,
Richard