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

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

Reply via email to