Hi!
On the following testcase the volatile load/store are optimized away.
IMHO this is a bug in forwprop, which replaces
tmp_Y = nonvolvar[arg_X];
MEM[(volatile ...*)tmp_Y] ={v} ...;
with
MEM[(volatile ...*)nonvolvar][tmp_Y] ={v} ...;
where the LHS is no longer TREE_THIS_VOLATILE like before,
TREE_THIS_VOLATILE is newly only the MEM_REF operand of the non-volatile
ARRAY_REF. This patch copies the TREE_THIS_VOLATILE bit to the ARRAY_REF.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2011-11-28 Jakub Jelinek ja...@redhat.com
PR tree-optimization/50078
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Copy over
TREE_THIS_VOLATILE also from the old to new lhs resp. rhs.
* gcc.dg/pr50078.c: New test.
--- gcc/tree-ssa-forwprop.c.jj 2011-10-20 14:13:43.0 +0200
+++ gcc/tree-ssa-forwprop.c 2011-11-28 09:47:39.822697552 +0100
@@ -910,7 +910,7 @@ forward_propagate_addr_expr_1 (tree name
TREE_TYPE (gimple_assign_rhs1 (use_stmt
{
tree *def_rhs_basep = TREE_OPERAND (def_rhs, 0);
- tree new_offset, new_base, saved;
+ tree new_offset, new_base, saved, new_lhs;
while (handled_component_p (*def_rhs_basep))
def_rhs_basep = TREE_OPERAND (*def_rhs_basep, 0);
saved = *def_rhs_basep;
@@ -930,8 +930,9 @@ forward_propagate_addr_expr_1 (tree name
new_base, new_offset);
TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (lhs);
TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs);
- gimple_assign_set_lhs (use_stmt,
-unshare_expr (TREE_OPERAND (def_rhs, 0)));
+ new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
+ gimple_assign_set_lhs (use_stmt, new_lhs);
+ TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs);
*def_rhs_basep = saved;
tidy_after_forward_propagate_addr (use_stmt);
/* Continue propagating into the RHS if this was not the
@@ -991,7 +992,7 @@ forward_propagate_addr_expr_1 (tree name
TREE_TYPE (TREE_OPERAND (def_rhs, 0
{
tree *def_rhs_basep = TREE_OPERAND (def_rhs, 0);
- tree new_offset, new_base, saved;
+ tree new_offset, new_base, saved, new_rhs;
while (handled_component_p (*def_rhs_basep))
def_rhs_basep = TREE_OPERAND (*def_rhs_basep, 0);
saved = *def_rhs_basep;
@@ -1011,8 +1012,9 @@ forward_propagate_addr_expr_1 (tree name
new_base, new_offset);
TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (rhs);
TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs);
- gimple_assign_set_rhs1 (use_stmt,
- unshare_expr (TREE_OPERAND (def_rhs, 0)));
+ new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
+ gimple_assign_set_rhs1 (use_stmt, new_rhs);
+ TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs);
*def_rhs_basep = saved;
fold_stmt_inplace (use_stmt_gsi);
tidy_after_forward_propagate_addr (use_stmt);
--- gcc/testsuite/gcc.dg/pr50078.c.jj 2011-11-28 10:03:18.020091603 +0100
+++ gcc/testsuite/gcc.dg/pr50078.c 2011-11-28 10:05:01.533389187 +0100
@@ -0,0 +1,14 @@
+/* PR tree-optimization/50078 */
+/* { dg-do compile } */
+/* { dg-options -O2 } */
+
+unsigned nonvolvar[2];
+
+void
+test (int arg)
+{
+ unsigned v = *(volatile unsigned *) (nonvolvar[arg]);
+ *(volatile unsigned *) (nonvolvar[arg]) = v;
+}
+
+/* { dg-final { scan-assembler-times movl\[^\n\r\]*nonvolvar 2 { target { {
i?86-*-* x86_64-*-* } nonpic } } } } */
Jakub