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);

Reply via email to