https://gcc.gnu.org/g:b6242bd122757ec6c75c73a4921f24a9a382b090
commit r15-6109-gb6242bd122757ec6c75c73a4921f24a9a382b090 Author: Victor Do Nascimento <victor.donascime...@arm.com> Date: Wed Dec 11 12:00:58 2024 +0000 middle-end: Add initial support for poly_int64 BIT_FIELD_REF in expand pass [PR96342] 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. Co-authored-by: Tamar Christina <tamar.christ...@arm.com> Diff: --- gcc/expr.cc | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index 88fa56cb299d..babf00f34dcf 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);