On Wed, Dec 4, 2024 at 1:21 PM Tamar Christina <tamar.christ...@arm.com> wrote: > > Hi All, > > While `poly_int64' has been the default representation of bitfield size > and offset for some time, there was a lack of support for the use of > non-constant `poly_int64' values for those values throughout the > compiler, limiting the applicability of the BIT_FIELD_REF rtl expression > for variable length vectors, such as those used by SVE. > > This patch starts work on extending the functionality of relevant > functions in the expand pass such as to enable their use by the compiler > for such vectors. > > gcc/ChangeLog: > > PR target/96342 > * expr.cc (store_constructor): Enable poly_{u}int64 type usage. > (get_inner_reference): Ditto. > * expmed.cc (store_bit_field_1): Add is_constant checks to bitsize > and bitnum. > > Co-authored-by: Tamar Christina <tamar.christ...@arm.com> > > 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 > > --- > diff --git a/gcc/expmed.cc b/gcc/expmed.cc > index > 2d5e5243ce8e9c7dd2eeb0996711801d969b3f22..3721d55967ba21516b9a816505e0e999a53c3d2f > 100644 > --- a/gcc/expmed.cc > +++ b/gcc/expmed.cc > @@ -849,6 +849,10 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, > poly_uint64 bitnum, > polynomial bitnum and bitsize. */ > > /* From here on we need to be looking at a fixed-size insertion. */ > + > + if (!bitsize.is_constant () || !bitnum.is_constant ()) > + error ("bit field masks of variable size length/offset unsupported"); > +
Nak for this, we'll ICE immediately after anyway. > unsigned HOST_WIDE_INT ibitsize = bitsize.to_constant (); > unsigned HOST_WIDE_INT ibitnum = bitnum.to_constant (); > > diff --git a/gcc/expr.cc b/gcc/expr.cc > index > 70f2ecec99839e6247ed7601e0bff67e7aa38ba4..2d90d7aac296077cc0bda8a1b4732b1cd44a610d > 100644 > --- a/gcc/expr.cc > +++ b/gcc/expr.cc > @@ -7897,15 +7897,15 @@ store_constructor (tree exp, rtx target, int cleared, > poly_int64 size, > { > unsigned HOST_WIDE_INT idx; > constructor_elt *ce; > - int i; > + poly_int64 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; > @@ -8002,7 +8002,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; > > @@ -8015,12 +8015,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; > @@ -8029,7 +8029,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) > @@ -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. > if (cleared && initializer_zerop (value)) > @@ -8081,7 +8081,7 @@ store_constructor (tree exp, rtx target, int cleared, > poly_int64 size, > } > else > gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE); > - RTVEC_ELT (vector, eltpos) = expand_normal (value); > + RTVEC_ELT (vector, eltpos.to_constant ()) = expand_normal > (value); > } > else > { > @@ -8457,10 +8457,10 @@ get_inner_reference (tree exp, poly_int64 *pbitsize, > > if (size_tree != 0) > { > - if (! tree_fits_uhwi_p (size_tree)) > - mode = BLKmode, *pbitsize = -1; > + if (poly_int_tree_p (size_tree, pbitsize)) > + ; > else > - *pbitsize = tree_to_uhwi (size_tree); > + mode = BLKmode, *pbitsize = -1; > } > > *preversep = reverse_storage_order_for_component_p (exp); > > > > > --