This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Nonlocal gotos: wrong frame pointer handling


Hello,

I've a problem using nonlocal gotos on S/390. The problem is identified but I need a
hint how to fix it.
The following program causes a segfault compiled on a S/390 (64 and 31 bit) with 

gcc test.c -o test -O2

gcc -v:

Reading specs from /build/cvs/mygcc/lib/gcc/s390x-ibm-linux/3.4/specs
Configured with: ../gcc/configure --prefix=/build/cvs/mygcc --mandir=/usr/share/man 
--infodir=/usr/share/info --enable-threads=posix --enable-shared --with-system-zlib 
--enable-__cxa_atexit --disable-multilib --enable-serial-configure
Thread model: posix
gcc version 3.4 20031020 (experimental)

/* Target S/390 64 and 31 bit.
   Checks whether the literal pool base pointer is saved and restored
   correctly during nonlocal gotos. 
   Failures can also be caused through wrong handling of the hard frame 
   pointer in stmt.c: expand_goto. 
   Created by Andreas Krebbel <krebbel1@de.ibm.com> */
/* { dg-do run } */
/* { dg-options "-O2" } */

static void foo (int * a, int * b)
{
  __label__ foo;

  static void baz (int * c)
  {
    __label__ baz;

    static void bazz ()
      {
	/* Force the compiler to create a literal pool for bazz. */
	*c += 0xbbbbbbbb;

	goto baz;
      }
    bazz();
    
    *c += 0xcccccccc;

  baz:
    goto foo;
  }

  int d;

  *a += 0xaaaaaaaa;

  baz (&d);
 foo:

  *b += 0xaaaaaaaa;
}
int main ()
{
  int a = 0, b = 0;

  foo (&a, &b);
  if (a != b) 
	exit (-1); 
  else 
	exit (0);
}


program execution:

# ./test
Segmentation fault


problem description:

The problem are two stack references in function baz. These are generated through:

save_area = replace_rtx (copy_rtx (save_area),
		         virtual_stack_vars_rtx, static_chain);

emit_move_insn (hard_frame_pointer_rtx, static_chain);

in function expand_goto file stmt.c . 

The generated insns taken from test.c.01.rtl are:

(insn 30 29 31 (set (reg:DI 49)
        (mem:DI (reg:DI 48) [0 S8 A8])) -1 (nil)
    (nil))

(insn 31 30 32 (set (reg/f:DI %r11)
        (reg:DI 48)) -1 (nil)
    (nil))

The scheduler step likes to exchange both which at first glance seems to be valid. Unfortunately 
register 48 turns out to be a reference to the stack using the frame pointer (register 11 on S/390)
which results in the following rtl expressions taken from test.c.39.mach:

(insn 31 34 86 (set (reg/f:DI %r11)
        (mem:DI (plus:DI (reg/f:DI %r11)
                (const_int 216 [0xd8])) [6 S8 A8])) 53 {*movdi_64} (nil)
    (nil))

(insn 86 31 30 (set (reg:DI %r2)
        (mem:DI (plus:DI (reg/f:DI %r11)
                (const_int 216 [0xd8])) [6 S8 A8])) 53 {*movdi_64} (insn_list 31 (nil))
    (nil))

On S/390 inserting a blockage between both instructions avoids the problem. 

Index: stmt.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.333
diff -p -c -r1.333 stmt.c
*** stmt.c	28 Sep 2003 19:09:49 -0000	1.333
--- stmt.c	7 Oct 2003 15:15:53 -0000
*************** expand_goto (tree label)
*** 648,653 ****
--- 648,655 ----
        else
  #endif
  	{
+ 	  emit_insn (gen_blockage ());
+ 
  	  /* Restore frame pointer for containing function.
  	     This sets the actual hard register used for the frame pointer
  	     to the location of the function's incoming static chain info.


A blockage is defined in the s390 backend as an UNSPEC_VOLATILE. Therefore the scheduler can't 
exchange the insns. But this solution is apparently platform dependent and therefore is not the right way. 
My question is how to generate a blockage which is platform independent or whether there is a better way 
to solve this.

Please consider including test.c in the testsuite in order to get notified in the regression test if the frame 
pointer gets used in the wrong way during nonlocal gotos.

Bye,

-Andreas-


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]