diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2024-02-21 11:12:28 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2024-02-21 11:12:28 +0000 |
commit | 6d56f590483b17c538e332097807a6c5a9225ea3 (patch) | |
tree | 6d493b28a871842e2769106da45718980bffe875 | |
parent | 22f0cf36ec0ad4ec76b50cd87eaab925bda74df8 (diff) | |
download | gcc-6d56f590483b17c538e332097807a6c5a9225ea3.zip gcc-6d56f590483b17c538e332097807a6c5a9225ea3.tar.gz gcc-6d56f590483b17c538e332097807a6c5a9225ea3.tar.bz2 |
aarch64: Fix sibcalls involving shared-ZT0 functions
In:
void bar() __arm_inout("za");
void foo() __arm_inout("za", "zt0") { bar(); }
foo cannot tail-call bar because foo needs to restore ZT0 after
the call. I'd forgotten to update the ok_for_sibcall rules
to handle this when adding SME2.
Thanks to Sander de Smalen for the spot.
gcc/
* config/aarch64/aarch64.cc (aarch64_function_ok_for_sibcall):
Check that each individual piece of state is shared in the same
way, rather than using an aggregate check for PSTATE.ZA.
gcc/testsuite/
* gcc.target/aarch64/sme/sibcall_9.c: New test.
-rw-r--r-- | gcc/config/aarch64/aarch64.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sme/sibcall_9.c | 51 |
2 files changed, 55 insertions, 2 deletions
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index de746e2..f9cedd3 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -6334,8 +6334,10 @@ aarch64_function_ok_for_sibcall (tree, tree exp) tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp))); if (aarch64_fntype_pstate_sm (fntype) & ~aarch64_cfun_incoming_pstate_sm ()) return false; - if (aarch64_fntype_pstate_za (fntype) != aarch64_cfun_incoming_pstate_za ()) - return false; + for (auto state : { "za", "zt0" }) + if (bool (aarch64_cfun_shared_flags (state)) + != bool (aarch64_fntype_shared_flags (fntype, state))) + return false; return true; } diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_9.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_9.c new file mode 100644 index 0000000..2e133c8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_9.c @@ -0,0 +1,51 @@ +// { dg-options "-O2 -fno-schedule-insns -fno-schedule-insns2" } +// { dg-final { check-function-bodies "**" "" } } + +#pragma GCC target "+sme2" + +void gen_zt0() __arm_preserves("za") __arm_out("zt0"); +void callee() __arm_inout("za"); + +/* +** caller_inout: +** ... +** str zt0, \[[^\n]+\] +** bl callee +** ldr zt0, \[[^\n]+\] +** ... +** ret +*/ +void caller_inout() __arm_inout("za", "zt0") { callee(); } + +/* +** caller_in: +** ... +** str zt0, \[[^\n]+\] +** bl callee +** ldr zt0, \[[^\n]+\] +** ... +** ret +*/ +void caller_in() __arm_inout("za") __arm_in("zt0") { callee(); } + +/* +** caller_out: +** ... +** str zt0, \[[^\n]+\] +** bl callee +** ldr zt0, \[[^\n]+\] +** ... +** ret +*/ +void caller_out() __arm_inout("za") __arm_in("zt0") { gen_zt0(); callee(); } + +/* +** caller_preserves: +** ... +** str zt0, \[[^\n]+\] +** bl callee +** ldr zt0, \[[^\n]+\] +** ... +** ret +*/ +void caller_preserves() __arm_inout("za") __arm_preserves("zt0") { callee(); } |