]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Replicate static chain on the stack
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Jul 2015 23:02:25 +0000 (23:02 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Jul 2015 23:02:25 +0000 (23:02 +0000)
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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr66906.c [new file with mode: 0644]

index fc24180f85996e1ed22a0ca1a244b91895546a2c..6d583195ff7fe994189bd7b97d106726f4ddc2db 100644 (file)
@@ -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.
index 55e1e2db3493006c0d6de3b27ffdd3ae2704f9c6..01a1cb94a7c99d757e8f7ed5cbf1278617c61295 100644 (file)
@@ -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);
index a27f032a61b4c320e49d79d267c477d4d0fbd208..9628a20dc1217116df311eb5f5347a64587f3a14 100644 (file)
@@ -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 (file)
index 0000000..969e183
--- /dev/null
@@ -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;
+}