During an IRC discussion I noticed that we mark p = &a[i] as volatile p_2 ={v} &a[i_1(D)];
in the operand scanner even though that is not necessary. The following patch properly guards setting the volatile flag on that we are not processing the operands of an ADDR_EXPR currently. Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2011-12-08 Richard Guenther <rguent...@suse.de> * tree-ssa-operands.c (add_stmt_operand): Do not mark stmts volatile when processing operands of an ADDR_EXPR. (get_indirect_ref_operands): Likewise. (get_tmr_operands): Likewise. (get_expr_operands): Likewise. * gcc.dg/volatile3.c: New testcase. Index: gcc/tree-ssa-operands.c =================================================================== --- gcc/tree-ssa-operands.c (revision 182107) +++ gcc/tree-ssa-operands.c (working copy) @@ -668,7 +668,8 @@ add_stmt_operand (tree *var_p, gimple st sym = (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var); /* Mark statements with volatile operands. */ - if (TREE_THIS_VOLATILE (sym)) + if (!(flags & opf_no_vops) + && TREE_THIS_VOLATILE (sym)) gimple_set_has_volatile_ops (stmt, true); if (is_gimple_reg (sym)) @@ -728,7 +729,8 @@ get_indirect_ref_operands (gimple stmt, { tree *pptr = &TREE_OPERAND (expr, 0); - if (TREE_THIS_VOLATILE (expr)) + if (!(flags & opf_no_vops) + && TREE_THIS_VOLATILE (expr)) gimple_set_has_volatile_ops (stmt, true); /* Add the VOP. */ @@ -747,7 +749,8 @@ get_indirect_ref_operands (gimple stmt, static void get_tmr_operands (gimple stmt, tree expr, int flags) { - if (TREE_THIS_VOLATILE (expr)) + if (!(flags & opf_no_vops) + && TREE_THIS_VOLATILE (expr)) gimple_set_has_volatile_ops (stmt, true); /* First record the real operands. */ @@ -914,14 +917,16 @@ get_expr_operands (gimple stmt, tree *ex case REALPART_EXPR: case IMAGPART_EXPR: { - if (TREE_THIS_VOLATILE (expr)) + if (!(flags & opf_no_vops) + && TREE_THIS_VOLATILE (expr)) gimple_set_has_volatile_ops (stmt, true); get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags); if (code == COMPONENT_REF) { - if (TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1))) + if (!(flags & opf_no_vops) + && TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1))) gimple_set_has_volatile_ops (stmt, true); get_expr_operands (stmt, &TREE_OPERAND (expr, 2), uflags); } @@ -960,7 +965,8 @@ get_expr_operands (gimple stmt, tree *ex /* A volatile constructor is actually TREE_CLOBBER_P, transfer the volatility to the statement, don't use TREE_CLOBBER_P for mirroring the other uses of THIS_VOLATILE in this file. */ - if (TREE_THIS_VOLATILE (expr)) + if (!(flags & opf_no_vops) + && TREE_THIS_VOLATILE (expr)) gimple_set_has_volatile_ops (stmt, true); for (idx = 0; @@ -972,7 +978,8 @@ get_expr_operands (gimple stmt, tree *ex } case BIT_FIELD_REF: - if (TREE_THIS_VOLATILE (expr)) + if (!(flags & opf_no_vops) + && TREE_THIS_VOLATILE (expr)) gimple_set_has_volatile_ops (stmt, true); /* FALLTHRU */ Index: gcc/testsuite/gcc.dg/volatile3.c =================================================================== --- gcc/testsuite/gcc.dg/volatile3.c (revision 0) +++ gcc/testsuite/gcc.dg/volatile3.c (revision 0) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-ssa" } */ + +volatile int *q; +void foo(int i) +{ + volatile int a[2]; + volatile int *p = &a[i]; + q = p; +} + +/* { dg-final { scan-tree-dump-not "{v}" "ssa" } } */ +/* { dg-final { cleanup-tree-dump "ssa" } } */