https://gcc.gnu.org/g:c76ba902433ba9013ee3cddc362ab76c58d45ca2

commit c76ba902433ba9013ee3cddc362ab76c58d45ca2
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Tue Sep 16 21:52:51 2025 +0200

    Factorisation calcul index dimension
    
    Correction régression ICE compilation openacc.f90
    
    Correction régression libgomp.fortran/pr93553.f90
    
    Correction régression pr93638-1.f90
    
    Ajout commentaire gfc_offset_add

Diff:
---
 gcc/fortran/trans-array.cc | 134 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 95 insertions(+), 39 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index b1064426c2ca..52e9ffc2932a 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -3452,7 +3452,68 @@ array_bound_check_elemental (gfc_se * se, gfc_ss * ss, 
gfc_expr * expr)
 }
 
 
+struct gfc_offset_pair
+{
+  tree cst_part, non_cst_part;
+};
+
+
+/* Add T to the offset pair *OFFSET, *CST_OFFSET.  */
+
+static void
+gfc_offset_add (gfc_offset_pair &offset, tree t)
+{
+  if (TREE_CODE (t) == INTEGER_CST)
+    {
+      if (offset.cst_part == NULL_TREE)
+       offset.cst_part = t;
+      else
+       offset.cst_part = int_const_binop (PLUS_EXPR, offset.cst_part, t);
+    }
+  else
+    {
+      if (offset.non_cst_part == NULL_TREE)
+       offset.non_cst_part = t;
+      else
+       offset.non_cst_part = fold_build2_loc (input_location, PLUS_EXPR,
+                                              gfc_array_index_type,
+                                              offset.non_cst_part, t);
+    }
+}
+
+
 static tree
+gfc_offset_pair_materialize (gfc_offset_pair &pair)
+{
+  if (pair.cst_part == NULL_TREE
+      || integer_zerop (pair.cst_part))
+    {
+      if (pair.non_cst_part == NULL_TREE)
+       return gfc_index_zero_node;
+      else
+       return pair.non_cst_part;
+    }
+  else
+    return fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+                           pair.non_cst_part, pair.cst_part);
+}
+
+
+/* Add T to the offset pair *OFFSET, *CST_OFFSET.  */
+
+static gfc_offset_pair
+add_to_offset (gfc_array_ref_info *ref_info, tree val)
+{
+  gfc_offset_pair offset {NULL_TREE, NULL_TREE};
+  memset (&offset, 0, sizeof (offset));
+  offset.cst_part = ref_info->cst_index;
+  offset.non_cst_part = ref_info->index;
+  gfc_offset_add (offset, val);
+  return offset;
+}
+
+
+static gfc_offset_pair
 conv_array_index_dim (gfc_array_ref_info *ref_info, tree index, tree stride)
 {
   /* Multiply by the stride.  */
@@ -3462,8 +3523,7 @@ conv_array_index_dim (gfc_array_ref_info *ref_info, tree 
index, tree stride)
 
   /* Add the offset for this dimension to the stored offset for all other
      dimensions.  */
-  return fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-                         ref_info->index, index);
+  return add_to_offset (ref_info, index);
 }
 
 
@@ -3471,7 +3531,7 @@ conv_array_index_dim (gfc_array_ref_info *ref_info, tree 
index, tree stride)
    dimensions.  Single element references are processed separately.
    DIM is the array dimension, I is the loop dimension.  */
 
-static tree
+static gfc_offset_pair
 conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
                         gfc_array_ref * ar)
 {
@@ -3715,7 +3775,6 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref 
* ar,
 {
   gfc_array_info *info;
   tree decl = NULL_TREE;
-  tree index;
   tree base;
   gfc_ss *ss;
   gfc_expr *expr;
@@ -3729,7 +3788,8 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref 
* ar,
   else
     n = 0;
 
-  index = conv_array_index_offset (se, ss, ss->dim[n], n, ar);
+  gfc_offset_pair pair = conv_array_index_offset (se, ss, ss->dim[n], n, ar);
+  tree index = gfc_offset_pair_materialize (pair);
 
   base = build_fold_indirect_ref_loc (input_location, info->current_elem.base);
 
@@ -3772,23 +3832,6 @@ gfc_conv_tmp_array_ref (gfc_se * se)
   gfc_advance_se_ss_chain (se);
 }
 
-/* Add T to the offset pair *OFFSET, *CST_OFFSET.  */
-
-static void
-add_to_offset (tree *cst_offset, tree *offset, tree t)
-{
-  if (TREE_CODE (t) == INTEGER_CST)
-    *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t);
-  else
-    {
-      if (!integer_zerop (*offset))
-       *offset = fold_build2_loc (input_location, PLUS_EXPR,
-                                  gfc_array_index_type, *offset, t);
-      else
-       *offset = t;
-    }
-}
-
 
 static tree
 build_array_ref (tree desc, tree offset, tree decl, tree vptr)
