diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2005-04-02 17:02:15 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2005-04-02 17:02:15 +0000 |
commit | e18d4a1904df31796cd4f10df5fb44fa9ef68d17 (patch) | |
tree | 11878561a726f557b6264d3b578b755ffe510bb9 /gcc | |
parent | bbe3791247584e9b520a0a7afdc14acea321678a (diff) | |
download | gcc-e18d4a1904df31796cd4f10df5fb44fa9ef68d17.zip gcc-e18d4a1904df31796cd4f10df5fb44fa9ef68d17.tar.gz gcc-e18d4a1904df31796cd4f10df5fb44fa9ef68d17.tar.bz2 |
re PR tree-optimization/20640 (ICE on NULL PHI_ARG_DEF)
gcc/ChangeLog:
PR tree-optimization/20640
* tree-ssa-dce.c (remove_dead_stmt): Don't redirect edge to
post-dominator if it has phi nodes.
(eliminate_unnecessary_stmts): Remove dead phis in all blocks
before dead statements.
gcc/testsuite/ChangeLog:
PR tree-optimization/20640
* gcc.dg/torture/tree-loop-1.c: New.
From-SVN: r97446
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/tree-loop-1.c | 21 | ||||
-rw-r--r-- | gcc/tree-ssa-dce.c | 21 |
4 files changed, 52 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d03fcf9..3cb960e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2005-04-02 Alexandre Oliva <aoliva@redhat.com> + PR tree-optimization/20640 + * tree-ssa-dce.c (remove_dead_stmt): Don't redirect edge to + post-dominator if it has phi nodes. + (eliminate_unnecessary_stmts): Remove dead phis in all blocks + before dead statements. + +2005-04-02 Alexandre Oliva <aoliva@redhat.com> + PR middle-end/20491 * final.c (alter_subreg): Don't call subreg_regno for a non-REG. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c2a4928..1264cf7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2005-04-02 Alexandre Oliva <aoliva@redhat.com> + PR tree-optimization/20640 + * gcc.dg/torture/tree-loop-1.c: New. + +2005-04-02 Alexandre Oliva <aoliva@redhat.com> + PR rtl-optimization/20290 * gcc.c-torture/execute/loop-ivopts-2.c: New. diff --git a/gcc/testsuite/gcc.dg/torture/tree-loop-1.c b/gcc/testsuite/gcc.dg/torture/tree-loop-1.c new file mode 100644 index 0000000..1d38691 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/tree-loop-1.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/20640 */ + +/* After unrolling the loop, we'd turn some conditional branches into + unconditional ones, but branch redirection would fail to compute + the PHI args for the PHI nodes in the replacement edge + destination, so they'd remain NULL causing crashes later on. */ + +/* { dg-do compile } */ + +static int a = 0; +extern int foo (void); +extern int *bar (void) __attribute__ ((__const__)); + +void +test (int x) +{ + int b = 10; + while (foo () == -1 && *bar () == 4 && b > 0) + --b; + a = x; +} diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index f8946bc..dc388ee 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -637,7 +637,10 @@ eliminate_unnecessary_stmts (void) { /* Remove dead PHI nodes. */ remove_dead_phis (bb); + } + FOR_EACH_BB (bb) + { /* Remove dead statements. */ for (i = bsi_start (bb); ! bsi_end_p (i) ; ) { @@ -724,6 +727,7 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb) if (is_ctrl_stmt (t)) { basic_block post_dom_bb; + /* The post dominance info has to be up-to-date. */ gcc_assert (dom_computed[CDI_POST_DOMINATORS] == DOM_OK); /* Get the immediate post dominator of bb. */ @@ -737,9 +741,20 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb) return; } - /* Redirect the first edge out of BB to reach POST_DOM_BB. */ - redirect_edge_and_branch (EDGE_SUCC (bb, 0), post_dom_bb); - PENDING_STMT (EDGE_SUCC (bb, 0)) = NULL; + /* If the post dominator block has PHI nodes, we might be unable + to compute the right PHI args for them. Since the control + statement is unnecessary, all edges can be regarded as + equivalent, but we have to get rid of the condition, since it + might reference a variable that was determined to be + unnecessary and thus removed. */ + if (phi_nodes (post_dom_bb)) + post_dom_bb = EDGE_SUCC (bb, 0)->dest; + else + { + /* Redirect the first edge out of BB to reach POST_DOM_BB. */ + redirect_edge_and_branch (EDGE_SUCC (bb, 0), post_dom_bb); + PENDING_STMT (EDGE_SUCC (bb, 0)) = NULL; + } EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE; EDGE_SUCC (bb, 0)->count = bb->count; |