[llvm] [AArch64][SME] Emit unimplemented error for non-lazy-save of ZA. (PR #227608)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 01:53:46 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Sander de Smalen (sdesmalen-arm)

<details>
<summary>Changes</summary>

A non-lazy-save of ZA is required when the caller has both ZA and ZT0 state and calls a function with a shared-ZA interface that only shares ZT0.

This case is already rejected by Clang but LLVM compiles it without generating a save of ZA.

---
Full diff: https://github.com/llvm/llvm-project/pull/227608.diff


3 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+3) 
- (modified) llvm/lib/Target/AArch64/AArch64SMEAttributes.h (+7-1) 
- (added) llvm/test/CodeGen/AArch64/sme-non-lazy-save-za.ll (+14) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 26ca67ed132e5..9e5aac507e8dd 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -10588,6 +10588,9 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
   // Determine whether we need any streaming mode changes.
   SMECallAttrs CallAttrs =
       getSMECallAttrs(MF.getFunction(), getRuntimeLibcallsInfo(), CLI);
+  if (CallAttrs.requiresNonLazySaveZA())
+    reportFatalUsageError(
+        "Calls that require saving ZA non-lazily is not yet implemented");
 
   std::optional<unsigned> ZAMarkerNode = getZAMarkerForCall(CallAttrs);
 
diff --git a/llvm/lib/Target/AArch64/AArch64SMEAttributes.h b/llvm/lib/Target/AArch64/AArch64SMEAttributes.h
index a340866335793..5a1e3d60df70a 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEAttributes.h
+++ b/llvm/lib/Target/AArch64/AArch64SMEAttributes.h
@@ -189,6 +189,11 @@ class SMECallAttrs {
            !callee().isSMEABIRoutine();
   }
 
+  bool requiresNonLazySaveZA() const {
+    return caller().hasZAState() && callee().hasSharedZAInterface() &&
+           !callee().sharesZA();
+  }
+
   bool requiresPreservingZT0() const {
     return caller().hasZT0State() && !callee().sharesZT0() &&
            !callee().hasAgnosticZAInterface();
@@ -200,7 +205,8 @@ class SMECallAttrs {
   }
 
   bool requiresZASave() const {
-    return requiresLazySave() || requiresPreservingAllZAState();
+    return requiresLazySave() || requiresNonLazySaveZA() ||
+           requiresPreservingAllZAState();
   }
 };
 
diff --git a/llvm/test/CodeGen/AArch64/sme-non-lazy-save-za.ll b/llvm/test/CodeGen/AArch64/sme-non-lazy-save-za.ll
new file mode 100644
index 0000000000000..7a8827dfedd66
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sme-non-lazy-save-za.ll
@@ -0,0 +1,14 @@
+; RUN: not llc < %s 2>&1 | FileCheck %s
+; RUN: not llc -fast-isel=true < %s 2>&1 | FileCheck %s
+; RUN: not llc -global-isel=true -global-isel-abort=2 < %s 2>&1 | FileCheck %s
+
+; CHECK: LLVM ERROR: Calls that require saving ZA non-lazily is not yet implemented
+
+target triple = "aarch64"
+
+define void @foo(ptr %f) #0 {
+  call void %f() "aarch64_inout_zt0"
+  ret void
+}
+
+attributes #0 = { "aarch64_inout_zt0" "aarch64_inout_za" "target-feature"="+sme,+sve" }

``````````

</details>


https://github.com/llvm/llvm-project/pull/227608


More information about the llvm-commits mailing list