aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/calls.c18
-rw-r--r--gcc/calls.h1
-rw-r--r--gcc/config/i386/i386.c13
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr97267.c19
4 files changed, 34 insertions, 17 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index a8f4596..1a7632d 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1922,7 +1922,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
/* Issue an error if CALL_EXPR was flagged as requiring
tall-call optimization. */
-static void
+void
maybe_complain_about_tail_call (tree call_expr, const char *reason)
{
gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
@@ -3525,7 +3525,6 @@ static bool
can_implement_as_sibling_call_p (tree exp,
rtx structure_value_addr,
tree funtype,
- int reg_parm_stack_space ATTRIBUTE_UNUSED,
tree fndecl,
int flags,
tree addr,
@@ -3550,20 +3549,6 @@ can_implement_as_sibling_call_p (tree exp,
return false;
}
-#ifdef REG_PARM_STACK_SPACE
- /* If outgoing reg parm stack space changes, we cannot do sibcall. */
- if (OUTGOING_REG_PARM_STACK_SPACE (funtype)
- != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl))
- || (reg_parm_stack_space != REG_PARM_STACK_SPACE (current_function_decl)))
- {
- maybe_complain_about_tail_call (exp,
- "inconsistent size of stack space"
- " allocated for arguments which are"
- " passed in registers");
- return false;
- }
-#endif
-
/* Check whether the target is able to optimize the call
into a sibcall. */
if (!targetm.function_ok_for_sibcall (fndecl, exp))
@@ -4088,7 +4073,6 @@ expand_call (tree exp, rtx target, int ignore)
try_tail_call = can_implement_as_sibling_call_p (exp,
structure_value_addr,
funtype,
- reg_parm_stack_space,
fndecl,
flags, addr, args_size);
diff --git a/gcc/calls.h b/gcc/calls.h
index f32b630..b20d24b 100644
--- a/gcc/calls.h
+++ b/gcc/calls.h
@@ -133,6 +133,7 @@ extern bool reference_callee_copied (CUMULATIVE_ARGS *,
extern void maybe_warn_alloc_args_overflow (tree, tree, tree[2], int[2]);
extern tree get_attr_nonstring_decl (tree, tree * = NULL);
extern bool maybe_warn_nonstring_arg (tree, tree);
+extern void maybe_complain_about_tail_call (tree, const char *);
enum size_range_flags
{
/* Set to consider zero a valid range. */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8aa9516..caa9b9d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -939,6 +939,19 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
decl_or_type = type;
}
+ /* If outgoing reg parm stack space changes, we cannot do sibcall. */
+ if ((OUTGOING_REG_PARM_STACK_SPACE (type)
+ != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
+ || (REG_PARM_STACK_SPACE (decl_or_type)
+ != REG_PARM_STACK_SPACE (current_function_decl)))
+ {
+ maybe_complain_about_tail_call (exp,
+ "inconsistent size of stack space"
+ " allocated for arguments which are"
+ " passed in registers");
+ return false;
+ }
+
/* Check that the return value locations are the same. Like
if we are returning floats on the 80387 register stack, we cannot
make a sibcall from a function that doesn't return a float to a
diff --git a/gcc/testsuite/gcc.target/powerpc/pr97267.c b/gcc/testsuite/gcc.target/powerpc/pr97267.c
new file mode 100644
index 0000000..cab4624
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr97267.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+static int __attribute__ ((__noclone__, __noinline__))
+reg_args (int j1, int j2, int j3, int j4, int j5, int j6, int j7, int j8)
+{
+ return j1 + j2 + j3 + j4 + j5 + j6 + j7 + j8;
+}
+
+int __attribute__ ((__noclone__, __noinline__))
+stack_args (int j1, int j2, int j3, int j4, int j5, int j6, int j7, int j8,
+ int j9)
+{
+ if (j9 == 0)
+ return 0;
+ return reg_args (j1, j2, j3, j4, j5, j6, j7, j8);
+}
+
+/* { dg-final { scan-assembler-not {(?n)^\s+bl\s} } } */