On 6/27/25 12:16 AM, Andrew Pinski wrote:
Since after a tail call function (even if it is tail called in the end),
the current function does not care about the local memory any more so
there is no reason to do a copy of the argument. This is only true for the
first usage of the decl, the rest requires a copy (c-c++-common/pr42909-3.c
checks that).
Bootstrapped and tested on aarch64-linux-gnu.
PR middle-end/42909
gcc/ChangeLog:
* calls.cc (initialize_argument_information): For tail
calls allow to reuse the argument if it is not addressable
nor static if the first use of the decl. Disallow tails if
that argument is not an incoming argument.
gcc/testsuite/ChangeLog:
* c-c++-common/pr42909-1.c: New testcase
* c-c++-common/pr42909-2.c: New testcase
* c-c++-common/pr42909-3.c: New testcase
* c-c++-common/pr42909-4.c: New testcase
Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
---
gcc/calls.cc | 33 ++++++++++++++++++----
gcc/testsuite/c-c++-common/pr42909-1.c | 19 +++++++++++++
gcc/testsuite/c-c++-common/pr42909-2.c | 19 +++++++++++++
gcc/testsuite/c-c++-common/pr42909-3.c | 38 ++++++++++++++++++++++++++
gcc/testsuite/c-c++-common/pr42909-4.c | 20 ++++++++++++++
5 files changed, 124 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/pr42909-1.c
create mode 100644 gcc/testsuite/c-c++-common/pr42909-2.c
create mode 100644 gcc/testsuite/c-c++-common/pr42909-3.c
create mode 100644 gcc/testsuite/c-c++-common/pr42909-4.c
@@ -1428,15 +1430,37 @@ initialize_argument_information (int num_actuals
ATTRIBUTE_UNUSED,
const bool callee_copies
= reference_callee_copied (args_so_far_pnt, arg);
tree base;
-
+ bool can_reuse_arg = false;
+ bool can_reuse_with_tail_call = call_from_thunk_p;
/* If we're compiling a thunk, pass directly the address of an object
already in memory, instead of making a copy. Likewise if we want
- to make the copy in the callee instead of the caller. */
+ to make the copy in the callee instead of the caller. */
Whitespace nit at the comment close. Guessing you didn't mean to make
that change.
if ((call_from_thunk_p || callee_copies)
&& TREE_CODE (args[i].tree_value) != WITH_SIZE_EXPR
&& ((base = get_base_address (args[i].tree_value)), true)
&& TREE_CODE (base) != SSA_NAME
&& (!DECL_P (base) || MEM_P (DECL_RTL (base))))
+ can_reuse_arg = true;
+
+ /* If we're compiling a tail call, pass the address of an object
+ already in memory, instead of a copy if the argument is a local
+ variable. Since after the tail call, the memory belongs to the
caller,
+ this is safe even if we don't expand the call in the end as a tail
call.
+ The first use of the decl can reuse it, the rest uses requires a
copy. */
What about a set before any use? Does everything still work in that case?
Assuming the right things happen if there's an assignment to the
argument before the first use, then this is OK. Otherwise I think you
need more changes.
jeff