On Mon, 9 Dec 2024, Tamar Christina wrote:
> > > if (need_to_clear && maybe_gt (size, 0) && !vector)
> > > @@ -8058,9 +8058,9 @@ store_constructor (tree exp, rtx target, int
> > > cleared,
> > poly_int64 size,
> > > element of TARGET, determined by counting the elements. */
> > > for (idx = 0, i = 0;
> > > vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
> > > - idx++, i += bitsize / elt_size)
> > > + idx++, i += exact_div (bitsize, elt_size))
> > > {
> > > - HOST_WIDE_INT eltpos;
> > > + poly_int64 eltpos;
> > > tree value = ce->value;
> >
> > That seems incomplete. We also have
> >
> > if (ce->index)
> > eltpos = tree_to_uhwi (ce->index);
> > else
> > eltpos = i;
> >
> > which should use tree_to_poly_int64 then? And if .to_constant () below
> > works,
> > why not use constant_multiple_p instead of exact_div?
> >
> > It seems to me the code interweaves two cases with multi-exclusive
> > conditions
> > where only one is expected to have poly-ints but the changes make sure to
> > obfuscate this even more ...
> >
> > Note we have GIMPLE verification that vector CTOR have no holes and no
> > or incrementing INTEGER_CST indices unless the components are vectors
> > themselves in which case the CTOR has to be full and CTOR_NELTS *
> > subparts of element
> > should be known_eq to subparts of the CTOR vector type.
> >
>
> Done,
OK.
Thanks,
Richard.
> gcc/ChangeLog:
>
> PR target/96342
> * expr.cc (store_constructor): Enable poly_{u}int64 type usage.
> (get_inner_reference): Ditto.
>
> Co-authored-by: Tamar Christina <[email protected]>
>
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> -m32, -m64 and no issues.
>
> Ok for master?
>
> Thanks,
> Tamar
>
> -- inline copy of patch --
>
> diff --git a/gcc/expr.cc b/gcc/expr.cc
> index
> 980ac415cfc7e2f7cf666637e756f857758688fc..4c6039c6608c0d9db3d1796eeab2129cb844433f
> 100644
> --- a/gcc/expr.cc
> +++ b/gcc/expr.cc
> @@ -7901,15 +7901,14 @@ store_constructor (tree exp, rtx target, int cleared,
> poly_int64 size,
> {
> unsigned HOST_WIDE_INT idx;
> constructor_elt *ce;
> - int i;
> bool need_to_clear;
> insn_code icode = CODE_FOR_nothing;
> tree elt;
> tree elttype = TREE_TYPE (type);
> int elt_size = vector_element_bits (type);
> machine_mode eltmode = TYPE_MODE (elttype);
> - HOST_WIDE_INT bitsize;
> - HOST_WIDE_INT bitpos;
> + poly_int64 bitsize;
> + poly_int64 bitpos;
> rtvec vector = NULL;
> poly_uint64 n_elts;
> unsigned HOST_WIDE_INT const_n_elts;
> @@ -8006,7 +8005,7 @@ store_constructor (tree exp, rtx target, int cleared,
> poly_int64 size,
> ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)
> : elttype);
> if (VECTOR_TYPE_P (val_type))
> - bitsize = tree_to_uhwi (TYPE_SIZE (val_type));
> + bitsize = tree_to_poly_uint64 (TYPE_SIZE (val_type));
> else
> bitsize = elt_size;
>
> @@ -8019,12 +8018,12 @@ store_constructor (tree exp, rtx target, int cleared,
> poly_int64 size,
> need_to_clear = true;
> else
> {
> - unsigned HOST_WIDE_INT count = 0, zero_count = 0;
> + poly_uint64 count = 0, zero_count = 0;
> tree value;
>
> FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
> {
> - int n_elts_here = bitsize / elt_size;
> + poly_int64 n_elts_here = exact_div (bitsize, elt_size);
> count += n_elts_here;
> if (mostly_zeros_p (value))
> zero_count += n_elts_here;
> @@ -8033,7 +8032,7 @@ store_constructor (tree exp, rtx target, int cleared,
> poly_int64 size,
> /* Clear the entire vector first if there are any missing elements,
> or if the incidence of zero elements is >= 75%. */
> need_to_clear = (maybe_lt (count, n_elts)
> - || 4 * zero_count >= 3 * count);
> + || maybe_gt (4 * zero_count, 3 * count));
> }
>
> if (need_to_clear && maybe_gt (size, 0) && !vector)
> @@ -8060,9 +8059,13 @@ store_constructor (tree exp, rtx target, int cleared,
> poly_int64 size,
>
> /* Store each element of the constructor into the corresponding
> element of TARGET, determined by counting the elements. */
> - for (idx = 0, i = 0;
> - vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
> - idx++, i += bitsize / elt_size)
> + HOST_WIDE_INT chunk_size = 0;
> + bool chunk_multiple_p = constant_multiple_p (bitsize, elt_size,
> + &chunk_size);
> + gcc_assert (chunk_multiple_p || vec_vec_init_p);
> +
> + for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
> + idx++)
> {
> HOST_WIDE_INT eltpos;
> tree value = ce->value;
> @@ -8073,7 +8076,7 @@ store_constructor (tree exp, rtx target, int cleared,
> poly_int64 size,
> if (ce->index)
> eltpos = tree_to_uhwi (ce->index);
> else
> - eltpos = i;
> + eltpos = idx * chunk_size;
>
> if (vector)
> {
> @@ -8461,10 +8464,8 @@ get_inner_reference (tree exp, poly_int64 *pbitsize,
>
> if (size_tree != 0)
> {
> - if (! tree_fits_uhwi_p (size_tree))
> + if (!poly_int_tree_p (size_tree, pbitsize))
> mode = BLKmode, *pbitsize = -1;
> - else
> - *pbitsize = tree_to_uhwi (size_tree);
> }
>
> *preversep = reverse_storage_order_for_component_p (exp);
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)