[gcc r14-12758] aarch64: Fix ZA state transition [PR119210]

Alice Carlotti via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:c1d1bf1f42523dad8e10056fa7058d9d67648a3f

commit r14-12758-gc1d1bf1f42523dad8e10056fa7058d9d67648a3f
Author: Alice Carlotti <[email protected]>
Date:   Thu Apr 16 13:02:35 2026 +0100

    aarch64: Fix ZA state transition [PR119210]
    
    In the INACTIVE_CALLER -> INACTIVE LOCAL transition, ensure ZA is active
    and zeroed before setting tpidr2_el0.
    
    gcc/ChangeLog:
    
            PR target/119210
            * config/aarch64/aarch64.cc (aarch64_mode_emit_local_sme_state):
            Add PSTATE.ZA enablement, and zero it if already enabled.
    
    gcc/testsuite/ChangeLog:
    
            PR target/119210
            * gcc.target/aarch64/sme/za_state_8.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64.cc                     | 13 +++++++++++-
 gcc/testsuite/gcc.target/aarch64/sme/za_state_8.c | 25 +++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 152de30aecf2..0b8a36c4af1a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -29555,7 +29555,8 @@ aarch64_mode_emit_local_sme_state (aarch64_local_sme_state mode,
       emit_insn (gen_aarch64_tpidr2_save ());
       emit_insn (gen_aarch64_clear_tpidr2 ());
       if (mode == aarch64_local_sme_state::ACTIVE_LIVE
-	  || mode == aarch64_local_sme_state::ACTIVE_DEAD)
+	  || mode == aarch64_local_sme_state::ACTIVE_DEAD
+	  || mode == aarch64_local_sme_state::INACTIVE_LOCAL)
 	{
 	  if (aarch64_cfun_has_state ("za"))
 	    emit_insn (gen_aarch64_initial_zero_za ());
@@ -29637,6 +29638,16 @@ aarch64_mode_emit_local_sme_state (aarch64_local_sme_state mode,
 
   if (mode == aarch64_local_sme_state::INACTIVE_LOCAL)
     {
+      if (prev_mode == aarch64_local_sme_state::INACTIVE_CALLER)
+	/* Enable ZA (if it wasn't already enabled on entry).  Enabling ZA has
+	   the side-effect of zeroing ZA.
+
+	   A functionally correct alternative would be to leave TPIDR2_EL0 null
+	   and zero the save buffer.  However, zeroing the save buffer would require
+	   more code and would optimize for the case in which a callee also
+	   initialises private ZA state (which should be a rare event).  */
+	emit_insn (gen_aarch64_smstart_za ());
+
       if (prev_mode == aarch64_local_sme_state::ACTIVE_LIVE
 	  || prev_mode == aarch64_local_sme_state::ACTIVE_DEAD
 	  || prev_mode == aarch64_local_sme_state::INACTIVE_CALLER)
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/za_state_8.c b/gcc/testsuite/gcc.target/aarch64/sme/za_state_8.c
new file mode 100644
index 000000000000..9b7a6ffa69cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sme/za_state_8.c
@@ -0,0 +1,25 @@
+// { dg-options "-O -fomit-frame-pointer -fno-optimize-sibling-calls" }
+// { dg-final { check-function-bodies "**" "" } }
+
+#include <arm_sme.h>
+
+void callee_ns();
+__arm_streaming __arm_inout("za") void callee_s();
+
+/*
+** foo:
+**	...
+**	smstart	za
+**	...
+**	msr	tpidr2_el0, x\d+
+**	...
+*/
+__arm_locally_streaming __arm_new("za") const float * foo(const float* x) {
+    callee_ns ();
+    const float32_t *x_f_in = x;
+    svzero_za();
+    callee_s ();
+    return x_f_in;
+}
+
+
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.