Message ID | 20100812081028.GM702@tyan-ft48-01.lab.bos.redhat.com |
---|---|
State | New |
Headers | show |
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 >
--- 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); + } +}