------- Comment #20 from zadeck at naturalbridge dot com 2007-10-11 22:35 ------- Subject: Re: libgfortran bootstrap failure: selected_int_kind.f90:22: Segmentation fault, wrong code with -fomit-frame-pointer
zadeck at naturalbridge dot com wrote: > ------- Comment #17 from zadeck at naturalbridge dot com 2007-10-11 16:21 > ------- > Subject: Re: libgfortran bootstrap failure: selected_int_kind.f90:22: > Segmentation fault, wrong code with -fomit-frame-pointer > > > > When I rewrote this code to use backward scanning rather than forwards > scanning, I converted it to properly use the cfg, since it is generally > considered outmoded to just scan the insns. > > However, the reload_insn_chain actually needs the insns that appear > between basic blocks, in particular the labels in front of branch > tables. I added code here to check for insns that may be in front of a > basic block after scanning that block. > > There are a lot of ways that I could have done this, for instance, I > could have just written in terms of the PREV_INSN as the old code was. > I think that in doing it the way that i have done it, it is obvious what > needs to be done if someone really does get rid of the branch tables > between the blocks. > > This has been bootstrapped and regression tested on x86-{64,32} ppc-32, > and ia-64. However it is not clear to me how many platforms use this > kind of table branch. The bug appears to only be on the -march=i586, so > the reviewers may wish to comment on my choice of dg options on the test. > > 2007-10-11 Kenneth Zadeck <[EMAIL PROTECTED]> PR middle-end/33676 * global.c (build_insn_chain): Include insn that occur between basic blocks. 2007-10-11 Kenneth Zadeck <[EMAIL PROTECTED]> PR middle-end/33676 * gcc.dg/torture/pr33676.c: New. bootstrapped and regression tested on x86-32 x86-64, ppc-32 and ia-64. committed as revision 129244. Kenny Index: ChangeLog =================================================================== --- ChangeLog (revision 129243) +++ ChangeLog (working copy) @@ -1,3 +1,9 @@ +2007-10-11 Kenneth Zadeck <[EMAIL PROTECTED]> + + PR middle-end/33676 + * global.c (build_insn_chain): Include insn that occur between + basic blocks. + 2007-10-11 Tom Tromey <[EMAIL PROTECTED]> * gengtype-yacc.y: Delete. Index: testsuite/gcc.dg/torture/pr33676.c =================================================================== --- testsuite/gcc.dg/torture/pr33676.c (revision 0) +++ testsuite/gcc.dg/torture/pr33676.c (revision 0) @@ -0,0 +1,51 @@ +/* { dg-do run } */ +/* { dg-options "-march=i586 -fomit-frame-pointer" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +__attribute__((noreturn,noinline)) void abrt (const char *fi, const char *fu) +{ + __builtin_abort (); +} + +__attribute__((noinline)) int f (int k) +{ + return k; +} + +__attribute__((noinline)) int g (int t, int k) +{ + int b; + + switch (t) + { + case 0: + abrt (__FILE__, __FUNCTION__); + + case 1: + b = f (k); + break; + + case 2: + b = f (k); + break; + + case 3: + b = f (k); + break; + + case 4: + b = f (k); + break; + + default: + abrt (__FILE__, __FUNCTION__); + } + + return b; +} + +int main (void) +{ + if (g (3, 1337) != 1337) + abrt (__FILE__, __FUNCTION__); + return 0; +} Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 129243) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2007-10-11 Kenneth Zadeck <[EMAIL PROTECTED]> + + PR middle-end/33676 + * gcc.dg/torture/pr33676.c: New. + 2007-10-11 Paolo Carlini <[EMAIL PROTECTED]> PR c++/31441 Index: global.c =================================================================== --- global.c (revision 129243) +++ global.c (working copy) @@ -1575,6 +1575,41 @@ build_insn_chain (void) } } } + + /* FIXME!! The following code is a disaster. Reload needs to see the + labels and jump tables that are just hanging out in between + the basic blocks. See pr33676. */ + + insn = BB_HEAD (bb); + + /* Skip over the barriers and cruft. */ + while (insn && (BARRIER_P (insn) || NOTE_P (insn) || BLOCK_FOR_INSN (insn) == bb)) + insn = PREV_INSN (insn); + + /* While we add anything except barriers and notes, the focus is + to get the labels and jump tables into the + reload_insn_chain. */ + while (insn) + { + if (!NOTE_P (insn) && !BARRIER_P (insn)) + { + if (BLOCK_FOR_INSN (insn)) + break; + + c = new_insn_chain (); + c->next = next; + next = c; + *p = c; + p = &c->prev; + + c->insn = insn; + /* The block makes no sense here, but it is what the old + code did. */ + c->block = bb->index; + bitmap_copy (&c->live_throughout, live_relevant_regs); + } + insn = PREV_INSN (insn); + } } for (i = 0; i < (unsigned int)max_regno; i++) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33676