diff options
Diffstat (limited to '0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch')
-rw-r--r-- | 0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch b/0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch new file mode 100644 index 0000000..aa57f9c --- /dev/null +++ b/0215-Backport-SME-aarch64-Update-sibcall-handling-for-SME.patch @@ -0,0 +1,424 @@ +From 08b6cbe756ede25b16b8e9ff9ee32f76c4f8430f Mon Sep 17 00:00:00 2001 +From: Richard Sandiford <richard.sandiford@arm.com> +Date: Tue, 5 Dec 2023 10:11:30 +0000 +Subject: [PATCH 116/157] [Backport][SME] aarch64: Update sibcall handling for + SME + +Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0e7fee57c00ae17611651e0b057dc03b6e276b82 + +We only support tail calls between functions with the same PSTATE.ZA +setting ("private-ZA" to "private-ZA" and "shared-ZA" to "shared-ZA"). + +Only a normal non-streaming function can tail-call another non-streaming +function, and only a streaming function can tail-call another streaming +function. Any function can tail-call a streaming-compatible function. + +gcc/ + * config/aarch64/aarch64.cc (aarch64_function_ok_for_sibcall): + Enforce PSTATE.SM and PSTATE.ZA restrictions. + (aarch64_expand_epilogue): Save and restore the arguments + to a sibcall around any change to PSTATE.SM. + +gcc/testsuite/ + * gcc.target/aarch64/sme/sibcall_1.c: New test. + * gcc.target/aarch64/sme/sibcall_2.c: Likewise. + * gcc.target/aarch64/sme/sibcall_3.c: Likewise. + * gcc.target/aarch64/sme/sibcall_4.c: Likewise. + * gcc.target/aarch64/sme/sibcall_5.c: Likewise. + * gcc.target/aarch64/sme/sibcall_6.c: Likewise. + * gcc.target/aarch64/sme/sibcall_7.c: Likewise. + * gcc.target/aarch64/sme/sibcall_8.c: Likewise. +--- + gcc/config/aarch64/aarch64.cc | 9 +++- + .../gcc.target/aarch64/sme/sibcall_1.c | 45 +++++++++++++++++++ + .../gcc.target/aarch64/sme/sibcall_2.c | 45 +++++++++++++++++++ + .../gcc.target/aarch64/sme/sibcall_3.c | 45 +++++++++++++++++++ + .../gcc.target/aarch64/sme/sibcall_4.c | 45 +++++++++++++++++++ + .../gcc.target/aarch64/sme/sibcall_5.c | 45 +++++++++++++++++++ + .../gcc.target/aarch64/sme/sibcall_6.c | 26 +++++++++++ + .../gcc.target/aarch64/sme/sibcall_7.c | 26 +++++++++++ + .../gcc.target/aarch64/sme/sibcall_8.c | 19 ++++++++ + 9 files changed, 304 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_1.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_2.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_3.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_4.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_5.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_6.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_7.c + create mode 100644 gcc/testsuite/gcc.target/aarch64/sme/sibcall_8.c + +diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc +index eab94d5c2..b8e540b6e 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -8660,6 +8660,11 @@ aarch64_function_ok_for_sibcall (tree, tree exp) + if (crtl->abi->id () != expr_callee_abi (exp).id ()) + return false; + ++ 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; + return true; + } + +@@ -11923,7 +11928,9 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall) + guard_label = aarch64_guard_switch_pstate_sm (IP0_REGNUM, + aarch64_isa_flags); + aarch64_sme_mode_switch_regs return_switch; +- if (crtl->return_rtx && REG_P (crtl->return_rtx)) ++ if (sibcall) ++ return_switch.add_call_args (sibcall); ++ else if (crtl->return_rtx && REG_P (crtl->return_rtx)) + return_switch.add_reg (GET_MODE (crtl->return_rtx), + REGNO (crtl->return_rtx)); + return_switch.emit_prologue (); +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_1.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_1.c +new file mode 100644 +index 000000000..c7530de5c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_1.c +@@ -0,0 +1,45 @@ ++/* { dg-options "-O2" } */ ++ ++void sc_callee () [[arm::streaming_compatible]]; ++void s_callee () [[arm::streaming]]; ++void n_callee (); ++ ++[[arm::locally_streaming]] __attribute__((noipa)) void ++sc_ls_callee () [[arm::streaming_compatible]] {} ++[[arm::locally_streaming]] __attribute__((noipa)) void ++n_ls_callee () {} ++ ++void ++sc_to_sc () [[arm::streaming_compatible]] ++{ ++ sc_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_callee} } } */ ++ ++void ++sc_to_s () [[arm::streaming_compatible]] ++{ ++ s_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\ts_callee} } } */ ++ ++void ++sc_to_n () [[arm::streaming_compatible]] ++{ ++ n_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tn_callee} } } */ ++ ++void ++sc_to_sc_ls () [[arm::streaming_compatible]] ++{ ++ sc_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_ls_callee} } } */ ++ ++void ++sc_to_n_ls () [[arm::streaming_compatible]] ++{ ++ n_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tn_ls_callee} } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_2.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_2.c +new file mode 100644 +index 000000000..8d1c8a9f9 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_2.c +@@ -0,0 +1,45 @@ ++/* { dg-options "-O2" } */ ++ ++void sc_callee () [[arm::streaming_compatible]]; ++void s_callee () [[arm::streaming]]; ++void n_callee (); ++ ++[[arm::locally_streaming]] __attribute__((noipa)) void ++sc_ls_callee () [[arm::streaming_compatible]] {} ++[[arm::locally_streaming]] __attribute__((noipa)) void ++n_ls_callee () {} ++ ++void ++s_to_sc () [[arm::streaming]] ++{ ++ sc_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_callee} } } */ ++ ++void ++s_to_s () [[arm::streaming]] ++{ ++ s_callee (); ++} ++/* { dg-final { scan-assembler {\tb\ts_callee} } } */ ++ ++void ++s_to_n () [[arm::streaming]] ++{ ++ n_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tn_callee} } } */ ++ ++void ++s_to_sc_ls () [[arm::streaming]] ++{ ++ sc_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_ls_callee} } } */ ++ ++void ++s_to_n_ls () [[arm::streaming]] ++{ ++ n_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tn_ls_callee} } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_3.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_3.c +new file mode 100644 +index 000000000..2ae937fc5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_3.c +@@ -0,0 +1,45 @@ ++/* { dg-options "-O2" } */ ++ ++void sc_callee () [[arm::streaming_compatible]]; ++void s_callee () [[arm::streaming]]; ++void n_callee (); ++ ++[[arm::locally_streaming]] __attribute__((noipa)) void ++sc_ls_callee () [[arm::streaming_compatible]] {} ++[[arm::locally_streaming]] __attribute__((noipa)) void ++n_ls_callee () {} ++ ++void ++n_to_sc () ++{ ++ sc_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_callee} } } */ ++ ++void ++n_to_s () ++{ ++ s_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\ts_callee} } } */ ++ ++void ++n_to_n () ++{ ++ n_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tn_callee} } } */ ++ ++void ++n_to_sc_ls () ++{ ++ sc_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_ls_callee} } } */ ++ ++void ++n_to_n_ls () ++{ ++ n_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tn_ls_callee} } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_4.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_4.c +new file mode 100644 +index 000000000..6935a1bd7 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_4.c +@@ -0,0 +1,45 @@ ++/* { dg-options "-O2" } */ ++ ++void sc_callee () [[arm::streaming_compatible]]; ++void s_callee () [[arm::streaming]]; ++void n_callee (); ++ ++[[arm::locally_streaming]] __attribute__((noipa)) void ++sc_ls_callee () [[arm::streaming_compatible]] {} ++[[arm::locally_streaming]] __attribute__((noipa)) void ++n_ls_callee () {} ++ ++[[arm::locally_streaming]] void ++sc_to_sc () [[arm::streaming_compatible]] ++{ ++ sc_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_callee} } } */ ++ ++[[arm::locally_streaming]] void ++sc_to_s () [[arm::streaming_compatible]] ++{ ++ s_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\ts_callee} } } */ ++ ++[[arm::locally_streaming]] void ++sc_to_n () [[arm::streaming_compatible]] ++{ ++ n_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tn_callee} } } */ ++ ++[[arm::locally_streaming]] void ++sc_to_sc_ls () [[arm::streaming_compatible]] ++{ ++ sc_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_ls_callee} } } */ ++ ++[[arm::locally_streaming]] void ++sc_to_n_ls () [[arm::streaming_compatible]] ++{ ++ n_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tn_ls_callee} } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_5.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_5.c +new file mode 100644 +index 000000000..7aaf58dfa +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_5.c +@@ -0,0 +1,45 @@ ++/* { dg-options "-O2" } */ ++ ++void sc_callee () [[arm::streaming_compatible]]; ++void s_callee () [[arm::streaming]]; ++void n_callee (); ++ ++[[arm::locally_streaming]] __attribute__((noipa)) void ++sc_ls_callee () [[arm::streaming_compatible]] {} ++[[arm::locally_streaming]] __attribute__((noipa)) void ++n_ls_callee () {} ++ ++[[arm::locally_streaming]] void ++n_to_sc () ++{ ++ sc_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_callee} } } */ ++ ++[[arm::locally_streaming]] void ++n_to_s () ++{ ++ s_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\ts_callee} } } */ ++ ++[[arm::locally_streaming]] void ++n_to_n () ++{ ++ n_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tn_callee} } } */ ++ ++[[arm::locally_streaming]] void ++n_to_sc_ls () ++{ ++ sc_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tsc_ls_callee} } } */ ++ ++[[arm::locally_streaming]] void ++n_to_n_ls () ++{ ++ n_ls_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tn_ls_callee} } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_6.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_6.c +new file mode 100644 +index 000000000..e568edb17 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_6.c +@@ -0,0 +1,26 @@ ++/* { dg-options "-O2" } */ ++ ++void shared_callee () [[arm::inout("za")]]; ++[[arm::new("za")]] __attribute__((noipa)) void new_callee () {} ++void normal_callee (); ++ ++void ++shared_to_shared () [[arm::inout("za")]] ++{ ++ shared_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tshared_callee} } } */ ++ ++void ++shared_to_new () [[arm::inout("za")]] ++{ ++ new_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tnew_callee} } } */ ++ ++void ++shared_to_normal () [[arm::inout("za")]] ++{ ++ normal_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tnormal_callee} } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_7.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_7.c +new file mode 100644 +index 000000000..a5f576d20 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_7.c +@@ -0,0 +1,26 @@ ++/* { dg-options "-O2" } */ ++ ++void shared_callee () [[arm::inout("za")]]; ++[[arm::new("za")]] __attribute__((noipa)) void new_callee () {} ++void normal_callee (); ++ ++[[arm::new("za")]] void ++new_to_shared () ++{ ++ shared_callee (); ++} ++/* { dg-final { scan-assembler {\tbl\tshared_callee} } } */ ++ ++[[arm::new("za")]] void ++new_to_new () ++{ ++ new_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tnew_callee} } } */ ++ ++[[arm::new("za")]] void ++new_to_normal () ++{ ++ normal_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tnormal_callee} } } */ +diff --git a/gcc/testsuite/gcc.target/aarch64/sme/sibcall_8.c b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_8.c +new file mode 100644 +index 000000000..33370f7a8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/aarch64/sme/sibcall_8.c +@@ -0,0 +1,19 @@ ++/* { dg-options "-O2" } */ ++ ++void shared_callee () [[arm::inout("za")]]; ++[[arm::new("za")]] __attribute__((noipa)) void new_callee () {} ++void normal_callee (); ++ ++void ++normal_to_new () ++{ ++ new_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tnew_callee} } } */ ++ ++void ++normal_to_normal () ++{ ++ normal_callee (); ++} ++/* { dg-final { scan-assembler {\tb\tnormal_callee} } } */ +-- +2.33.0 + |