------- Comment #16 from rguenth at gcc dot gnu dot org 2007-05-12 16:09 ------- And it's update_stmt () that clears the flag. It doesn't consider
(gdb) call debug_tree (stmt) <modify_expr 0xb7c6b384 type <integer_type 0xb7c752e0 unsigned int public unsigned SI size <integer_cst 0xb7c643d8 constant invariant 32> unit size <integer_cst 0xb7c64168 constant invariant 4> align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0xb7c64450 0> max <integer_cst 0xb7c64438 4294967295>> side-effects asm_written visited arg 0 <ssa_name 0xb7cf6d80 type <integer_type 0xb7c752e0 unsigned int> var <var_decl 0xb7c70420 D.1546> def_stmt <modify_expr 0xb7c6b384> version 8> arg 1 <component_ref 0xb7cf2168 type <integer_type 0xb7cfa4ac unsigned int volatile unsigned SI size <integer_cst 0xb7c643d8 32> unit size <integer_cst 0xb7c64168 4> align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0xb7c64450 0> max <integer_cst 0xb7c64438 4294967295>> side-effects volatile arg 0 <array_ref 0xb7c715ac type <record_type 0xb7cfa3f4 GTeth_desc> arg 0 <component_ref 0xb7cf2870 type <array_type 0xb7cfa0b8> arg 0 <indirect_ref 0xb7cf3860 type <record_type 0xb7cfa000 GTeth_softc> arg 0 <ssa_name 0xb7cf6c30 type <pointer_type 0xb7cfa284> var <parm_decl 0xb7cfb0a0 sc> def_stmt <nop_expr 0xb7cf37a0> version 1 ptr-info 0xb7cf0870>> arg 1 <field_decl 0xb7cfa170 txq_desc>> arg 1 <ssa_name 0xb7cf6cc0 type <integer_type 0xb7c752e0 unsigned int> var <var_decl 0xb7c70318 D.1543> def_stmt <modify_expr 0xb7c6b318> version 4> arg 2 <integer_cst 0xb7c64180 constant invariant 0> arg 3 <integer_cst 0xb7c641f8 constant invariant 1>> arg 1 <field_decl 0xb7ceff74 ed_cmdsts type <integer_type 0xb7c752e0 unsigned int> unsigned SI file GT64260eth.c line 3 size <integer_cst 0xb7c643d8 32> unit size <integer_cst 0xb7c64168 4> align 32 offset_align 128 offset <integer_cst 0xb7c64180 0> bit offset <integer_cst 0xb7c64960 constant invariant 0> context <record_type 0xb7ceff18 GTeth_desc>>> GT64260eth.c:24> to have volatile ops just because the COMPONENT_REF has side-effects and wrong types (the field_decl is non-volatile unsigned int while the component_ref is volatile unsigned int). So after update_stmt there is a mismatch. Now what do we want here? Clear the volatileness on the COMPONENT_REF? Or refrain from doing the propagation? Or fix update_ssa? Two of the solutions are like Index: tree-ssa-operands.c =================================================================== --- tree-ssa-operands.c (revision 124635) +++ tree-ssa-operands.c (working copy) @@ -2174,6 +2174,11 @@ build_ssa_operands (tree stmt) operand_build_sort_virtual (build_v_must_defs); finalize_ssa_stmt_operands (stmt); + + /* If the RHS has side-effects, reset has_volatile_ops. */ + if (TREE_CODE (stmt) == MODIFY_EXPR + && TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1))) + ann->has_volatile_ops = true; } and Index: tree-ssa-forwprop.c =================================================================== --- tree-ssa-forwprop.c (revision 124635) +++ tree-ssa-forwprop.c (working copy) @@ -843,15 +843,22 @@ forward_propagate_addr_expr (tree stmt, continue; } - /* If the use is in a deeper loop nest, then we do not want - to propagate the ADDR_EXPR into the loop as that is likely - adding expression evaluations into the loop. */ + /* If the use is in a deeper loop nest, then we do not want + to propagate the ADDR_EXPR into the loop as that is likely + adding expression evaluations into the loop. */ if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth) { all = false; continue; } - + + /* If the use_stmt has side-effects, don't propagate into it. */ + if (stmt_ann (use_stmt)->has_volatile_ops) + { + all = false; + continue; + } + result = forward_propagate_addr_expr_1 (stmt, use_stmt, some); *some |= result; all &= result; where I prefer the first one. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31797