[Bug rtl-optimization/33676] libgfortran bootstrap failure: selected_int_kind.f90:22: Segmentation fault, wrong code with -fomit-frame-pointer

zadeck at naturalbridge dot com gcc-bugzilla@gcc.gnu.org
Thu Oct 11 22:35:00 GMT 2007



------- 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 <zadeck@naturalbridge.com>

    PR middle-end/33676
    * global.c (build_insn_chain): Include insn that occur between
    basic blocks.

2007-10-11  Kenneth Zadeck <zadeck@naturalbridge.com>

    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 <zadeck@naturalbridge.com>
+
+       PR middle-end/33676
+       * global.c (build_insn_chain): Include insn that occur between
+       basic blocks.
+       
 2007-10-11  Tom Tromey  <tromey@redhat.com>

        * 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 <zadeck@naturalbridge.com>
+
+       PR middle-end/33676
+       * gcc.dg/torture/pr33676.c: New.
+
 2007-10-11  Paolo Carlini  <pcarlini@suse.de>

        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



More information about the Gcc-bugs mailing list