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