This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR target/66906: Replicate static chain on the stack
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Uros Bizjak <ubizjak at gmail dot com>
- Date: Fri, 17 Jul 2015 10:49:50 -0700
- Subject: [PATCH] PR target/66906: Replicate static chain on the stack
- Authentication-results: sourceware.org; auth=none
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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;
+ }
}
int_registers_saved = (frame.nregs == 0);
diff --git a/gcc/testsuite/gcc.target/i386/pr66906.c b/gcc/testsuite/gcc.target/i386/pr66906.c
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;
+}
--
2.4.3