https://gcc.gnu.org/g:637d188f6e050a5dd2a2e761940c3c5076945b85

commit 637d188f6e050a5dd2a2e761940c3c5076945b85
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri Aug 15 15:27:59 2025 +0200

    Refactor set_gfc_from_cfi
    
    Correction régression bind_c_optional-1
    
    Correction renseignement stride
    
    Correction régression bind-c-contiguous-3
    
    Correction motif array_reference_3
    
    Suppression code commenté
    
    Modif dump

Diff:
---
 gcc/fortran/trans-descriptor.cc                 | 174 ++++++++++++------------
 gcc/testsuite/gfortran.dg/array_reference_3.f90 |   2 +-
 2 files changed, 89 insertions(+), 87 deletions(-)

diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 29c43346be09..e60a5bde4f5c 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -1775,6 +1775,61 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree 
desc,
 }
 
 
+static void
+set_gfc_dimension_from_cfi (stmtblock_t *block, tree gfc, tree cfi, tree idx,
+                           tree lbound, tree offset_var, tree cont_stride_var,
+                           bool contiguous)
+{
+  /* gfc->dim[i].lbound = ... */
+  lbound = fold_convert (gfc_array_index_type, lbound);
+  lbound = gfc_evaluate_now (lbound, block);
+  gfc_conv_descriptor_lbound_set (block, gfc, idx, lbound);
+
+  /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
+  tree tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+                             lbound, gfc_index_one_node);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+                        gfc_get_cfi_dim_extent (cfi, idx), tmp);
+  gfc_conv_descriptor_ubound_set (block, gfc, idx, tmp);
+
+  tree stride;
+  if (contiguous)
+    {
+      /* gfc->dim[i].stride
+          = idx == 0 ? 1 : gfc->dim[i-1].stride * cfi->dim[i-1].extent */
+      tree cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
+                                  idx, build_zero_cst (TREE_TYPE (idx)));
+      tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
+                            idx, build_int_cst (TREE_TYPE (idx), 1));
+      tmp = gfc_get_cfi_dim_extent (cfi, tmp);
+      tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
+                            tmp, cont_stride_var);
+      tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
+                       gfc_index_one_node, tmp);
+      stride = gfc_evaluate_now (tmp, block);
+      gfc_add_modify (block, cont_stride_var, stride);
+    }
+  else
+    {
+      /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
+      tmp = gfc_get_cfi_dim_sm (cfi, idx);
+      tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
+                            gfc_array_index_type, tmp,
+                            fold_convert (gfc_array_index_type,
+                                          gfc_get_cfi_desc_elem_len (cfi)));
+      stride = gfc_evaluate_now (tmp, block);
+    }
+  gfc_conv_descriptor_stride_set (block, gfc, idx, stride);
+
+  /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
+  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+                        stride, lbound);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+                        offset_var, tmp);
+  gfc_add_modify (block, offset_var, tmp);
+}
+
+
 void
 gfc_set_gfc_from_cfi (stmtblock_t *block, tree gfc, gfc_expr *e, tree rank,
                      tree gfc_strlen, tree cfi, gfc_symbol *fsym)
