Hi! As documented in tree.h for TREE_THIS_VOLATILE: If this bit is set in an expression, so is TREE_SIDE_EFFECTS. so copying just TREE_THIS_VOLATILE is not sufficient. On 4.6 branch this resulted in ICEs in gimple_rhs_has_side_effects.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed after IRC discussion with richi. 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. --- gcc/tree-ssa-forwprop.c.jj 2011-11-29 08:58:52.000000000 +0100 +++ gcc/tree-ssa-forwprop.c 2011-12-08 15:17:01.474873355 +0100 @@ -929,10 +929,12 @@ forward_propagate_addr_expr_1 (tree name *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep), 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); 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 @@ -1011,10 +1013,12 @@ forward_propagate_addr_expr_1 (tree name *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep), 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); 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_gsi); tidy_after_forward_propagate_addr (use_stmt); --- 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