This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR target/66906: 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.

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]