diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 56c60bae2a7..4a70dc7dd1b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-01-20 Richard Guenther + + PR tree-optimization/42717 + * tree-ssa-dce.c (get_live_post_dom): Remove. + (forward_edge_to_pdom): Take an arbitrary edge to copy + degenerate PHI args from. + (remove_dead_stmt): Use the first post-dominator even if it + does not contain live statements as redirection destination. + 2010-01-20 Richard Guenther * tree-inline.c (estimate_num_insns): Handle EH builtins. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 476d0fddc1d..6d7c3a6189d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 Richard Guenther + + PR tree-optimization/42717 + * gcc.c-torture/compile/pr42717.c: New testcase. + 2010-01-20 Jakub Jelinek * gcc.dg/cleanup-13.c: Expect DW_OP_mod to do unsigned modulo instead diff --git a/gcc/testsuite/gcc.c-torture/compile/pr42717.c b/gcc/testsuite/gcc.c-torture/compile/pr42717.c new file mode 100644 index 00000000000..4fe6f93e797 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr42717.c @@ -0,0 +1,30 @@ +static signed char +foo (signed char si1, unsigned char si2) +{ + return (si1 ^ si2) & (-si2 ^ si2) ? : si1 - si2; +} + +struct S0 +{ +}; + +unsigned char g_21; + +struct S0 g_34; + +void +bar (unsigned char p_20) +{ + unsigned char *l_22 = &g_21; + unsigned char l_23 = 0; + struct S0 *l = &g_34; + goto lbl_42; + for (; l_23; l_23 = foo (l_23, 1)) + { + for (p_20 = 0; 0; p_20 = foo (p_20, 1)) + lbl_42:; + (l == &g_34) ? 0 : ""; +lbl_85:*l_22 = p_20; + } + goto lbl_85; +} diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index bb24b6254d2..4e3499aa6e1 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -917,27 +917,6 @@ remove_dead_phis (basic_block bb) return something_changed; } -/* Find first live post dominator of BB. */ - -static basic_block -get_live_post_dom (basic_block bb) -{ - basic_block post_dom_bb; - - - /* The post dominance info has to be up-to-date. */ - gcc_assert (dom_info_state (CDI_POST_DOMINATORS) == DOM_OK); - - /* Get the immediate post dominator of bb. */ - post_dom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb); - /* And look for first live one. */ - while (post_dom_bb != EXIT_BLOCK_PTR - && !TEST_BIT (bb_contains_live_stmts, post_dom_bb->index)) - post_dom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, post_dom_bb); - - return post_dom_bb; -} - /* Forward edge E to respective POST_DOM_BB and update PHIs. */ static edge @@ -961,10 +940,9 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) if (!gimple_seq_empty_p (phi_nodes (post_dom_bb))) { /* We are sure that for every live PHI we are seeing control dependent BB. - This means that we can look up the end of control dependent path leading - to the PHI itself. */ + This means that we can pick any edge to duplicate PHI args from. */ FOR_EACH_EDGE (e2, ei, post_dom_bb->preds) - if (e2 != e && dominated_by_p (CDI_POST_DOMINATORS, e->src, e2->src)) + if (e2 != e) break; for (gsi = gsi_start_phis (post_dom_bb); !gsi_end_p (gsi);) { @@ -972,40 +950,27 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) tree op; source_location locus; - /* Dead PHI do not imply control dependency. */ - if (!gimple_plf (phi, STMT_NECESSARY) - && is_gimple_reg (gimple_phi_result (phi))) - { - gsi_next (&gsi); - continue; - } - if (gimple_phi_arg_def (phi, e->dest_idx)) - { - gsi_next (&gsi); - continue; - } - - /* We didn't find edge to update. This can happen for PHIs on virtuals - since there is no control dependency relation on them. We are lost - here and must force renaming of the symbol. */ + /* PHIs for virtuals have no control dependency relation on them. + We are lost here and must force renaming of the symbol. */ if (!is_gimple_reg (gimple_phi_result (phi))) { mark_virtual_phi_result_for_renaming (phi); remove_phi_node (&gsi, true); continue; } - if (!e2) + + /* Dead PHI do not imply control dependency. */ + if (!gimple_plf (phi, STMT_NECESSARY)) { - op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0); - locus = gimple_phi_arg_location (phi, e->dest_idx == 0 ? 1 : 0); - } - else - { - op = gimple_phi_arg_def (phi, e2->dest_idx); - locus = gimple_phi_arg_location (phi, e2->dest_idx); + gsi_next (&gsi); + continue; } + + op = gimple_phi_arg_def (phi, e2->dest_idx); + locus = gimple_phi_arg_location (phi, e2->dest_idx); add_phi_arg (phi, op, e, locus); - gcc_assert (e2 || degenerate_phi_p (phi)); + /* The resulting PHI if not dead can only be degenerate. */ + gcc_assert (degenerate_phi_p (phi)); gsi_next (&gsi); } } @@ -1041,7 +1006,7 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb) edge e, e2; edge_iterator ei; - post_dom_bb = get_live_post_dom (bb); + post_dom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb); e = find_edge (bb, post_dom_bb);