https://gcc.gnu.org/g:7cad3fe95a2ff5636f6df1fc4f772768ae859038

commit 7cad3fe95a2ff5636f6df1fc4f772768ae859038
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Mon Feb 17 17:28:01 2025 +0100

    Suppression mise à jour offset forall
    
    Sauvegarde
    
    Correction régression forall

Diff:
---
 gcc/fortran/trans-array.cc      | 55 +++++++++++++++++++++++++----------------
 gcc/fortran/trans-array.h       |  3 ++-
 gcc/fortran/trans-descriptor.cc | 37 ++++++++++++++++++++++-----
 gcc/fortran/trans-descriptor.h  |  4 ++-
 gcc/fortran/trans-expr.cc       |  4 ++-
 gcc/fortran/trans-stmt.cc       | 10 ++------
 gcc/fortran/trans.h             |  4 ++-
 7 files changed, 78 insertions(+), 39 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index f59ec4a69d43..11460dff9c12 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -960,7 +960,8 @@ get_class_info_from_ss (stmtblock_t * pre, gfc_ss *ss, tree 
*eltype,
 tree
 gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * 
ss,
                             tree eltype, tree initial, bool dynamic,
-                            bool dealloc, bool callee_alloc, locus * where)
+                            bool dealloc, bool callee_alloc, locus * where,
+                            bool shift_bounds)
 {
   gfc_loopinfo *loop;
   gfc_ss *s;
@@ -1048,19 +1049,23 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
        {
          dim = s->dim[n];
 
-         /* Callee allocated arrays may not have a known bound yet.  */
-         if (loop->to[n])
-           loop->to[n] = gfc_evaluate_now (
-                       fold_build2_loc (input_location, MINUS_EXPR,
-                                        gfc_array_index_type,
-                                        loop->to[n], loop->from[n]),
-                       pre);
-         loop->from[n] = gfc_index_zero_node;
+         if (shift_bounds)
+           {
+             /* Callee allocated arrays may not have a known bound yet.  */
+             if (loop->to[n])
+               {
+                 tree t = fold_build2_loc (input_location, MINUS_EXPR,
+                                           gfc_array_index_type,
+                                           loop->to[n], loop->from[n]);
+                 loop->to[n] = gfc_evaluate_now (t, pre);
+               }
+             loop->from[n] = gfc_index_zero_node;
 
-         /* We have just changed the loop bounds, we must clear the
-            corresponding specloop, so that delta calculation is not skipped
-            later in gfc_set_delta.  */
-         loop->specloop[n] = NULL;
+             /* We have just changed the loop bounds, we must clear the
+                corresponding specloop, so that delta calculation is not
+                skipped later in gfc_set_delta.  */
+             loop->specloop[n] = NULL;
+           }
 
          /* We are constructing the temporary's descriptor based on the loop
             dimensions.  As the dimensions may be accessed in arbitrary order
@@ -1221,13 +1226,18 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
        {
          stride[n] = size;
 
-         tmp = fold_build2_loc (input_location, PLUS_EXPR,
-                                gfc_array_index_type,
-                                to[n], gfc_index_one_node);
+         tmp = gfc_index_one_node;
+         if (!shift_bounds && !integer_zerop (from[n]))
+           tmp = fold_build2_loc (input_location, MINUS_EXPR,
+                                  gfc_array_index_type, 
+                                  gfc_index_one_node, from[n]);
+
+         tree extent = fold_build2_loc (input_location, PLUS_EXPR,
+                                        gfc_array_index_type, to[n], tmp);
 
          /* Check whether the size for this dimension is negative.  */
          cond = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
-                                 tmp, gfc_index_zero_node);
+                                 extent, gfc_index_zero_node);
          cond = gfc_evaluate_now (cond, pre);
 
          if (n == 0)
@@ -1237,7 +1247,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
                                       logical_type_node, or_expr, cond);
 
          size = fold_build2_loc (input_location, MULT_EXPR,
-                                 gfc_array_index_type, size, tmp);
+                                 gfc_array_index_type, size, extent);
          size = gfc_evaluate_now (size, pre);
        }
     }
