diff mbox

Fix force_nonfallthru_and_redirect with asm goto (PR rtl-optimization/54127)

Message ID 20121112194845.GT1886@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 12, 2012, 7:48 p.m. UTC
Hi!

The following testcase was ICEing on powerpc64-linux.
While force_nonfallthru_and_redirect properly adjusted the LABEL_REFs
in asm goto from the old fallthru block to a new one, it didn't adjust
LABEL_NUSES and didn't adjust JUMP_LABEL resp. REG_LABEL_TARGET.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk (and 4.7 after say a week)?

2012-11-12  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/54127
	* cfgrtl.c (force_nonfallthru_and_redirect): When redirecting
	asm goto labels from BB_HEAD (e->dest) to target bb, decrement
	LABEL_NUSES of BB_HEAD (e->dest) and increment LABEL_NUSES of
	BB_HEAD (target) appropriately and adjust JUMP_LABEL and/or
	REG_LABEL_TARGET and REG_LABEL_OPERAND.

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


	Jakub

Comments

Richard Henderson Nov. 12, 2012, 8:20 p.m. UTC | #1
On 11/12/2012 11:48 AM, Jakub Jelinek wrote:
> 2012-11-12  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR rtl-optimization/54127
> 	* cfgrtl.c (force_nonfallthru_and_redirect): When redirecting
> 	asm goto labels from BB_HEAD (e->dest) to target bb, decrement
> 	LABEL_NUSES of BB_HEAD (e->dest) and increment LABEL_NUSES of
> 	BB_HEAD (target) appropriately and adjust JUMP_LABEL and/or
> 	REG_LABEL_TARGET and REG_LABEL_OPERAND.
> 
> 	* gcc.dg/torture/pr54127.c: New test.

Ok


r~
diff mbox

Patch

--- gcc/cfgrtl.c.jj	2012-11-05 08:55:21.000000000 +0100
+++ gcc/cfgrtl.c	2012-11-12 11:06:32.254919581 +0100
@@ -1424,14 +1424,46 @@  force_nonfallthru_and_redirect (edge e,
       && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
     {
       int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+      bool adjust_jump_target = false;
 
       for (i = 0; i < n; ++i)
 	{
 	  if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (e->dest))
-	    XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target);
+	    {
+	      LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))--;
+	      XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target);
+	      LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))++;
+	      adjust_jump_target = true;
+	    }
 	  if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
 	    asm_goto_edge = true;
 	}
+      if (adjust_jump_target)
+	{
+	  rtx insn = BB_END (e->src), note;
+	  rtx old_label = BB_HEAD (e->dest);
+	  rtx new_label = BB_HEAD (target);
+
+	  if (JUMP_LABEL (insn) == old_label)
+	    {
+	      JUMP_LABEL (insn) = new_label;
+	      note = find_reg_note (insn, REG_LABEL_TARGET, new_label);
+	      if (note)
+		remove_note (insn, note);
+	    }
+	  else
+	    {
+	      note = find_reg_note (insn, REG_LABEL_TARGET, old_label);
+	      if (note)
+		remove_note (insn, note);
+	      if (JUMP_LABEL (insn) != new_label
+		  && !find_reg_note (insn, REG_LABEL_TARGET, new_label))
+		add_reg_note (insn, REG_LABEL_TARGET, new_label);
+	    }
+	  while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label))
+		 != NULL_RTX)
+	    XEXP (note, 0) = new_label;
+	}
     }
 
   if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
--- gcc/testsuite/gcc.dg/torture/pr54127.c.jj	2012-11-12 11:13:45.422433593 +0100
+++ gcc/testsuite/gcc.dg/torture/pr54127.c	2012-11-12 11:09:07.000000000 +0100
@@ -0,0 +1,16 @@ 
+/* PR rtl-optimization/54127 */
+/* { 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] %l[lab2]" : : : : lab, lab2);
+lab:;
+lab2:;
+}