diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5e2b4f560d0..2a0c6d6e007 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2017-07-09 H.J. Lu + + 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. + 2017-07-09 Krister Walfridsson * config.gcc (*-*-netbsd*): Remove check for NetBSD versions not diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index afd61bf6f8c..42e0ddaca56 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 && cum->caller) + 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 08243c16498..a2ae9b4e242 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/ChangeLog b/gcc/testsuite/ChangeLog index d9cf47871fc..d13db2dbc0d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2017-07-09 H.J. Lu + + 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.target/i386/pr81313-5.c: Likewise. + 2017-07-08 Richard Sandiford * gnat.dg/vect15.ads (Sarray): Increase range to 1 .. 5. 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 00000000000..f7650035cac --- /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 00000000000..2cdc645dbcc --- /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 00000000000..9c1b2326616 --- /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 (int i1, int i2, int i3, int i4) +{ + foo (i1, i2, i3); +} + +/* { 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 00000000000..bad0b3c27db --- /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\\)" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr81313-5.c b/gcc/testsuite/gcc.target/i386/pr81313-5.c new file mode 100644 index 00000000000..51a543ca57e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81313-5.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, int, int, int); + +void +bar (int i1, int i2, int i3, int i4, int i5, int i6, int i7) +{ + foo (i1, i2, i3, i4, i5, i6); +} + +/* { dg-final { scan-assembler-not "lea\[lq\]?\[\\t \]*\[0-9\]*\\(%\[er\]sp\\)" } } */