Created attachment 24070 [details] reduced testcase Compiler output: $ gcc -O -foptimize-sibling-calls -fsched2-use-superblocks -fschedule-insns2 -mtune=core2 testcase.c testcase.c: In function 'internal_state_transition': testcase.c:73:1: error: missing barrier after block 6 testcase.c:73:1: internal compiler error: verify_flow_info failed Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. Tested revisions: r172826 - crash 4.6 r172337 - crash 4.5 r172337 - crash
GCC 4.6.1 is being released.
Compiles OK with gcc 4.7.0 20110801 (experimental) [trunk revision 176998].
Fails for me with 4.7.0 20110823 (experimental) [trunk revision 178018] (x86_64-unknown-linux-gnu). gcc -O -foptimize-sibling-calls -fsched2-use-superblocks -fschedule-insns2 -mtune=core2 t.c Note the tune at the end.
begin_move_insn is not creating the needed barrier.
GCC 4.6.2 is being released.
Slightly reduced testcase: /* PR rtl-optimization/48721 */ /* { dg-do compile } */ /* { dg-options "-O -foptimize-sibling-calls -fsched2-use-superblocks -fschedule-insns2 -mtune=core2" } */ extern unsigned char a[]; extern int b[], d[], e[], f[], g[], *h[], m[], *n[], o[]; extern char c[]; struct S { unsigned char s1; int s2, s3, s4, s5, s6, s7, s8; }; __attribute__((noinline, noclone)) int foo (int x) { return 0; } int bar (int x, struct S *y) { int z; switch (x) { case 1: case 2: { int t2, t4, t5, t6, t7, t8; z = o[y->s8 * 6]; t8 = *n[m[x] * 5]; t4 = *h[y->s7]; t7 = z; z = g[f[x] + y->s6]; t6 = e[y->s5]; t5 = d[c[x] + y->s3 * 17]; if (z) t2 = b[z]; if (a[z] != y->s1) return foo (x); y->s8 = t8; y->s4 = t4; y->s7 = t7; y->s6 = t6; y->s5 = t5; y->s2 = t2; } } return 0; }
Created attachment 25951 [details] gcc47-pr48721.patch begin_move_insn can be easily fixed, the question is why we try to schedule the tail call insn over the restore of r12, which is a call saved register and therefore has to be restored.
Vlad, could you please look at that?
Created attachment 25952 [details] gcc47-pr48721.patch Perhaps we should just consider tail calls as full barriers like asm volatile etc., scheduling some insn after them doesn't make much sense, that is just a fancy way of removing them and I'd hope that insn removal is the job of DCE and similar optimizations, but not of the scheduler.
Author: jakub Date: Wed Nov 30 18:53:46 2011 New Revision: 181855 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181855 Log: PR rtl-optimization/48721 * sched-ebb.c (begin_move_insn): Insert empty unreachable block after BARRIER if insn is followed by it. Modified: trunk/gcc/ChangeLog trunk/gcc/sched-ebb.c
Author: jakub Date: Wed Nov 30 18:58:33 2011 New Revision: 181856 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181856 Log: PR rtl-optimization/48721 * sched-deps.c (sched_analyze_insn): For SIBLING_CALL_P set reg_pending_barrier to TRUE_BARRIER. * gcc.target/i386/pr48721.c: New test. Added: trunk/gcc/testsuite/gcc.target/i386/pr48721.c Modified: trunk/gcc/ChangeLog trunk/gcc/sched-deps.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk so far.
Author: jakub Date: Thu Dec 8 13:33:58 2011 New Revision: 182111 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182111 Log: Backport from mainline 2011-11-30 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/48721 * sched-deps.c (sched_analyze_insn): For SIBLING_CALL_P set reg_pending_barrier to TRUE_BARRIER. * gcc.target/i386/pr48721.c: New test. Added: branches/gcc-4_6-branch/gcc/testsuite/gcc.target/i386/pr48721.c Modified: branches/gcc-4_6-branch/gcc/ChangeLog branches/gcc-4_6-branch/gcc/sched-deps.c branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Fixed.