@@ -1265,9 +1275,9 @@ gfc_trans_create_temp_array (stmtblock_t * pre, 
stmtblock_t * post, gfc_ss * ss,
                                                    dealloc);
 
   gfc_set_temporary_descriptor (pre, desc, class_expr, elemsize, data_ptr,
-                               to, stride, total_dim,
+                               from, to, stride, total_dim,
                                size == NULL_TREE || callee_alloc,
-                               rank_changer);
+                               rank_changer, shift_bounds);
 
   while (ss->parent)
     ss = ss->parent;
@@ -5631,6 +5641,8 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
                        (TREE_TYPE (tmp_ss_info->data.temp.type),
                         tmp_ss_info->string_length);
 
+      bool preserve_bounds = tmp_ss_info->data.temp.preserve_bounds;
+
       tmp = tmp_ss_info->data.temp.type;
       memset (&tmp_ss_info->data.array, 0, sizeof (gfc_array_info));
       tmp_ss_info->type = GFC_SS_SECTION;
@@ -5638,7 +5650,8 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
       gcc_assert (tmp_ss->dimen != 0);
 
       gfc_trans_create_temp_array (&loop->pre, &loop->post, tmp_ss, tmp,
-                                  NULL_TREE, false, true, false, where);
+                                  NULL_TREE, false, true, false, where,
+                                  !preserve_bounds);
     }
 
   /* For array parameters we don't have loop variables, so don't calculate the
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 8b02e331aa1a..36728ab83b94 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -29,7 +29,8 @@ void gfc_set_loop_bounds_from_array_spec 
(gfc_interface_mapping *,
 
 /* Generate code to create a temporary array.  */
 tree gfc_trans_create_temp_array (stmtblock_t *, stmtblock_t *, gfc_ss *,
-                                 tree, tree, bool, bool, bool, locus *);
+                                 tree, tree, bool, bool, bool, locus *,
+                                 bool shift_bounds = true);
 
 /* Generate function entry code for allocation of compiler allocated array
    variables.  */
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 6965262cf9b0..7b717f043a9c 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2073,9 +2073,11 @@ gfc_set_gfc_from_cfi (stmtblock_t *block, stmtblock_t 
*block2, tree gfc_desc,
 void
 gfc_set_temporary_descriptor (stmtblock_t *block, tree descr, tree class_src,
                              tree elemsize, tree data_ptr,
+                             tree lbound[GFC_MAX_DIMENSIONS],
                              tree ubound[GFC_MAX_DIMENSIONS],
                              tree stride[GFC_MAX_DIMENSIONS], int rank,
-                             bool callee_allocated, bool rank_changer)
+                             bool callee_allocated, bool rank_changer,
+                             bool shift_bounds)
 {
   if (!class_src)
     {
@@ -2099,6 +2101,7 @@ gfc_set_temporary_descriptor (stmtblock_t *block, tree 
descr, tree class_src,
       gfc_conv_descriptor_rank_set (block, descr, rank);
     }
 
+  tree offset = gfc_index_zero_node;
   if (!callee_allocated)
     for (int n = 0; n < rank; n++)
       {
@@ -2106,18 +2109,40 @@ gfc_set_temporary_descriptor (stmtblock_t *block, tree 
descr, tree class_src,
        gfc_conv_descriptor_stride_set (block, descr, gfc_rank_cst[n],
                                        stride[n]);
 
+       tree this_lbound = shift_bounds ? gfc_index_zero_node : lbound[n];
        gfc_conv_descriptor_lbound_set (block, descr, gfc_rank_cst[n],
-                                       gfc_index_zero_node);
+                                       this_lbound);
+
+       tree this_ubound;
+       if (shift_bounds)
+         {
+           tree lbound_diff = fold_build2_loc (input_location, MINUS_EXPR,
+                                               gfc_array_index_type,
+                                               this_lbound, lbound[n]);
+           this_ubound = fold_build2_loc (input_location, PLUS_EXPR,
+                                          gfc_array_index_type,
+                                          ubound[n], lbound_diff);
+         }
+       else
+         this_ubound = ubound[n];
 
        gfc_conv_descriptor_ubound_set (block, descr, gfc_rank_cst[n],
-                                       ubound[n]);
+                                       this_ubound);
+
+       if (!shift_bounds)
+         {
+           tree tmp = fold_build2_loc (input_location, MULT_EXPR,
+                                       gfc_array_index_type, this_lbound,
+                                       stride[n]);
+           tmp = fold_build2_loc (input_location, MINUS_EXPR,
+                                  gfc_array_index_type, offset, tmp);
+           offset = gfc_evaluate_now (tmp, block);
+         }
       }
 
   gfc_conv_descriptor_span_set (block, descr, elemsize);
 
-  /* The offset is zero because we create temporaries with a zero
-     lower bound.  */
-  gfc_conv_descriptor_offset_set (block, descr, gfc_index_zero_node);
+  gfc_conv_descriptor_offset_set (block, descr, offset);
 
   gfc_conv_descriptor_data_set (block, descr, data_ptr);
 }
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index 6087c3d2e548..aaa27ece57eb 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -142,6 +142,8 @@ void gfc_set_gfc_from_cfi (stmtblock_t *, stmtblock_t *, 
tree, tree, tree,
 
 void gfc_set_temporary_descriptor (stmtblock_t *, tree, tree, tree, tree,
                                   tree [GFC_MAX_DIMENSIONS],
-                                  tree [GFC_MAX_DIMENSIONS], int, bool, bool);
+                                  tree [GFC_MAX_DIMENSIONS],
+                                  tree [GFC_MAX_DIMENSIONS], int, bool, bool,
+                                  bool shift_bounds = true);
 
 #endif /* GFC_TRANS_DESCRIPTOR_H */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index dca47ca8a2d6..81cc33417f34 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5297,7 +5297,8 @@ void
 gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, int g77,
                           sym_intent intent, bool formal_ptr,
                           const gfc_symbol *fsym, const char *proc_name,