@@ -1814,43 +1869,21 @@ gfc_set_gfc_from_cfi (stmtblock_t *block, tree gfc, 
gfc_expr *e, tree rank,
       gfc_conv_descriptor_span_set (&block2, gfc, tmp);
 
       /* Calculate offset + set lbound, ubound and stride.  */
-      gfc_conv_descriptor_offset_set (&block2, gfc, gfc_index_zero_node);
+      tree offset = gfc_create_var (gfc_array_index_type, "offset");
+      gfc_add_modify (&block2, offset, gfc_index_zero_node);
       /* Loop: for (i = 0; i < rank; ++i).  */
       tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
       /* Loop body.  */
       stmtblock_t loop_body;
       gfc_init_block (&loop_body);
-      /* gfc->dim[i].lbound = ... */
-      tmp = gfc_get_cfi_dim_lbound (cfi, idx);
-      gfc_conv_descriptor_lbound_set (&loop_body, gfc, idx, tmp);
-
-      /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
-      tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-                            gfc_conv_descriptor_lbound_get (gfc, idx),
-                            gfc_index_one_node);
-      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-                            gfc_get_cfi_dim_extent (cfi, idx), tmp);
-      gfc_conv_descriptor_ubound_set (&loop_body, gfc, idx, tmp);
-
-      /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
-      tmp = gfc_get_cfi_dim_sm (cfi, idx);
-      tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
-                            gfc_array_index_type, tmp,
-                            fold_convert (gfc_array_index_type,
-                                          gfc_get_cfi_desc_elem_len (cfi)));
-      gfc_conv_descriptor_stride_set (&loop_body, gfc, idx, tmp);
-
-      /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
-      tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-                            gfc_conv_descriptor_stride_get (gfc, idx),
-                            gfc_conv_descriptor_lbound_get (gfc, idx));
-      tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-                            gfc_conv_descriptor_offset_get (gfc), tmp);
-      gfc_conv_descriptor_offset_set (&loop_body, gfc, tmp);
+      set_gfc_dimension_from_cfi (&loop_body, gfc, cfi, idx,
+                                 gfc_get_cfi_dim_lbound (cfi, idx), offset,
+                                 NULL_TREE, false);
       /* Generate loop.  */
       gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 0),
                           rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
                           gfc_finish_block (&loop_body));
+      gfc_conv_descriptor_offset_set (&block2, gfc, offset);
     }
 
   if (e->ts.type == BT_CHARACTER && !e->ts.u.cl->length)
@@ -1878,17 +1911,14 @@ void
 gfc_set_gfc_from_cfi (stmtblock_t *block, stmtblock_t *block2, tree gfc_desc,
                      tree rank, tree cfi, gfc_symbol *sym, bool do_copy_inout)
 {
-  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
-    {
-      /* gfc->dtype = ... (from declaration, not from cfi).  */
-      tree etype = gfc_get_element_type (TREE_TYPE (gfc_desc));
-      gfc_conv_descriptor_dtype_set (block, gfc_desc,
-                                    gfc_get_dtype_rank_type (sym->as->rank,
-                                                             etype));
-      /* gfc->data = cfi->base_addr. */
-      gfc_conv_descriptor_data_set (block, gfc_desc,
-                                   gfc_get_cfi_desc_base_addr (cfi));
-    }
+  /* gfc->dtype = ... (from declaration, not from cfi).  */
+  tree etype = gfc_get_element_type (TREE_TYPE (gfc_desc));
+  gfc_conv_descriptor_dtype_set (block, gfc_desc,
+                                gfc_get_dtype_rank_type (sym->as->rank,
+                                                         etype));
+  /* gfc->data = cfi->base_addr. */
+  gfc_conv_descriptor_data_set (block, gfc_desc,
+                               gfc_get_cfi_desc_base_addr (cfi));
 
   if (sym->ts.type == BT_ASSUMED)
     {
@@ -1989,7 +2019,9 @@ gfc_set_gfc_from_cfi (stmtblock_t *block, stmtblock_t 
*block2, tree gfc_desc,
   gfc_conv_descriptor_span_set (block2, gfc_desc, tmp);
 
   /* Calculate offset + set lbound, ubound and stride.  */
-  gfc_conv_descriptor_offset_set (block2, gfc_desc, gfc_index_zero_node);
+  tree offset = gfc_create_var (gfc_array_index_type, "offset");
+  gfc_add_modify (block2, offset, gfc_index_zero_node);
+
   if (sym->as->rank > 0 && !sym->attr.pointer && !sym->attr.allocatable)
     for (int i = 0; i < sym->as->rank; ++i)
       {
@@ -2010,62 +2042,32 @@ gfc_set_gfc_from_cfi (stmtblock_t *block, stmtblock_t 
*block2, tree gfc_desc,
   /* Loop: for (i = 0; i < rank; ++i).  */
   tree idx = gfc_create_var (TREE_TYPE (rank), "idx");
 
+  /* Stride  */
+  tree stride;
+  if (do_copy_inout)
+    stride = gfc_create_var (gfc_array_index_type, "stride");
+  else
+    stride = NULL_TREE;
+
   /* Loop body.  */
   stmtblock_t loop_body;
   gfc_init_block (&loop_body);
   /* gfc->dim[i].lbound = ... */
+  tree lbound;
   if (sym->attr.pointer || sym->attr.allocatable)
-    {
-      tmp = gfc_get_cfi_dim_lbound (cfi, idx);
-      gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx, tmp);
-    }
+    lbound = gfc_get_cfi_dim_lbound (cfi, idx);
   else if (sym->as->rank < 0)
-    gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx,
-                                   gfc_index_one_node);
-
-  /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-                            gfc_conv_descriptor_lbound_get (gfc_desc, idx),
-                            gfc_index_one_node);
-  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-                            gfc_get_cfi_dim_extent (cfi, idx), tmp);
-  gfc_conv_descriptor_ubound_set (&loop_body, gfc_desc, idx, tmp);
-
-  if (do_copy_inout)
-    {
-      /* gfc->dim[i].stride
-          = idx == 0 ? 1 : gfc->dim[i-1].stride * cfi->dim[i-1].extent */
-      tree cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
-                                  idx, build_zero_cst (TREE_TYPE (idx)));
-      tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
-                            idx, build_int_cst (TREE_TYPE (idx), 1));
-      tree tmp2 = gfc_get_cfi_dim_extent (cfi, tmp);
-      tmp = gfc_conv_descriptor_stride_get (gfc_desc, tmp);
-      tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp2),
-                            tmp2, tmp);
-      tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
-                       gfc_index_one_node, tmp);
-    }
+    lbound = gfc_index_one_node;
   else
