diff mbox

Fix VTA ICE (PR debug/45259)

Message ID 20100812081028.GM702@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Aug. 12, 2010, 8:10 a.m. UTC
Hi!

When fixing PR42918, I wasn't aware of reload chain pointing also to
insns before basic block (like jump tables) with ->block number of the
following bb.  The moving of notes in that case is both completely
unnecessary (as the jump tables etc. certainly can't cause any register
saves, therefore there is nothing to restore), but doesn't work (both
in that it tries to move around block notes and that it fails assertion
because it sees CODE_LABEL or BARRIER insns, which is neither a NOTE nor
DEBUG_INSN nor last->insn.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
Ok for trunk/4.5?

2010-08-12  Jakub Jelinek  <jakub@redhat.com>

	PR debug/45259
	* caller-save.c (save_call_clobbered_regs): Only swap notes with
	DEBUG_INSNs if n_regs_saved.

	* gcc.dg/pr45259.c: New test.


	Jakub

Comments

Richard Biener Aug. 12, 2010, 8:52 a.m. UTC | #1
On Thu, Aug 12, 2010 at 10:10 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> When fixing PR42918, I wasn't aware of reload chain pointing also to
> insns before basic block (like jump tables) with ->block number of the
> following bb.  The moving of notes in that case is both completely
> unnecessary (as the jump tables etc. certainly can't cause any register
> saves, therefore there is nothing to restore), but doesn't work (both
> in that it tries to move around block notes and that it fails assertion
> because it sees CODE_LABEL or BARRIER insns, which is neither a NOTE nor
> DEBUG_INSN nor last->insn.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
> Ok for trunk/4.5?

Ok.

Thanks,
Richard.

> 2010-08-12  Jakub Jelinek  <jakub@redhat.com>
>
>        PR debug/45259
>        * caller-save.c (save_call_clobbered_regs): Only swap notes with
>        DEBUG_INSNs if n_regs_saved.
>
>        * gcc.dg/pr45259.c: New test.
>
> --- gcc/caller-save.c.jj        2010-08-11 21:08:06.000000000 +0200
> +++ gcc/caller-save.c   2010-08-11 22:23:12.000000000 +0200
> @@ -868,7 +868,10 @@ save_call_clobbered_regs (void)
>             remain saved.  If the last insn in the block is a JUMP_INSN, put
>             the restore before the insn, otherwise, put it after the insn.  */
>
> -         if (DEBUG_INSN_P (insn) && last && last->block == chain->block)
> +         if (n_regs_saved
> +             && DEBUG_INSN_P (insn)
> +             && last
> +             && last->block == chain->block)
>            {
>              rtx ins, prev;
>              basic_block bb = BLOCK_FOR_INSN (insn);
> --- gcc/testsuite/gcc.dg/pr45259.c.jj   2010-08-11 22:12:19.000000000 +0200
> +++ gcc/testsuite/gcc.dg/pr45259.c      2010-08-11 21:43:24.000000000 +0200
> @@ -0,0 +1,42 @@
> +/* PR debug/45259 */
> +/* { dg-do compile } */
> +/* { dg-options "-g -O2 -fpic -w" { target fpic } } */
> +
> +struct S { void (*bar) (long); };
> +struct T { struct S *t; };
> +int w;
> +extern int baz (int);
> +
> +void
> +foo (int x, int u, char *z)
> +{
> +  struct T *v;
> +  static void *y[256] = { &&l1, &&l2 };
> +  for (;;)
> +    switch (x)
> +      {
> +      l2:
> +       x = 9;
> +      case 9:
> +       goto *y[*z++];
> +      case 10:
> +      case 27:
> +      case 54:
> +      case 99:
> +      case 100:
> +      case 120:
> +      case 122:
> +      case 131:
> +      case 132:
> +      case 134:
> +      case 141:
> +      case 142:
> +       v->t->bar (u);
> +       v->t->bar (u);
> +      case 143:
> +       continue;
> +      l1:
> +      default:
> +       baz (w);
> +      }
> +}
>
>        Jakub
>
diff mbox

Patch

--- gcc/caller-save.c.jj	2010-08-11 21:08:06.000000000 +0200
+++ gcc/caller-save.c	2010-08-11 22:23:12.000000000 +0200
@@ -868,7 +868,10 @@  save_call_clobbered_regs (void)
 	     remain saved.  If the last insn in the block is a JUMP_INSN, put
 	     the restore before the insn, otherwise, put it after the insn.  */
 
-	  if (DEBUG_INSN_P (insn) && last && last->block == chain->block)
+	  if (n_regs_saved
+	      && DEBUG_INSN_P (insn)
+	      && last
+	      && last->block == chain->block)
 	    {
 	      rtx ins, prev;
 	      basic_block bb = BLOCK_FOR_INSN (insn);
--- gcc/testsuite/gcc.dg/pr45259.c.jj	2010-08-11 22:12:19.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr45259.c	2010-08-11 21:43:24.000000000 +0200
@@ -0,0 +1,42 @@ 
+/* PR debug/45259 */
+/* { dg-do compile } */
+/* { dg-options "-g -O2 -fpic -w" { target fpic } } */
+
+struct S { void (*bar) (long); };
+struct T { struct S *t; };
+int w;
+extern int baz (int);
+
+void
+foo (int x, int u, char *z)
+{
+  struct T *v;
+  static void *y[256] = { &&l1, &&l2 };
+  for (;;)
+    switch (x)
+      {
+      l2:
+	x = 9;
+      case 9:
+	goto *y[*z++];
+      case 10:
+      case 27:
+      case 54:
+      case 99:
+      case 100:
+      case 120:
+      case 122:
+      case 131:
+      case 132:
+      case 134:
+      case 141:
+      case 142:
+	v->t->bar (u);
+	v->t->bar (u);
+      case 143:
+	continue;
+      l1:
+      default:
+	baz (w);
+      }
+}