From patchwork Thu Aug 12 08:10:28 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix VTA ICE (PR debug/45259) From: Jakub Jelinek X-Patchwork-Id: 61544 Message-Id: <20100812081028.GM702@tyan-ft48-01.lab.bos.redhat.com> To: gcc-patches@gcc.gnu.org Date: Thu, 12 Aug 2010 10:10:28 +0200 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 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 --- 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); + } +}