This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix ICE when threading jump to exit block
- From: Jakub Jelinek <jakub at redhat dot com>
- To: rth at redhat dot com, jh at suse dot cz
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 29 Dec 2001 23:45:30 +0100
- Subject: [PATCH] Fix ICE when threading jump to exit block
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
It looks like cfgrtl.c needs to be more careful about target == EXIT_BLOCK_PTR.
The following testcase ICEs at -O and up on i386.
We have to bail jump redirecting if we need non-NULL block_label (target)
and target is EXIT_BLOCK_PTR. redirect_jump is able to cope with it,
provided machine description has appropriate patterns (with (return)), but
definitely shouldn't abort() if the machine description doesn't provide
them.
Ok to commit, provided pending bootstrap/regression testing succeeds?
2001-12-29 Jakub Jelinek <jakub@redhat.com>
* cfgrtl.c (try_redirect_by_replacing_jump): Allow redirect_jump
to fail if target is EXIT_BLOCK_PTR, die otherwise.
(redirect_edge_and_branch): Likewise.
* cfgcleanup.c (try_forward_edge): Don't force jump redirecting
if target is EXIT_BLOCK_PTR.
* gcc.c-torture/compile/20011229-2.c: New test.
--- gcc/testsuite/gcc.c-torture/compile/20011229-2.c.jj Sun Dec 30 00:49:00 2001
+++ gcc/testsuite/gcc.c-torture/compile/20011229-2.c Sun Dec 30 00:48:52 2001
@@ -0,0 +1,17 @@
+/* Test whether jump threading doesn't ICE if redirecting the jump to exit
+ block. */
+
+extern int bar ();
+extern void baz ();
+
+void foo ()
+{
+ int x;
+
+ do
+ {
+ if ((x = bar ()) == 1)
+ baz ();
+ }
+ while (x == 1);
+}
--- gcc/cfgrtl.c.jj Sat Dec 29 22:11:40 2001
+++ gcc/cfgrtl.c Sun Dec 30 00:38:22 2001
@@ -687,9 +687,18 @@ try_redirect_by_replacing_jump (e, targe
if (rtl_dump_file)
fprintf (rtl_dump_file, "Redirecting jump %i from %i to %i.\n",
INSN_UID (insn), e->dest->index, target->index);
- redirect_jump (insn, block_label (target), 0);
+ if (!redirect_jump (insn, block_label (target), 0))
+ {
+ if (target == EXIT_BLOCK_PTR)
+ return false;
+ abort ();
+ }
}
+ /* Cannot do anything for target exit block. */
+ else if (target == EXIT_BLOCK_PTR)
+ return false;
+
/* Or replace possibly complicated jump insn by simple jump insn. */
else
{
@@ -806,6 +815,8 @@ redirect_edge_and_branch (e, target)
int j;
rtx new_label = block_label (target);
+ if (target == EXIT_BLOCK_PTR)
+ return false;
if (GET_CODE (PATTERN (tmp)) == ADDR_VEC)
vec = XVEC (PATTERN (tmp), 0);
else
@@ -843,11 +854,18 @@ redirect_edge_and_branch (e, target)
return false;
/* If the insn doesn't go where we think, we're confused. */
- if (JUMP_LABEL (insn) != old_label
- /* If the substitution doesn't succeed, die. This can happen
- if the back end emitted unrecognizable instructions. */
- || !redirect_jump (insn, block_label (target), 0))
+ if (JUMP_LABEL (insn) != old_label)
abort ();
+
+ /* If the substitution doesn't succeed, die. This can happen
+ if the back end emitted unrecognizable instructions or if
+ target is exit block on some arches. */
+ if (!redirect_jump (insn, block_label (target), 0))
+ {
+ if (target == EXIT_BLOCK_PTR)
+ return false;
+ abort ();
+ }
}
if (rtl_dump_file)
--- gcc/cfgcleanup.c.jj Thu Dec 27 13:49:23 2001
+++ gcc/cfgcleanup.c Sun Dec 30 00:44:13 2001
@@ -440,7 +440,8 @@ try_forward_edges (mode, b)
int edge_probability = e->probability;
int edge_frequency;
- if (threaded)
+ /* Don't force if target is exit block. */
+ if (threaded && target != EXIT_BLOCK_PTR)
{
notice_new_block (redirect_edge_and_branch_force (e, target));
if (rtl_dump_file)
Jakub