This fixes PR50213 by adding a heuristic to tree forwprop to not propagate simple IV counter increments (similar as how to DOM avoids to CSE them).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2011-09-07 Richard Guenther <rguent...@suse.de> PR tree-optimization/50213 * tree-flow.h (simple_iv_increment_p): Declare. * tree-ssa-dom.c (simple_iv_increment_p): Export. Also handle POINTER_PLUS_EXPR. * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Do not propagate simple IV counter increments. Index: gcc/tree-flow.h =================================================================== *** gcc/tree-flow.h (revision 178628) --- gcc/tree-flow.h (working copy) *************** extern void dump_dominator_optimization_ *** 597,602 **** --- 597,603 ---- extern void debug_dominator_optimization_stats (void); int loop_depth_of_name (tree); tree degenerate_phi_result (gimple); + bool simple_iv_increment_p (gimple); /* In tree-ssa-copy.c */ extern void propagate_value (use_operand_p, tree); Index: gcc/tree-ssa-dom.c =================================================================== *** gcc/tree-ssa-dom.c (revision 178628) --- gcc/tree-ssa-dom.c (working copy) *************** record_equality (tree x, tree y) *** 1409,1417 **** i_1 = phi (..., i_2) i_2 = i_1 +/- ... */ ! static bool simple_iv_increment_p (gimple stmt) { tree lhs, preinc; gimple phi; size_t i; --- 1409,1418 ---- i_1 = phi (..., i_2) i_2 = i_1 +/- ... */ ! bool simple_iv_increment_p (gimple stmt) { + enum tree_code code; tree lhs, preinc; gimple phi; size_t i; *************** simple_iv_increment_p (gimple stmt) *** 1423,1434 **** if (TREE_CODE (lhs) != SSA_NAME) return false; ! if (gimple_assign_rhs_code (stmt) != PLUS_EXPR ! && gimple_assign_rhs_code (stmt) != MINUS_EXPR) return false; preinc = gimple_assign_rhs1 (stmt); - if (TREE_CODE (preinc) != SSA_NAME) return false; --- 1424,1436 ---- if (TREE_CODE (lhs) != SSA_NAME) return false; ! code = gimple_assign_rhs_code (stmt); ! if (code != PLUS_EXPR ! && code != MINUS_EXPR ! && code != POINTER_PLUS_EXPR) return false; preinc = gimple_assign_rhs1 (stmt); if (TREE_CODE (preinc) != SSA_NAME) return false; Index: gcc/tree-ssa-forwprop.c =================================================================== *** gcc/tree-ssa-forwprop.c (revision 178628) --- gcc/tree-ssa-forwprop.c (working copy) *************** ssa_forward_propagate_and_combine (void) *** 2377,2397 **** else gsi_next (&gsi); } ! else if (code == POINTER_PLUS_EXPR && can_propagate_from (stmt)) { ! if (TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST /* ??? Better adjust the interface to that function instead of building new trees here. */ && forward_propagate_addr_expr ! (lhs, ! build1 (ADDR_EXPR, ! TREE_TYPE (rhs), ! fold_build2 (MEM_REF, ! TREE_TYPE (TREE_TYPE (rhs)), ! rhs, ! fold_convert ! (ptr_type_node, ! gimple_assign_rhs2 (stmt)))))) { release_defs (stmt); todoflags |= TODO_remove_unused_locals; --- 2377,2399 ---- else gsi_next (&gsi); } ! else if (code == POINTER_PLUS_EXPR) { ! tree off = gimple_assign_rhs2 (stmt); ! if (TREE_CODE (off) == INTEGER_CST ! && can_propagate_from (stmt) ! && !simple_iv_increment_p (stmt) /* ??? Better adjust the interface to that function instead of building new trees here. */ && forward_propagate_addr_expr ! (lhs, ! build1_loc (gimple_location (stmt), ! ADDR_EXPR, TREE_TYPE (rhs), ! fold_build2 (MEM_REF, ! TREE_TYPE (TREE_TYPE (rhs)), ! rhs, ! fold_convert (ptr_type_node, ! off))))) { release_defs (stmt); todoflags |= TODO_remove_unused_locals;