summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>2018-01-15 16:13:23 +0000
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>2018-01-15 16:13:23 +0000
commit9a4efa46ac79e2f6fe75fe57091ff3f8bb593d6e (patch)
tree0f90abcdb965e3a0feddffe15518d1b0314fe484
parent839ca2d69157ef03c8df0ab912dacdb991738694 (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/ChangeLog13
-rw-r--r--gcc/config/i386/i386.c19
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr83330.c29
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;
+}