This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix ICE when threading jump to exit block


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]