-                          gfc_symbol *sym, bool check_contiguous)
+                          gfc_symbol *sym, bool check_contiguous,
+                          bool preserve_bounds)
 {
   gfc_se lse;
   gfc_se rse;
@@ -5376,6 +5377,7 @@ gfc_conv_subref_array_arg (gfc_se *se, gfc_expr * expr, 
int g77,
                                              ? expr->ts.u.cl->backend_decl
                                              : NULL),
                                  loop.dimen);
+  loop.temp_ss->info->data.temp.preserve_bounds = preserve_bounds;
 
   parmse->string_length = loop.temp_ss->info->string_length;
 
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index b525c4348916..de625b293eae 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -4139,17 +4139,11 @@ forall_make_variable_temp (gfc_code *c, stmtblock_t 
*pre, stmtblock_t *post)
   if (old_sym->attr.dimension)
     {
       gfc_init_se (&tse, NULL);
-      gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
+      gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false,
+                                NULL, NULL, NULL, false, true);
       gfc_add_block_to_block (pre, &tse.pre);
       gfc_add_block_to_block (post, &tse.post);
       tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
-
-      if (c->expr1->ref->u.ar.type != AR_SECTION)
-       {
-         /* Use the variable offset for the temporary.  */
-         tmp = gfc_conv_array_offset (old_sym->backend_decl);
-         gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
-       }
     }
   else
     {
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 2d4218439ad4..e3f1e6925baf 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -285,6 +285,7 @@ typedef struct gfc_ss_info
     struct
     {
       tree type;
+      bool preserve_bounds;
     }
     temp;
 
@@ -564,7 +565,8 @@ void gfc_conv_subref_array_arg (gfc_se *, gfc_expr *, int, 
sym_intent, bool,
                                const gfc_symbol *fsym = NULL,
                                const char *proc_name = NULL,
                                gfc_symbol *sym = NULL,
-                               bool check_contiguous = false);
+                               bool check_contiguous = false,
+                               bool preserve_bounds = false);
 
 void gfc_conv_is_contiguous_expr (gfc_se *, gfc_expr *);

Reply via email to