aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2015-07-17 23:02:25 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2015-07-17 16:02:25 -0700
commitf6f6b749d69f22218545b95433579fdb2af285e6 (patch)
tree4fd38423573f155ce3da3dba5c9c1a1a1661292e /gcc
parentde19301a86d2e3a71ffeb958239b3ec18a77b382 (diff)
downloadgcc-f6f6b749d69f22218545b95433579fdb2af285e6.zip
gcc-f6f6b749d69f22218545b95433579fdb2af285e6.tar.gz
gcc-f6f6b749d69f22218545b95433579fdb2af285e6.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr66906.c45
4 files changed, 68 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc24180..6d58319 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 55e1e2d..01a1cb9 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 a27f032..9628a20 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
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;
+}