&& 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;
--- /dev/null
+/* 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" } } */
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 { } {