Replicate static chain on the stack

If we put static chain on the stack, we need to replicate it on the stack
when stack is realigned with DRAP so that static chain can be reached via
(argp - 2) slot.

gcc/

	PR target/66906
	* config/i386/i386.c (ix86_expand_prologue): Replicate static
	chain on the stack.

gcc/testsuite/

	PR target/66906
	* gcc.target/i386/pr66906.c: New test.

From-SVN: r225974
This commit is contained in:
H.J. Lu 2015-07-17 23:02:25 +00:00 committed by H.J. Lu
parent de19301a86
commit f6f6b749d6
4 changed files with 68 additions and 1 deletions

View File

@ -1,3 +1,9 @@
2015-07-17 H.J. Lu <hongjiu.lu@intel.com>
PR target/66906
* config/i386/i386.c (ix86_expand_prologue): Replicate static
chain on the stack.
2015-07-17 Nathan Sidwell <nathan@codesourcery.com>
* config/nvptx/mkoffload.c (process): Constify host data.

View File

@ -11495,6 +11495,7 @@ ix86_expand_prologue (void)
HOST_WIDE_INT allocate;
bool int_registers_saved;
bool sse_registers_saved;
rtx static_chain = NULL_RTX;
ix86_finalize_stack_realign_flags ();
@ -11593,7 +11594,8 @@ ix86_expand_prologue (void)
call. This insn will be skipped by the trampoline. */
else if (ix86_static_chain_on_stack)
{
insn = emit_insn (gen_push (ix86_static_chain (cfun->decl, false)));
static_chain = ix86_static_chain (cfun->decl, false);
insn = emit_insn (gen_push (static_chain));
emit_insn (gen_blockage ());
/* We don't want to interpret this push insn as a register save,
@ -11645,6 +11647,15 @@ ix86_expand_prologue (void)
we've started over with a new frame. */
m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
m->fs.realigned = true;
if (static_chain)
{
/* Replicate static chain on the stack so that static chain
can be reached via (argp - 2) slot. This is needed for
nested function with stack realignment. */
insn = emit_insn (gen_push (static_chain));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
int_registers_saved = (frame.nregs == 0);

View File

@ -1,3 +1,8 @@
2015-07-17 H.J. Lu <hongjiu.lu@intel.com>
PR target/66906
* gcc.target/i386/pr66906.c: New test.
2015-07-17 Mikael Morin <mikael@gcc.gnu.org>
* gfortran.dg/coarray_collectives_16.f90: Fix pattern

View File

@ -0,0 +1,45 @@
/* { dg-do run { target ia32 } } */
/* { dg-options "-O0 -mregparm=3" } */
typedef int ptrdiff_t;
extern void abort (void);
int
check_int (int *i, int align)
{
*i = 20;
if ((((ptrdiff_t) i) & (align - 1)) != 0)
abort ();
return *i;
}
void
check (void *p, int align)
{
if ((((ptrdiff_t) p) & (align - 1)) != 0)
abort ();
}
typedef int aligned __attribute__((aligned(64)));
void
foo (void)
{
aligned j;
void bar ()
{
aligned i;
if (check_int (&i, __alignof__(i)) != i)
abort ();
if (check_int (&j, __alignof__(j)) != j)
abort ();
j = -20;
}
bar ();
if (j != -20)
abort ();
if (check_int (&j, __alignof__(j)) != j)
abort ();
}
int
main()
{
foo ();
return 0;
}