-    {
-      /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
-      tmp = gfc_get_cfi_dim_sm (cfi, idx);
-      tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
-                            gfc_array_index_type, tmp,
-                            fold_convert (gfc_array_index_type,
-                                          gfc_get_cfi_desc_elem_len (cfi)));
-     }
-  gfc_conv_descriptor_stride_set (&loop_body, gfc_desc, idx, tmp);
-  /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
-  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-                            gfc_conv_descriptor_stride_get (gfc_desc, idx),
-                            gfc_conv_descriptor_lbound_get (gfc_desc, idx));
-  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
-                            gfc_conv_descriptor_offset_get (gfc_desc), tmp);
-  gfc_conv_descriptor_offset_set (&loop_body, gfc_desc, tmp);
+    lbound = gfc_conv_descriptor_lbound_get (gfc_desc, idx);
+
+  set_gfc_dimension_from_cfi (&loop_body, gfc_desc, cfi, idx, lbound, offset,
+                             stride, do_copy_inout);
 
   /* Generate loop.  */
   gfc_simple_for_loop (block2, idx, build_zero_cst (TREE_TYPE (idx)),
                       rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
                       gfc_finish_block (&loop_body));
+
+  gfc_conv_descriptor_offset_set (block2, gfc_desc, offset);
 }
diff --git a/gcc/testsuite/gfortran.dg/array_reference_3.f90 
b/gcc/testsuite/gfortran.dg/array_reference_3.f90
index 4841518dcc32..ae05db559cd8 100644
--- a/gcc/testsuite/gfortran.dg/array_reference_3.f90
+++ b/gcc/testsuite/gfortran.dg/array_reference_3.f90
@@ -65,7 +65,7 @@ contains
     call ccfis(x)
     if (any(x /= 13)) stop 13
     ! The cfi descriptor’s dim array is referenced with array indexing.
-    ! { dg-final { scan-tree-dump-times 
{cfi_descriptor->dim\[idx.\d+\]\.ubound = 
_cfi_descriptor->dim\[idx.\d+\]\.extent \+ \((?:NON_LVALUE_EXPR 
<)?cfi_descriptor->dim\[idx.\d+\]\.lbound>? \+ -1\);} 1 "original" } }
+    ! { dg-final { scan-tree-dump-times {cfi_descriptor->dim\[[^]]+\]\.ubound 
= (?:NON_LVALUE_EXPR <)?_cfi_descriptor->dim\[[^]]+\]\.extent>?(?: \+ \(D\.\d+ 
\+ -1\))?;} 1 "original" } }
   end subroutine check_cfi_dim
   subroutine css(c) bind(c)
     character :: c

Reply via email to