Hello,apparently it is possible to have a PHI in the middle basic block of value_replacement, so I need to move it as well when I move the statement and remove the block.
Bootstrap and testsuite on x86_64-linux-gnu (re-running for various reasons but they had completed successfully yesterday).
2014-06-03 Marc Glisse <marc.gli...@inria.fr> PR tree-optimization/61385 gcc/ * tree-ssa-phiopt.c (value_replacement): Copy PHI nodes before removing the basic block. gcc/testsuite/ * gcc.dg/tree-ssa/pr61385.c: New file. -- Marc Glisse
Index: gcc/testsuite/gcc.dg/tree-ssa/pr61385.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/pr61385.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/pr61385.c (working copy) @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#define assert(x) if (!(x)) __builtin_abort () + +int a, b, c, d, e, f, g; + +int +fn1 () +{ + int *h = &c; + for (; c < 1; c++) + { + int *i = &a, *k = &a; + f = 0; + if (b) + return 0; + if (*h) + { + int **j = &i; + *j = 0; + d = 0; + } + else + g = e = 0; + if (*h) + { + int **l = &k; + *l = &g; + } + d &= *h; + assert (k == &a || k); + assert (i); + } + return 0; +} + +int +main () +{ + fn1 (); + return 0; +} Index: gcc/tree-ssa-phiopt.c =================================================================== --- gcc/tree-ssa-phiopt.c (revision 211178) +++ gcc/tree-ssa-phiopt.c (working copy) @@ -877,20 +877,39 @@ value_replacement (basic_block cond_bb, && operand_equal_for_phi_arg_p (rhs2, cond_lhs) && neutral_element_p (code_def, cond_rhs, true)) || (arg1 == rhs2 && operand_equal_for_phi_arg_p (rhs1, cond_lhs) && neutral_element_p (code_def, cond_rhs, false)) || (operand_equal_for_phi_arg_p (arg1, cond_rhs) && (operand_equal_for_phi_arg_p (rhs2, cond_lhs) || operand_equal_for_phi_arg_p (rhs1, cond_lhs)) && absorbing_element_p (code_def, cond_rhs)))) { + /* Move potential PHI nodes. */ + gimple_stmt_iterator psi = gsi_start_phis (middle_bb); + while (!gsi_end_p (psi)) + { + gimple phi_moving = gsi_stmt (psi); + gimple newphi = create_phi_node (gimple_phi_result (phi_moving), + cond_bb); + int nargs = cond_bb->preds->length(); + location_t loc = gimple_phi_arg_location (phi_moving, 0); + tree phi_arg = gimple_phi_arg_def (phi_moving, 0); + for (int i = 0; i < nargs; ++i) + { + edge e = (*cond_bb->preds)[i]; + add_phi_arg (newphi, phi_arg, e, loc); + } + update_stmt (newphi); + gsi_remove (&psi, false); + } + gsi = gsi_for_stmt (cond); gimple_stmt_iterator gsi_from = gsi_for_stmt (assign); gsi_move_before (&gsi_from, &gsi); replace_phi_edge_with_variable (cond_bb, e1, phi, lhs); return 2; } return 0; }