On Fri, Jul 17, 2015 at 7:49 PM, H.J. Lu <hongjiu...@intel.com> wrote: > If we put static chain on the stack, we need to replicate it on the stack > so that static chain can be reached via (argp - 2) slot. This is needed > for nested function with stack realignment. > > OK for trunk if there are no regressions? > > H.J. > --- > 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. > --- > gcc/config/i386/i386.c | 18 ++++++++++++- > gcc/testsuite/gcc.target/i386/pr66906.c | 45 > +++++++++++++++++++++++++++++++++ > 2 files changed, 62 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr66906.c > > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > index 0551a75..3803dde 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,20 @@ 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. */ > + t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD); > + t = gen_rtx_SET (stack_pointer_rtx, t); > + insn = emit_insn (t); > + RTX_FRAME_RELATED_P (insn) = 1; > + emit_move_insn (gen_rtx_MEM (Pmode, stack_pointer_rtx), > + static_chain); > + m->fs.sp_offset += UNITS_PER_WORD;
All above can be just: if (static_chain) { /* ... */ insn = emit_insn (gen_push (static_chain)); RTX_FRAME_RELATED_P (insn) = 1; } Please check if the above code survives bootstrap and regression test on x86_32. Uros.