diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-01-15 16:13:23 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-01-15 16:13:23 +0000 |
commit | 9a4efa46ac79e2f6fe75fe57091ff3f8bb593d6e (patch) | |
tree | 0f90abcdb965e3a0feddffe15518d1b0314fe484 | |
parent | 839ca2d69157ef03c8df0ab912dacdb991738694 (diff) |
i386: Align stack frame if argument is passed on stack
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.
gcc/
Backport from mainline
PR target/83330
* 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_compute_frame_layout): Align stack frame if argument is
passed on stack.
* config/i386/i386.h (machine_function): Add
outgoing_args_on_stack.
gcc/testsuite/
Backport from mainline
PR target/83330
* gcc.target/i386/pr83330.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256703 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 19 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr83330.c | 29 |
5 files changed, 68 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 029582575d85..b78521698556 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,19 @@ 2018-01-15 H.J. Lu <hongjiu.lu@intel.com> Backport from mainline + PR target/83330 + * 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_compute_frame_layout): Align stack frame if argument is + passed on stack. + * config/i386/i386.h (machine_function): Add + outgoing_args_on_stack. + +2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + Backport from mainline * config/i386/i386.c (ix86_expand_prologue): Use reference of struct ix86_frame. (ix86_expand_epilogue): Likewise. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 986e6d795841..1786640da190 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -9752,7 +9752,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. @@ -10081,6 +10087,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; } @@ -12510,11 +12520,16 @@ ix86_compute_frame_layout (void) frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size; 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 (stack_realign_fp || offset != frame->sse_reg_save_offset || 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/config/i386/i386.h b/gcc/config/i386/i386.h index f9b91286a014..11727e5274ff 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2620,6 +2620,9 @@ struct GTY(()) machine_function { pass arguments and can be used for indirect sibcall. */ BOOL_BITFIELD arg_reg_available : 1; + /* 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 e4ea2377fbe6..5a2684da8085 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-01-15 H.J. Lu <hongjiu.lu@intel.com> + + Backport from mainline + PR target/83330 + * gcc.target/i386/pr83330.c: New test. + 2018-01-14 Jerry DeLisle <jvdelisle@gcc.gnu.org> Backport from trunk diff --git a/gcc/testsuite/gcc.target/i386/pr83330.c b/gcc/testsuite/gcc.target/i386/pr83330.c new file mode 100644 index 000000000000..9040168377a7 --- /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 +foo (void) +{ + (void)(v - bar (0, 0, 0, 0, 0)); + return g; +} + +int +main (void) +{ + (void)foo (); + return 0; +} |