@@ -3837,9 +3880,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, 
gfc_expr *expr,
                    locus * where)
 {
   int n;
-  tree offset, cst_offset;
   tree tmp;
-  tree stride;
   tree decl = NULL_TREE;
   gfc_se indexse;
   gfc_se tmpse;
@@ -3895,8 +3936,13 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, 
gfc_expr *expr,
       && ar->as->type != AS_DEFERRED)
     decl = sym->backend_decl;
 
-  cst_offset = offset = gfc_index_zero_node;
-  add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (decl));
+  gfc_array_ref_info ref_info;
+  memset (&ref_info, 0, sizeof (ref_info));
+
+  ref_info.base = decl;
+  gfc_offset_pair offset = add_to_offset (&ref_info, gfc_conv_array_offset 
(decl));
+  ref_info.cst_index = offset.cst_part;
+  ref_info.index = offset.non_cst_part;
 
   /* Calculate the offsets from all the dimensions.  Make sure to associate
      the final offset so that we form a chain of loop invariant summands.  */
@@ -3963,18 +4009,28 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, 
gfc_expr *expr,
            }
        }
 
-      /* Multiply the index by the stride.  */
-      stride = gfc_conv_array_stride (decl, n);
-      tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-                            indexse.expr, stride);
-
-      /* And add it to the total.  */
-      add_to_offset (&cst_offset, &offset, tmp);
+      gfc_offset_pair offset;
+      offset = conv_array_index_dim (&ref_info, indexse.expr,
+                                    gfc_conv_array_stride (decl, n));
+      ref_info.cst_index = offset.cst_part;
+      ref_info.index = offset.non_cst_part;
     }
 
-  if (!integer_zerop (cst_offset))
-    offset = fold_build2_loc (input_location, PLUS_EXPR,
-                             gfc_array_index_type, offset, cst_offset);
+  tree index;
+  if (ref_info.cst_index == NULL_TREE
+      || integer_zerop (ref_info.cst_index))
+    {
+      if (ref_info.index == NULL_TREE)
+       index = gfc_index_zero_node;
+      else
+       index = ref_info.index;
+    }
+  else if (ref_info.index == NULL_TREE)
+    index = ref_info.cst_index;
+  else
+    index = fold_build2_loc (input_location, PLUS_EXPR,
+                            gfc_array_index_type, ref_info.index,
+                            ref_info.cst_index);
 
   /* A pointer array component can be detected from its field decl. Fix
      the descriptor, mark the resulting variable decl and pass it to
@@ -4022,7 +4078,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, 
gfc_expr *expr,
     }
 
   free (var_name);
-  se->expr = build_array_ref (se->expr, offset, decl, se->class_vptr);
+  se->expr = build_array_ref (se->expr, index, decl, se->class_vptr);
 }
 
 
@@ -4035,16 +4091,16 @@ add_array_offset (stmtblock_t *pblock, gfc_loopinfo 
*loop, gfc_ss *ss,
 {
   gfc_se se;
   gfc_array_info *info;
-  tree index;
 
   info = &ss->info->data.array;
 
   gfc_init_se (&se, NULL);
   se.loop = loop;
   se.expr = info->descriptor;
-  index = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar);
+  gfc_offset_pair pair = conv_array_index_offset (&se, ss, array_dim, 
loop_dim, ar);
   gfc_add_block_to_block (pblock, &se.pre);
 
+  tree index = gfc_offset_pair_materialize (pair);
   info->current_elem.index = gfc_evaluate_now (index, pblock);
 }

Reply via email to