]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end: Add initial support for poly_int64 BIT_FIELD_REF in expand pass [PR96342]
authorVictor Do Nascimento <victor.donascimento@arm.com>
Wed, 11 Dec 2024 12:00:58 +0000 (12:00 +0000)
committerTamar Christina <tamar.christina@arm.com>
Wed, 11 Dec 2024 12:01:06 +0000 (12:01 +0000)
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.christina@arm.com>
gcc/expr.cc

index 88fa56cb299db93c367cd6021c01d1c1a68ad803..babf00f34dcf1ac81a9d2d9947350fb1c0455811 100644 (file)
@@ -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);