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. From-SVN: r256703
This commit is contained in:
parent
d031a3aaf5
commit
1984fccf0b
|
@ -1,3 +1,16 @@
|
||||||
|
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>
|
2018-01-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
Backport from mainline
|
Backport from mainline
|
||||||
|
|
|
@ -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
|
/* For pointers passed in memory we expect bounds passed in Bounds
|
||||||
Table. */
|
Table. */
|
||||||
if (!nregs)
|
if (!nregs)
|
||||||
|
{
|
||||||
|
/* 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);
|
cum->bnds_in_bt = chkp_type_bounds_count (type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define where to put the arguments to a function.
|
/* 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
|
else
|
||||||
arg = function_arg_32 (cum, mode, omode, type, bytes, words);
|
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;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12510,11 +12520,16 @@ ix86_compute_frame_layout (void)
|
||||||
frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
|
frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
|
||||||
offset += frame->va_arg_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
|
if (stack_realign_fp
|
||||||
|| offset != frame->sse_reg_save_offset
|
|| offset != frame->sse_reg_save_offset
|
||||||
|| size != 0
|
|| size != 0
|
||||||
|| !crtl->is_leaf
|
|| !crtl->is_leaf
|
||||||
|
|| (!crtl->tail_call_emit
|
||||||
|
&& cfun->machine->outgoing_args_on_stack)
|
||||||
|| cfun->calls_alloca
|
|| cfun->calls_alloca
|
||||||
|| ix86_current_function_calls_tls_descriptor)
|
|| ix86_current_function_calls_tls_descriptor)
|
||||||
offset = ROUND_UP (offset, stack_alignment_needed);
|
offset = ROUND_UP (offset, stack_alignment_needed);
|
||||||
|
|
|
@ -2620,6 +2620,9 @@ struct GTY(()) machine_function {
|
||||||
pass arguments and can be used for indirect sibcall. */
|
pass arguments and can be used for indirect sibcall. */
|
||||||
BOOL_BITFIELD arg_reg_available : 1;
|
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.
|
/* During prologue/epilogue generation, the current frame state.
|
||||||
Otherwise, the frame state at the end of the prologue. */
|
Otherwise, the frame state at the end of the prologue. */
|
||||||
struct machine_frame_state fs;
|
struct machine_frame_state fs;
|
||||||
|
|
|
@ -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>
|
2018-01-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||||
|
|
||||||
Backport from trunk
|
Backport from trunk
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue