This extends the previous fix for the CFG cleanup issue WRT dead SSA defs to properly avoid doing sth fancy with conditons in the first pass.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2015-12-16 Richard Biener <rguent...@suse.de> PR tree-optimization/68870 * tree-cfgcleanup.c (cleanup_control_expr_graph): Add first_p parameter, if set only perform trivial constant folding. Queue other blocks with conditions for later processing. (cleanup_control_flow_bb): Add first_p parameter and pass it through. (cleanup_tree_cfg_1): Pass true for the first iteration cleanup_control_expr_graph. * gcc.dg/torture/pr68870.c: New testcase. Index: gcc/tree-cfgcleanup.c =================================================================== --- gcc/tree-cfgcleanup.c (revision 231673) +++ gcc/tree-cfgcleanup.c (working copy) @@ -78,7 +78,8 @@ remove_fallthru_edge (vec<edge, va_gc> * at block BB. */ static bool -cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi) +cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi, + bool first_p) { edge taken_edge; bool retval = false; @@ -95,15 +96,26 @@ cleanup_control_expr_graph (basic_block switch (gimple_code (stmt)) { case GIMPLE_COND: - { - code_helper rcode; - tree ops[3] = {}; - if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges, - no_follow_ssa_edges) - && rcode == INTEGER_CST) - val = ops[0]; - break; - } + /* During a first iteration on the CFG only remove trivially + dead edges but mark other conditions for re-evaluation. */ + if (first_p) + { + val = const_binop (gimple_cond_code (stmt), boolean_type_node, + gimple_cond_lhs (stmt), + gimple_cond_rhs (stmt)); + if (! val) + bitmap_set_bit (cfgcleanup_altered_bbs, bb->index); + } + else + { + code_helper rcode; + tree ops[3] = {}; + if (gimple_simplify (stmt, &rcode, ops, NULL, no_follow_ssa_edges, + no_follow_ssa_edges) + && rcode == INTEGER_CST) + val = ops[0]; + } + break; case GIMPLE_SWITCH: val = gimple_switch_index (as_a <gswitch *> (stmt)); @@ -176,7 +188,7 @@ cleanup_call_ctrl_altering_flag (gimple true if anything changes. */ static bool -cleanup_control_flow_bb (basic_block bb) +cleanup_control_flow_bb (basic_block bb, bool first_p) { gimple_stmt_iterator gsi; bool retval = false; @@ -199,7 +211,7 @@ cleanup_control_flow_bb (basic_block bb) || gimple_code (stmt) == GIMPLE_SWITCH) { gcc_checking_assert (gsi_stmt (gsi_last_bb (bb)) == stmt); - retval |= cleanup_control_expr_graph (bb, gsi); + retval |= cleanup_control_expr_graph (bb, gsi, first_p); } else if (gimple_code (stmt) == GIMPLE_GOTO && TREE_CODE (gimple_goto_dest (stmt)) == ADDR_EXPR @@ -680,7 +692,7 @@ cleanup_tree_cfg_1 (void) { bb = BASIC_BLOCK_FOR_FN (cfun, i); if (bb) - retval |= cleanup_control_flow_bb (bb); + retval |= cleanup_control_flow_bb (bb, true); } /* After doing the above SSA form should be valid (or an update SSA @@ -708,7 +720,7 @@ cleanup_tree_cfg_1 (void) if (!bb) continue; - retval |= cleanup_control_flow_bb (bb); + retval |= cleanup_control_flow_bb (bb, false); retval |= cleanup_tree_cfg_bb (bb); } Index: gcc/testsuite/gcc.dg/torture/pr68870.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr68870.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr68870.c (working copy) @@ -0,0 +1,29 @@ +/* { dg-do compile } */ + +int printf (const char *, ...); + +int a, f, g; +char b, d; +short c; +static short e; + +char +fn1 () +{ + for (; b; b++) + { + int h = 5; + for (a = 0; a < 1; a++) + { + for (d = 0; d < 1; d++) + for (c = 0; c < 1; c++) + for (; e >= 0;) + return 5; + if (f) + h = 0; + } + if (h) + printf ("%d", 0); + } + return g; +}