Hi! Bootstrapped/regtested on x86_64-linux and i686-linux, committed to 4.6 branch.
2011-12-09 Jakub Jelinek <ja...@redhat.com> Backport from mainline 2011-12-08 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/51466 * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Also copy TREE_SIDE_EFFECTS. * gcc.c-torture/execute/pr51466.c: New test. 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 (revision 181785) +++ gcc/tree-ssa-forwprop.c (revision 181786) @@ -872,7 +872,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; @@ -892,8 +892,11 @@ forward_propagate_addr_expr_1 (tree name new_base, new_offset); TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (lhs); + TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (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); + TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs); *def_rhs_basep = saved; tidy_after_forward_propagate_addr (use_stmt); /* Continue propagating into the RHS if this was not the @@ -953,7 +954,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; @@ -973,8 +974,11 @@ forward_propagate_addr_expr_1 (tree name new_base, new_offset); TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (rhs); + TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (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); + TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs); *def_rhs_basep = saved; fold_stmt_inplace (use_stmt); tidy_after_forward_propagate_addr (use_stmt); --- gcc/testsuite/gcc.dg/pr50078.c (revision 0) +++ gcc/testsuite/gcc.dg/pr50078.c (revision 181786) @@ -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 } } } } */ --- gcc/testsuite/gcc.c-torture/execute/pr51466.c.jj 2011-12-08 15:25:42.084966108 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr51466.c 2011-12-08 15:25:18.000000000 +0100 @@ -0,0 +1,43 @@ +/* PR tree-optimization/51466 */ + +extern void abort (void); + +__attribute__((noinline, noclone)) int +foo (int i) +{ + volatile int v[4]; + int *p; + v[i] = 6; + p = (int *) &v[i]; + return *p; +} + +__attribute__((noinline, noclone)) int +bar (int i) +{ + volatile int v[4]; + int *p; + v[i] = 6; + p = (int *) &v[i]; + *p = 8; + return v[i]; +} + +__attribute__((noinline, noclone)) int +baz (int i) +{ + volatile int v[4]; + int *p; + v[i] = 6; + p = (int *) &v[0]; + *p = 8; + return v[i]; +} + +int +main () +{ + if (foo (3) != 6 || bar (2) != 8 || baz (0) != 8 || baz (1) != 6) + abort (); + return 0; +} Jakub