On Fri, Jul 17, 2015 at 12:35 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
> On Fri, Jul 17, 2015 at 7:49 PM, H.J. Lu <hongjiu...@intel.com> wrote:
>> 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;
>
> All above can be just:
>
>  if (static_chain)
>     {
>       /* ... */
>       insn = emit_insn (gen_push (static_chain));
>       RTX_FRAME_RELATED_P (insn) = 1;
>     }
>
> Please check if the above code survives bootstrap and regression test on 
> x86_32.

I am testing this on both ia32 and x86-64.  I will check it in there are no
regressions.

Thanks.


-- 
H.J.
From 86be1d677bbef8bb23f0dfdffc3185b8afbcb080 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.to...@gmail.com>
Date: Fri, 17 Jul 2015 10:44:40 -0700
Subject: [PATCH] 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.
---
 gcc/config/i386/i386.c                  | 13 +++++++++-
 gcc/testsuite/gcc.target/i386/pr66906.c | 45 +++++++++++++++++++++++++++++++++
 2 files changed, 57 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 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/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

Reply via email to