Arm: Fix incorrect tailcall-generation for indirect calls [PR113780]

This patch fixes a bug that causes indirect calls in PAC-enabled functions
to be tailcalled incorrectly when all argument registers R0-R3 are used.

2024-02-07  Tejas Belagod  <tejas.belagod@arm.com>

	PR target/113780
	* config/arm/arm.cc (arm_function_ok_for_sibcall): Don't allow tailcalls
	for indirect calls with 4 or more arguments in pac-enabled functions.

	* lib/target-supports.exp (v8_1m_main_pacbti): Add __ARM_FEATURE_PAUTH.
	* gcc.target/arm/pac-sibcall.c: New.
This commit is contained in:
Tejas Belagod 2024-01-25 16:05:36 +05:30
parent 5c30ecfa81
commit f436a2ab6a
3 changed files with 22 additions and 5 deletions

View file

@ -7980,10 +7980,13 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
&& DECL_WEAK (decl))
return false;
/* We cannot do a tailcall for an indirect call by descriptor if all the
argument registers are used because the only register left to load the
address is IP and it will already contain the static chain. */
if (!decl && CALL_EXPR_BY_DESCRIPTOR (exp) && !flag_trampolines)
/* We cannot tailcall an indirect call by descriptor if all the call-clobbered
general registers are live (r0-r3 and ip). This can happen when:
- IP contains the static chain, or
- IP is needed for validating the PAC signature. */
if (!decl
&& ((CALL_EXPR_BY_DESCRIPTOR (exp) && !flag_trampolines)
|| arm_current_function_pac_enabled_p()))
{
tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
CUMULATIVE_ARGS cum;

View file

@ -0,0 +1,14 @@
/* If all call-clobbered general registers are live (r0-r3, ip), disable
indirect tail-call for a PAC-enabled function. */
/* { dg-do compile } */
/* { dg-require-effective-target arm_arch_v8_1m_main_pacbti_ok } */
/* { dg-add-options arm_arch_v8_1m_main_pacbti } */
/* { dg-additional-options "-mbranch-protection=pac-ret+leaf -O2" } */
void fail(void (*f)(int, int, int, int))
{
f(1, 2, 3, 4);
}
/* { dg-final { scan-assembler-not "bx\tip\t@ indirect register sibling call" } } */

View file

@ -5534,7 +5534,7 @@ foreach { armfunc armflag armdefs } {
v8m_main "-march=armv8-m.main+fp -mthumb" __ARM_ARCH_8M_MAIN__
v8_1m_main "-march=armv8.1-m.main+fp -mthumb" __ARM_ARCH_8M_MAIN__
v8_1m_main_pacbti "-march=armv8.1-m.main+pacbti+fp -mthumb"
"__ARM_ARCH_8M_MAIN__ && __ARM_FEATURE_BTI"
"__ARM_ARCH_8M_MAIN__ && __ARM_FEATURE_BTI && __ARM_FEATURE_PAUTH"
v9a "-march=armv9-a+simd" __ARM_ARCH_9A__ } {
eval [string map [list FUNC $armfunc FLAG $armflag DEFS $armdefs ] {
proc check_effective_target_arm_arch_FUNC_ok { } {