aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2005-04-02 17:02:15 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2005-04-02 17:02:15 +0000
commite18d4a1904df31796cd4f10df5fb44fa9ef68d17 (patch)
tree11878561a726f557b6264d3b578b755ffe510bb9 /gcc
parentbbe3791247584e9b520a0a7afdc14acea321678a (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/tree-loop-1.c21
-rw-r--r--gcc/tree-ssa-dce.c21
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;