--- Begin Message ---
The GIMPLE SSA operand scanner handles COMPONENT_REFs that are
not marked TREE_THIS_VOLATILE but have a TREE_THIS_VOLATILE
FIELD_DECL as volatile. That's inconsistent in how TREE_THIS_VOLATILE
testing on GENERIC refs works which requires operand zero of
component references to mirror TREE_THIS_VOLATILE to the ref
so that testing TREE_THIS_VOLATILE on the outermost reference
is enough to determine the volatileness.
The following patch thus removes FIELD_DECL scanning from
the GIMPLE SSA operand scanner, possibly leaving fewer stmts
marked as gimple_has_volatile_ops.
It shows we miss at least one case in the fortran frontend, though
there's a suspicious amount of COMPONENT_REF creation compared
to little setting of TREE_THIS_VOLATILE. This fixes the FAIL
of gfortran.dg/volatile11.f90 that would otherwise occur.
Visually inspecting fortran/ reveals a bunch of likely to fix
cases but I don't know the constraints of 'volatile' uses in
the fortran language to assess whether some of these are not
necessary. The cases would be fixed with
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 0d013defdbb..5d708fe90aa 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -6983,9 +6983,10 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm,
tree desc, tree offset,
case REF_COMPONENT:
field = ref->u.c.component->backend_decl;
gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
- tmp = fold_build3_loc (input_location, COMPONENT_REF,
- TREE_TYPE (field),
- tmp, field, NULL_TREE);
+ tmp = build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (field), tmp, field, NULL_TREE);
+ if (TREE_THIS_VOLATILE (field))
+ TREE_THIS_VOLATILE (tmp) = 1;
break;
case REF_SUBSTRING:
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index c4291cce079..e6dc79f8c1e 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -2244,9 +2244,11 @@ gfc_get_tree_for_caf_expr (gfc_expr *expr)
if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
- caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
- TREE_TYPE (comp->backend_decl), caf_decl,
- comp->backend_decl, NULL_TREE);
+ caf_decl = build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (comp->backend_decl), caf_decl,
+ comp->backend_decl, NULL_TREE);
+ if (TREE_THIS_VOLATILE (comp->backend_decl))
+ TREE_THIS_VOLATILE (caf_decl) = 1;
if (comp->ts.type == BT_CLASS)
{
caf_decl = gfc_class_data_get (caf_decl);
@@ -2755,8 +2757,10 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
else
se->class_vptr = NULL_TREE;
- tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
- decl, field, NULL_TREE);
+ tmp =build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
+ decl, field, NULL_TREE);
+ if (TREE_THIS_VOLATILE (field))
+ TREE_THIS_VOLATILE (tmp) = 1;
se->expr = tmp;
@@ -8792,8 +8796,10 @@ gfc_trans_structure_assign (tree dest, gfc_expr * expr,
bool init, bool coarray)
}
field = cm->backend_decl;
gcc_assert(field);
- tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
- dest, field, NULL_TREE);
+ tmp = build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
+ dest, field, NULL_TREE);
+ if (TREE_THIS_VOLATILE (field))
+ TREE_THIS_VOLATILE (tmp) = 1;
if (!c->expr)
{
gfc_expr *e = gfc_get_null_expr (NULL);
but I did not include them as they have no effect on the testsuite.
The question is whether we instead want to amend build3 to
set TREE_THIS_VOLATILE automatically when the FIELD_DECL has
it set. At least for the Fortran FE cases the gimplifier
fails to see some volatile references and thus can generate
wrong code which is a latent issue.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
OK?
Thanks,
Richard.
2021-08-09 Richard Biener <rguent...@suse.de>
gcc/
* tree-ssa-operands.c (operands_scanner::get_expr_operands):
Do not look at COMPONENT_REF FIELD_DECLs TREE_THIS_VOLATILE
to determine has_volatile_ops.
gcc/fortran/
* trans-common.c (create_common): Set TREE_THIS_VOLATILE on the
COMPONENT_REF if the field is volatile.
---
gcc/fortran/trans-common.c | 9 +++++----
gcc/tree-ssa-operands.c | 7 +------
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c
index a11cf4c839e..7bcf18dc475 100644
--- a/gcc/fortran/trans-common.c
+++ b/gcc/fortran/trans-common.c
@@ -759,10 +759,11 @@ create_common (gfc_common_head *com, segment_info *head,
bool saw_equiv)
else
gfc_add_decl_to_function (var_decl);
- SET_DECL_VALUE_EXPR (var_decl,
- fold_build3_loc (input_location, COMPONENT_REF,
- TREE_TYPE (s->field),
- decl, s->field, NULL_TREE));
+ tree comp = build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (s->field), decl, s->field, NULL_TREE);
+ if (TREE_THIS_VOLATILE (s->field))
+ TREE_THIS_VOLATILE (comp) = 1;
+ SET_DECL_VALUE_EXPR (var_decl, comp);
DECL_HAS_VALUE_EXPR_P (var_decl) = 1;
GFC_DECL_COMMON_OR_EQUIV (var_decl) = 1;
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index c15575416dd..ebf7eea3b04 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -834,12 +834,7 @@ operands_scanner::get_expr_operands (tree *expr_p, int
flags)
get_expr_operands (&TREE_OPERAND (expr, 0), flags);
if (code == COMPONENT_REF)
- {
- if (!(flags & opf_no_vops)
- && TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1)))
- gimple_set_has_volatile_ops (stmt, true);
- get_expr_operands (&TREE_OPERAND (expr, 2), uflags);
- }
+ get_expr_operands (&TREE_OPERAND (expr, 2), uflags);
else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
{
get_expr_operands (&TREE_OPERAND (expr, 1), uflags);
--
2.31.1
To declare a filtering error, please use the following link :
https://www.security-mail.net/reporter.php?mid=e9c2.611265ed.8e876.0&r=marc.poulhies%40kalray.eu&s=gcc-patches-bounces%2Bmarc.poulhies%3Dkalray.eu%40gcc.gnu.org&o=%5BPATCH%5D%5Bv2%5D+Adjust+volatile+handling+of+the+operand+scanner&verdict=C&c=6e6e41ce91c630eb8b61022e89dc0a89ce0902aa
--- End Message ---