http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50213
--- Comment #4 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-09-07 08:59:01 UTC --- With Index: gcc/tree-ssa-forwprop.c =================================================================== --- gcc/tree-ssa-forwprop.c (revision 178628) +++ gcc/tree-ssa-forwprop.c (working copy) @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. #include "flags.h" #include "gimple.h" #include "expr.h" +#include "cfgloop.h" /* This pass propagates the RHS of assignment statements into use sites of the LHS of the assignment. It's basically a specialized @@ -1069,10 +1070,11 @@ forward_propagate_addr_expr (tree name, continue; } - /* If the use is in a deeper loop nest, then we do not want - to propagate non-invariant ADDR_EXPRs into the loop as that - is likely adding expression evaluations into the loop. */ - if (gimple_bb (use_stmt)->loop_depth > stmt_loop_depth + /* If the use is in a different loop nest, then we do not want + to propagate non-invariant ADDR_EXPRs into or out of the loop + as that is likely adding expression evaluations into the loop + or extends register lifetimes across loop boundaries. */ + if (gimple_bb (use_stmt)->loop_depth != stmt_loop_depth && !is_gimple_min_invariant (rhs)) { all = false; @@ -2322,6 +2324,13 @@ ssa_forward_propagate_and_combine (void) { basic_block bb; unsigned int todoflags = 0; + bool cleanup_loops = false; + + if (!current_loops) + { + loop_optimizer_init (LOOPS_NORMAL); + cleanup_loops = true; + } cfg_changed = false; @@ -2517,6 +2526,9 @@ ssa_forward_propagate_and_combine (void) } } + if (cleanup_loops) + loop_optimizer_finalize (); + if (cfg_changed) todoflags |= TODO_cleanup_cfg; This is fixed. Of course computing loops all over the place is ... not the cheapest thing. I'll see if we can easily avoid some of them.