[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression forall_13
Mikael Morin
mikael@gcc.gnu.org
Fri Jun 13 14:46:01 GMT 2025
https://gcc.gnu.org/g:c03ee21ad332bdf48593f29ec6a64fcb056171db
commit c03ee21ad332bdf48593f29ec6a64fcb056171db
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Mon Feb 17 18:49:30 2025 +0100
Correction régression forall_13
Diff:
---
gcc/fortran/trans-array.cc | 86 ++++++++++++++++++++++++++----------------
gcc/fortran/trans-array.h | 3 +-
gcc/fortran/trans-expr.cc | 5 ++-
gcc/fortran/trans-intrinsic.cc | 6 ++-
gcc/fortran/trans-stmt.cc | 2 +-
gcc/fortran/trans.h | 1 +
6 files changed, 64 insertions(+), 39 deletions(-)
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 04965132c4f7..2fabffb53e73 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1910,17 +1910,20 @@ set_bounds_update_offset (stmtblock_t *block, tree desc, int dim,
return;
/* Update offset. */
- tree tmp = fold_build2_loc (input_location, MULT_EXPR,
- gfc_array_index_type, lbound_diff, stride);
- tmp = fold_build2_loc (input_location, MINUS_EXPR,
- gfc_array_index_type, *offset, tmp);
- *offset = gfc_evaluate_now (tmp, block);
+ if (!integer_zerop (lbound_diff))
+ {
+ tree tmp = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, lbound_diff, stride);
+ tmp = fold_build2_loc (input_location, MINUS_EXPR,
+ gfc_array_index_type, *offset, tmp);
+ *offset = gfc_evaluate_now (tmp, block);
+ }
if (!next_stride)
return;
/* Set stride for next dimension. */
- tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
+ tree tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
*next_stride = fold_build2_loc (input_location, MULT_EXPR,
gfc_array_index_type, stride, tmp);
}
@@ -3666,9 +3669,11 @@ get_class_info_from_ss (stmtblock_t * pre, gfc_ss *ss, tree *eltype,
static void
set_temporary_descriptor (stmtblock_t *block, tree desc, 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)
{
int n;
@@ -3694,13 +3699,15 @@ set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src,
gfc_conv_descriptor_rank_set (block, desc, rank);
}
+ tree offset = gfc_index_zero_node;
if (!callee_allocated)
{
for (n = 0; n < rank; n++)
{
/* Store the stride and bound components in the descriptor. */
- set_descriptor_dimension (block, desc, n, gfc_index_zero_node, ubound[n],
- stride[n], nullptr, nullptr);
+ tree this_lbound = shift_bounds ? gfc_index_zero_node : lbound[n];
+ set_descriptor_dimension (block, desc, n, this_lbound, ubound[n],
+ stride[n], &offset, nullptr);
}
}
@@ -3710,7 +3717,7 @@ set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src,
/* The offset is zero because we create temporaries with a zero
lower bound. */
- gfc_conv_descriptor_offset_set (block, desc, gfc_index_zero_node);
+ gfc_conv_descriptor_offset_set (block, desc, offset);
}
@@ -3735,7 +3742,8 @@ set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src,
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;
@@ -3822,19 +3830,22 @@ 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;
-
- /* 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;
+ if (shift_bounds)
+ {
+ /* 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;
+
+ /* 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
@@ -3995,13 +4006,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);
+ tree extent = to[n];
+ if (!shift_bounds && !integer_zerop (from[n]))
+ extent = fold_build2_loc (input_location, MINUS_EXPR,
+ gfc_array_index_type, to[n], from[n]);
+
+ extent = fold_build2_loc (input_location, PLUS_EXPR,
+ gfc_array_index_type,
+ extent, gfc_index_one_node);
/* 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)
@@ -4011,7 +4027,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);
}
}
@@ -4039,9 +4055,9 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
dealloc);
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;
@@ -5319,7 +5335,8 @@ trans_array_constructor (gfc_ss * ss, locus * where)
}
gfc_trans_create_temp_array (&outer_loop->pre, &outer_loop->post, ss, type,
- NULL_TREE, dynamic, true, false, where);
+ NULL_TREE, dynamic, true, false, where,
+ true);
desc = ss_info->data.array.descriptor;
offset = gfc_index_zero_node;
@@ -8215,6 +8232,8 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
gcc_assert (tmp_ss_info->type == GFC_SS_TEMP);
gcc_assert (loop->parent == NULL);
+ bool preserve_bounds = tmp_ss_info->data.temp.preserve_bounds;
+
/* Make absolutely sure that this is a complete type. */
if (tmp_ss_info->string_length)
tmp_ss_info->data.temp.type
@@ -8229,7 +8248,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 357bd64fb766..e0aa60b2e9b2 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -30,7 +30,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);
/* Generate function entry code for allocation of compiler allocated array
variables. */
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 7ba25dcf2f30..d4cb4a088962 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -5468,6 +5468,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 = 1;
parmse->string_length = loop.temp_ss->info->string_length;
@@ -8419,7 +8420,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
tmp, NULL_TREE, false,
!comp->attr.pointer, callee_alloc,
- &se->ss->info->expr->where);
+ &se->ss->info->expr->where, true);
/* Pass the temporary as the first argument. */
result = info->descriptor;
@@ -8455,7 +8456,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
tmp, NULL_TREE, false,
!sym->attr.pointer, callee_alloc,
- &se->ss->info->expr->where);
+ &se->ss->info->expr->where, true);
/* Pass the temporary as the first argument. */
result = info->descriptor;
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 3c6a396cef98..de1767ba4090 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -1288,7 +1288,8 @@ gfc_conv_intrinsic_caf_get (gfc_se *se, gfc_expr *expr, tree lhs,
/* Create temporary. */
may_realloc = gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
type, NULL_TREE, false, false,
- false, &array_expr->where)
+ false, &array_expr->where,
+ true)
== NULL_TREE;
res_var = se->ss->info->data.array.descriptor;
if (array_expr->ts.type == BT_CHARACTER)
@@ -8745,7 +8746,8 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
/* Build a destination descriptor, using the pointer, source, as the
data field. */
gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, mold_type,
- NULL_TREE, false, true, false, &expr->where);
+ NULL_TREE, false, true, false, &expr->where,
+ true);
/* Cast the pointer to the result. */
tmp = gfc_conv_descriptor_data_get (info->descriptor);
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index f058b415a863..1ba09d2f575d 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -325,7 +325,7 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
gfc_init_block (&temp_post);
tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
temptype, initial, false, true,
- false, &arg->expr->where);
+ false, &arg->expr->where, true);
gfc_add_modify (&se->pre, size, tmp);
tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
gfc_add_modify (&se->pre, data, tmp);
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 73dba86a3c92..d9dd37223497 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -286,6 +286,7 @@ typedef struct gfc_ss_info
struct
{
tree type;
+ unsigned preserve_bounds:1;
}
temp;
More information about the Gcc-cvs
mailing list