This is an automated email from the git hooks/post-receive script.
unknown user pushed a commit to branch hjl/iamcu/improve in repository gcc.
commit 7503aa6fa19848aee22fb1d49d9e36f23c56000e Author: H.J. Lu hjl.tools@gmail.com Date: Fri Jul 17 10:44:40 2015 -0700
Replicate static chain on the stack
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.
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(-)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 55e1e2d..56cfd6d 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; + } }
int_registers_saved = (frame.nregs == 0); diff --git a/gcc/testsuite/gcc.target/i386/pr66906.c b/gcc/testsuite/gcc.target/i38 [...] new file mode 100644 index 0000000..969e183 --- /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; +}