Since DRAP is needed only if there are outgoing arguments on stack, we
should track outgoing arguments on stack and avoid setting need_drap to
true when there are no outgoing arguments on stack.

Tested on i686 and x86-64 with SSE2, AVX and AVX2.  There is no
regression.  OK for trunk?

H.J.
---
gcc/

        PR target/81313
        * config/i386/i386.c (ix86_function_arg_advance): Set
        outgoing_args_on_stack to true if there are outgoing arguments
        on stack.
        (ix86_function_arg): Likewise.
        (ix86_get_drap_rtx): Use DRAP only if there are outgoing
        arguments on stack and ACCUMULATE_OUTGOING_ARGS is false.
        * config/i386/i386.h (machine_function): Add
        outgoing_args_on_stack.

gcc/testsuite/

        PR target/81313
        * gcc.target/i386/pr81313-1.c: New test.
        * gcc.target/i386/pr81313-2.c: Likewise.
        * gcc.target/i386/pr81313-3.c: Likewise.
        * gcc.target/i386/pr81313-4.c: Likewise.
---
 gcc/config/i386/i386.c                    | 18 ++++++++++++++++--
 gcc/config/i386/i386.h                    |  3 +++
 gcc/testsuite/gcc.target/i386/pr81313-1.c | 12 ++++++++++++
 gcc/testsuite/gcc.target/i386/pr81313-2.c | 12 ++++++++++++
 gcc/testsuite/gcc.target/i386/pr81313-3.c | 12 ++++++++++++
 gcc/testsuite/gcc.target/i386/pr81313-4.c | 12 ++++++++++++
 6 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr81313-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr81313-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr81313-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr81313-4.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1a8a3a3..9b64d50 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10143,7 +10143,13 @@ ix86_function_arg_advance (cumulative_args_t cum_v, 
machine_mode mode,
   /* For pointers passed in memory we expect bounds passed in Bounds
      Table.  */
   if (!nregs)
-    cum->bnds_in_bt = chkp_type_bounds_count (type);
+    {
+      /* Track if there are outgoing arguments on stack.  */
+      if (cum->caller)
+       cfun->machine->outgoing_args_on_stack = true;
+
+      cum->bnds_in_bt = chkp_type_bounds_count (type);
+    }
 }
 
 /* Define where to put the arguments to a function.
@@ -10473,6 +10479,10 @@ ix86_function_arg (cumulative_args_t cum_v, 
machine_mode omode,
   else
     arg = function_arg_32 (cum, mode, omode, type, bytes, words);
 
+  /* Track if there are outgoing arguments on stack.  */
+  if (arg == NULL_RTX)
+    cfun->machine->outgoing_args_on_stack = true;
+
   return arg;
 }
 
@@ -13646,7 +13656,11 @@ ix86_update_stack_boundary (void)
 static rtx
 ix86_get_drap_rtx (void)
 {
-  if (ix86_force_drap || !ACCUMULATE_OUTGOING_ARGS)
+  /* We must use DRAP if there are outgoing arguments on stack and
+     ACCUMULATE_OUTGOING_ARGS is false.  */
+  if (ix86_force_drap
+      || (cfun->machine->outgoing_args_on_stack
+         && !ACCUMULATE_OUTGOING_ARGS))
     crtl->need_drap = true;
 
   if (stack_realign_drap)
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 08243c1..a2ae9b4 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2657,6 +2657,9 @@ struct GTY(()) machine_function {
      frame pointer.) */
   unsigned int call_ms2sysv_extra_regs:3;
 
+  /* Nonzero if the function places outgoing arguments on stack.  */
+  BOOL_BITFIELD outgoing_args_on_stack : 1;
+
   /* During prologue/epilogue generation, the current frame state.
      Otherwise, the frame state at the end of the prologue.  */
   struct machine_frame_state fs;
diff --git a/gcc/testsuite/gcc.target/i386/pr81313-1.c 
b/gcc/testsuite/gcc.target/i386/pr81313-1.c
new file mode 100644
index 0000000..f765003
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81313-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-accumulate-outgoing-args -mincoming-stack-boundary=4 
-mpreferred-stack-boundary=6" } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}
+
+/* { dg-final { scan-assembler-not "lea\[lq\]?\[\\t 
\]*\[0-9\]*\\(%\[er\]sp\\)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81313-2.c 
b/gcc/testsuite/gcc.target/i386/pr81313-2.c
new file mode 100644
index 0000000..2cdc645
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81313-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mno-accumulate-outgoing-args -mincoming-stack-boundary=4 
-mpreferred-stack-boundary=6 -mno-iamcu" } */
+
+extern void foo (int, int, int);
+
+void
+bar (void)
+{
+  foo (1, 2, 3);
+}
+
+/* { dg-final { scan-assembler "lea\[l\]?\[\\t \]*\[0-9\]*\\(%esp\\)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81313-3.c 
b/gcc/testsuite/gcc.target/i386/pr81313-3.c
new file mode 100644
index 0000000..14bd708
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81313-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -mno-accumulate-outgoing-args -mincoming-stack-boundary=4 
-mpreferred-stack-boundary=6" } */
+
+extern void foo (int, int, int) __attribute__ ((regparm(3)));
+
+void
+bar (void)
+{
+  foo (1, 2, 3);
+}
+
+/* { dg-final { scan-assembler-not "lea\[l\]?\[\\t \]*\[0-9\]*\\(%esp\\)" } } 
*/
diff --git a/gcc/testsuite/gcc.target/i386/pr81313-4.c 
b/gcc/testsuite/gcc.target/i386/pr81313-4.c
new file mode 100644
index 0000000..bad0b3c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81313-4.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-accumulate-outgoing-args -mincoming-stack-boundary=4 
-mpreferred-stack-boundary=6" } */
+
+extern void foo (int, int, int, int, int, int, int);
+
+void
+bar (void)
+{
+  foo (1, 2, 3, 4, 5, 6, 7);
+}
+
+/* { dg-final { scan-assembler "lea\[lq\]?\[\\t \]*\[0-9\]*\\(%\[er\]sp\\)" } 
} */
-- 
2.9.4

Reply via email to