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  <ja...@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.

--- 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:;
+}

        Jakub

Reply via email to