diff mbox

Fix ICE with asm goto and shrink wrapping (PR rtl-optimization/53589)

Message ID 20120607065307.GN24904@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek June 7, 2012, 6:53 a.m. UTC
Hi!

On the following testcase we ICE, because shrink-wrapping ends up
calling force_nonfallthru_and_redirect on a BB that ends with
asm goto that has some labels point to the fallthru block as well
(i.e. asm goto ("..." : : : : lab); lab:;).  The problem was that in
that case the labels weren't adjusted and as it initially shared the
edge with the normal fallthru, the bb with the referenced labels has
been removed as unreachable soon afterwards.

Fixed by adjusting the labels and handling the edges properly afterwards
(similarly how we handle labels already pointing to the target before).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk
and 4.7.2?

2012-06-07  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/53589
	* cfgrtl.c (force_nonfallthru_and_redirect): Do asm_goto_edge
	discovery even when e->dest != target.  If any LABEL_REF points
	to e->dest label, redirect it to target's label.

	* gcc.dg/torture/pr53589.c: New test.


	Jakub

Comments

Richard Henderson June 11, 2012, 9:55 p.m. UTC | #1
On 2012-06-06 23:53, Jakub Jelinek wrote:
> 2012-06-07  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR rtl-optimization/53589
> 	* cfgrtl.c (force_nonfallthru_and_redirect): Do asm_goto_edge
> 	discovery even when e->dest != target.  If any LABEL_REF points
> 	to e->dest label, redirect it to target's label.
> 
> 	* gcc.dg/torture/pr53589.c: New test.

Ok.


r~
diff mbox

Patch

--- gcc/cfgrtl.c.jj	2012-06-01 14:41:05.000000000 +0200
+++ gcc/cfgrtl.c	2012-06-06 14:42:53.260826375 +0200
@@ -1293,21 +1293,21 @@  force_nonfallthru_and_redirect (edge e,
     }
 
   /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
-     don't point to target label.  */
+     don't point to the target or fallthru label.  */
   if (JUMP_P (BB_END (e->src))
       && target != EXIT_BLOCK_PTR
-      && e->dest == target
       && (e->flags & EDGE_FALLTHRU)
       && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
     {
       int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
 
       for (i = 0; i < n; ++i)
-	if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
-	  {
+	{
+	  if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (e->dest))
+	    XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target);
+	  if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
 	    asm_goto_edge = true;
-	    break;
-	  }
+	}
     }
 
   if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
--- gcc/testsuite/gcc.dg/torture/pr53589.c.jj	2012-06-06 14:55:40.169197226 +0200
+++ gcc/testsuite/gcc.dg/torture/pr53589.c	2012-06-06 14:57:44.644447827 +0200
@@ -0,0 +1,15 @@ 
+/* PR rtl-optimization/53589 */
+/* { dg-do compile } */
+
+extern void foo (void) __attribute__ ((__noreturn__));
+
+void
+bar (int x)
+{
+  if (x < 0)
+    foo ();
+  if (x == 0)
+    return;
+  __asm goto ("# %l[lab]" : : : : lab);
+lab:;
+}