From: hjl Date: Fri, 17 Jul 2015 23:02:25 +0000 (+0000) Subject: Replicate static chain on the stack X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dfd0262fae62279908b413e3ede443768177a5a3;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225974 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fc24180f8599..6d583195ff7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-07-17 H.J. Lu + + PR target/66906 + * config/i386/i386.c (ix86_expand_prologue): Replicate static + chain on the stack. + 2015-07-17 Nathan Sidwell * config/nvptx/mkoffload.c (process): Constify host data. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 55e1e2db3493..01a1cb94a7c9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a27f032a61b4..9628a20dc121 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-07-17 H.J. Lu + + PR target/66906 + * gcc.target/i386/pr66906.c: New test. + 2015-07-17 Mikael Morin * gfortran.dg/coarray_collectives_16.f90: Fix pattern diff --git a/gcc/testsuite/gcc.target/i386/pr66906.c b/gcc/testsuite/gcc.target/i386/pr66906.c new file mode 100644 index 000000000000..969e183c79c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66906.c @@ -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; +}