diff mbox series

i386: Align stack frame if argument is passed on stack

Message ID 20180110204011.GA21548@gmail.com
State New
Headers show
Series i386: Align stack frame if argument is passed on stack | expand

Commit Message

H.J. Lu Jan. 10, 2018, 8:40 p.m. UTC
When a function call is removed, it may become a leaf function.  But if
argument may be passed on stack, we need to align the stack frame when
there is no tail call.

Tested on Linux/i686 and Linux/x86-64.

OK for trunk?

H.J.
---
gcc/

	PR target/83330
	* config/i386/i386.c (ix86_compute_frame_layout): Align stack
	frame if argument is passed on stack.

gcc/testsuite/

	PR target/83330
	* gcc.target/i386/pr83330.c: New test.
---
 gcc/config/i386/i386.c                  |  7 ++++++-
 gcc/testsuite/gcc.target/i386/pr83330.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr83330.c

Comments

Uros Bizjak Jan. 11, 2018, 7:07 p.m. UTC | #1
On Wed, Jan 10, 2018 at 9:40 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> When a function call is removed, it may become a leaf function.  But if
> argument may be passed on stack, we need to align the stack frame when
> there is no tail call.
>
> Tested on Linux/i686 and Linux/x86-64.
>
> OK for trunk?
>
> H.J.
> ---
> gcc/
>
>         PR target/83330
>         * config/i386/i386.c (ix86_compute_frame_layout): Align stack
>         frame if argument is passed on stack.
>
> gcc/testsuite/
>
>         PR target/83330
>         * gcc.target/i386/pr83330.c: New test.

LGTM.

Thanks,
Uros.

> ---
>  gcc/config/i386/i386.c                  |  7 ++++++-
>  gcc/testsuite/gcc.target/i386/pr83330.c | 29 +++++++++++++++++++++++++++++
>  2 files changed, 35 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr83330.c
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 5e17b694d7f..d6ff096d466 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -11339,11 +11339,16 @@ ix86_compute_frame_layout (void)
>        offset += frame->va_arg_size;
>      }
>
> -  /* Align start of frame for local function.  */
> +  /* Align start of frame for local function.  When a function call
> +     is removed, it may become a leaf function.  But if argument may
> +     be passed on stack, we need to align the stack when there is no
> +     tail call.  */
>    if (m->call_ms2sysv
>        || frame->va_arg_size != 0
>        || size != 0
>        || !crtl->is_leaf
> +      || (!crtl->tail_call_emit
> +         && cfun->machine->outgoing_args_on_stack)
>        || cfun->calls_alloca
>        || ix86_current_function_calls_tls_descriptor)
>      offset = ROUND_UP (offset, stack_alignment_needed);
> diff --git a/gcc/testsuite/gcc.target/i386/pr83330.c b/gcc/testsuite/gcc.target/i386/pr83330.c
> new file mode 100644
> index 00000000000..8a63fbd5d09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr83330.c
> @@ -0,0 +1,29 @@
> +/* { dg-do run { target int128 } } */
> +/* { dg-options "-O2 -fno-tree-dce -mno-push-args" } */
> +
> +typedef unsigned long long u64;
> +typedef unsigned __int128 u128;
> +
> +u64 v;
> +u64 g;
> +
> +u64 __attribute__ ((noinline, noclone))
> +bar (u128 d, u64 e, u64 f, u64 g, u128 h)
> +{
> +  (void)d, (void)e, (void)f, (void)g, (void)h;
> +  return 0;
> +}
> +
> +static u64 __attribute__ ((noipa))
> +foo (void)
> +{
> +  (void)(v - bar (0, 0, 0, 0, 0));
> +  return g;
> +}
> +
> +int
> +main (void)
> +{
> +  (void)foo ();
> +  return 0;
> +}
> --
> 2.14.3
>
H.J. Lu Jan. 11, 2018, 9:17 p.m. UTC | #2
On Thu, Jan 11, 2018 at 11:07 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Jan 10, 2018 at 9:40 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>> When a function call is removed, it may become a leaf function.  But if
>> argument may be passed on stack, we need to align the stack frame when
>> there is no tail call.
>>
>> Tested on Linux/i686 and Linux/x86-64.
>>
>> OK for trunk?
>>
>> H.J.
>> ---
>> gcc/
>>
>>         PR target/83330
>>         * config/i386/i386.c (ix86_compute_frame_layout): Align stack
>>         frame if argument is passed on stack.
>>
>> gcc/testsuite/
>>
>>         PR target/83330
>>         * gcc.target/i386/pr83330.c: New test.
>
> LGTM.
>

Here is the backport for GCC 7.  OK for gcc-7-branch after a few days?

Thanks.
Uros Bizjak Jan. 12, 2018, 4:57 p.m. UTC | #3
On Thu, Jan 11, 2018 at 10:17 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Jan 11, 2018 at 11:07 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Wed, Jan 10, 2018 at 9:40 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>>> When a function call is removed, it may become a leaf function.  But if
>>> argument may be passed on stack, we need to align the stack frame when
>>> there is no tail call.
>>>
>>> Tested on Linux/i686 and Linux/x86-64.
>>>
>>> OK for trunk?
>>>
>>> H.J.
>>> ---
>>> gcc/
>>>
>>>         PR target/83330
>>>         * config/i386/i386.c (ix86_compute_frame_layout): Align stack
>>>         frame if argument is passed on stack.
>>>
>>> gcc/testsuite/
>>>
>>>         PR target/83330
>>>         * gcc.target/i386/pr83330.c: New test.
>>
>> LGTM.
>>
>
> Here is the backport for GCC 7.  OK for gcc-7-branch after a few days?

OK.

Thanks,
Uros.
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5e17b694d7f..d6ff096d466 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11339,11 +11339,16 @@  ix86_compute_frame_layout (void)
       offset += frame->va_arg_size;
     }
 
-  /* Align start of frame for local function.  */
+  /* Align start of frame for local function.  When a function call
+     is removed, it may become a leaf function.  But if argument may
+     be passed on stack, we need to align the stack when there is no
+     tail call.  */
   if (m->call_ms2sysv
       || frame->va_arg_size != 0
       || size != 0
       || !crtl->is_leaf
+      || (!crtl->tail_call_emit
+	  && cfun->machine->outgoing_args_on_stack)
       || cfun->calls_alloca
       || ix86_current_function_calls_tls_descriptor)
     offset = ROUND_UP (offset, stack_alignment_needed);
diff --git a/gcc/testsuite/gcc.target/i386/pr83330.c b/gcc/testsuite/gcc.target/i386/pr83330.c
new file mode 100644
index 00000000000..8a63fbd5d09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr83330.c
@@ -0,0 +1,29 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2 -fno-tree-dce -mno-push-args" } */
+
+typedef unsigned long long u64;
+typedef unsigned __int128 u128;
+
+u64 v;
+u64 g;
+
+u64 __attribute__ ((noinline, noclone))
+bar (u128 d, u64 e, u64 f, u64 g, u128 h)
+{
+  (void)d, (void)e, (void)f, (void)g, (void)h;
+  return 0;
+}
+
+static u64 __attribute__ ((noipa))
+foo (void)
+{
+  (void)(v - bar (0, 0, 0, 0, 0));
+  return g;
+}
+
+int
+main (void)
+{
+  (void)foo ();
+  return 0;
+}