Skip to content

[AArch64][SME] Disable tail calls in new ZA/ZT0 functions#177152

Merged
MacDue merged 2 commits into
llvm:mainfrom
MacDue:fix_sme_tail_call
Jan 21, 2026
Merged

[AArch64][SME] Disable tail calls in new ZA/ZT0 functions#177152
MacDue merged 2 commits into
llvm:mainfrom
MacDue:fix_sme_tail_call

Conversation

@MacDue
Copy link
Copy Markdown
Member

@MacDue MacDue commented Jan 21, 2026

Allowing this can result in invalid tail calls to shared ZA functions.

It may be possible to limit this to the case where the caller is private ZA and the callee shares ZA, but for now it is generally disabled.

Allowing this can result in invalid tail calls to shared ZA functions.

It may be possible to limit this to the case where the caller is private
ZA and the callee shares ZA, but for now it is generally disabled.
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Jan 21, 2026

@llvm/pr-subscribers-backend-aarch64

Author: Benjamin Maxwell (MacDue)

Changes

Allowing this can result in invalid tail calls to shared ZA functions.

It may be possible to limit this to the case where the caller is private ZA and the callee shares ZA, but for now it is generally disabled.


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

2 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+2-1)
  • (added) llvm/test/CodeGen/AArch64/sme-new-za-zt0-no-tail-call.ll (+78)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 2e96abfce72df..f16aa0188f9d5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9359,7 +9359,8 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
   if (CallAttrs.requiresSMChange() || CallAttrs.requiresLazySave() ||
       CallAttrs.requiresPreservingAllZAState() ||
       CallAttrs.requiresPreservingZT0() ||
-      CallAttrs.caller().hasStreamingBody())
+      CallAttrs.caller().hasStreamingBody() || CallAttrs.caller().isNewZA() ||
+      CallAttrs.caller().isNewZT0())
     return false;
 
   // Functions using the C or Fast calling convention that have an SVE signature
diff --git a/llvm/test/CodeGen/AArch64/sme-new-za-zt0-no-tail-call.ll b/llvm/test/CodeGen/AArch64/sme-new-za-zt0-no-tail-call.ll
new file mode 100644
index 0000000000000..3c76132556600
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sme-new-za-zt0-no-tail-call.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme2 -O3 -verify-machineinstrs < %s | FileCheck %s
+
+declare void @inout_za_zt0() "aarch64_inout_za" "aarch64_inout_zt0"
+
+define void @new_za_zt0() "aarch64_new_za" "aarch64_new_zt0" {
+; CHECK-LABEL: new_za_zt0:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset w30, -16
+; CHECK-NEXT:    mrs x8, TPIDR2_EL0
+; CHECK-NEXT:    cbz x8, .LBB0_2
+; CHECK-NEXT:  // %bb.1: // %entry
+; CHECK-NEXT:    bl __arm_tpidr2_save
+; CHECK-NEXT:    msr TPIDR2_EL0, xzr
+; CHECK-NEXT:    zero {za}
+; CHECK-NEXT:    zero { zt0 }
+; CHECK-NEXT:  .LBB0_2: // %entry
+; CHECK-NEXT:    smstart za
+; CHECK-NEXT:    bl inout_za_zt0
+; CHECK-NEXT:    smstop za
+; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT:    ret
+entry:
+  tail call void @inout_za_zt0()
+  ret void
+}
+
+declare void @inout_za() "aarch64_inout_za"
+
+define void @new_za() "aarch64_new_za" {
+; CHECK-LABEL: new_za:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset w30, -16
+; CHECK-NEXT:    mrs x8, TPIDR2_EL0
+; CHECK-NEXT:    cbz x8, .LBB1_2
+; CHECK-NEXT:  // %bb.1: // %entry
+; CHECK-NEXT:    bl __arm_tpidr2_save
+; CHECK-NEXT:    msr TPIDR2_EL0, xzr
+; CHECK-NEXT:    zero {za}
+; CHECK-NEXT:  .LBB1_2: // %entry
+; CHECK-NEXT:    smstart za
+; CHECK-NEXT:    bl inout_za
+; CHECK-NEXT:    smstop za
+; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT:    ret
+entry:
+  tail call void @inout_za()
+  ret void
+}
+
+declare void @inout_zt0() "aarch64_inout_zt0"
+
+define void @new_zt0() "aarch64_new_zt0" {
+; CHECK-LABEL: new_zt0:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset w30, -16
+; CHECK-NEXT:    mrs x8, TPIDR2_EL0
+; CHECK-NEXT:    cbz x8, .LBB2_2
+; CHECK-NEXT:  // %bb.1: // %entry
+; CHECK-NEXT:    bl __arm_tpidr2_save
+; CHECK-NEXT:    msr TPIDR2_EL0, xzr
+; CHECK-NEXT:    zero { zt0 }
+; CHECK-NEXT:  .LBB2_2: // %entry
+; CHECK-NEXT:    smstart za
+; CHECK-NEXT:    bl inout_zt0
+; CHECK-NEXT:    smstop za
+; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT:    ret
+entry:
+  tail call void @inout_zt0()
+  ret void
+}

Copy link
Copy Markdown
Contributor

@sdesmalen-arm sdesmalen-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find! I hope this was the last of them.

@MacDue MacDue merged commit 10aca26 into llvm:main Jan 21, 2026
13 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Triage to Done in LLVM Release Status Jan 21, 2026
@MacDue
Copy link
Copy Markdown
Member Author

MacDue commented Jan 21, 2026

/cherry-pick 10aca26

@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Jan 21, 2026

/pull-request #177169

@MacDue MacDue deleted the fix_sme_tail_call branch January 21, 2026 13:51
@llvm-ci
Copy link
Copy Markdown

llvm-ci commented Jan 21, 2026

LLVM Buildbot has detected a new failure on builder lldb-aarch64-ubuntu running on linaro-lldb-aarch64-ubuntu while building llvm at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/30443

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: types/TestCharType.py (1322 of 2428)
PASS: lldb-api :: types/TestCharTypeExpr.py (1323 of 2428)
PASS: lldb-api :: types/TestDoubleTypes.py (1324 of 2428)
PASS: lldb-api :: types/TestDoubleTypesExpr.py (1325 of 2428)
PASS: lldb-api :: types/TestFloatTypes.py (1326 of 2428)
PASS: lldb-api :: tools/lldb-server/vCont-threads/TestPartialResume.py (1327 of 2428)
PASS: lldb-api :: tools/lldb-server/TestGdbRemote_vCont.py (1328 of 2428)
PASS: lldb-api :: types/TestFloatTypesExpr.py (1329 of 2428)
PASS: lldb-api :: types/TestIntegerType.py (1330 of 2428)
PASS: lldb-api :: types/TestRecursiveTypes.py (1331 of 2428)
FAIL: lldb-api :: tools/lldb-dap/restart/TestDAP_restart.py (1332 of 2428)
******************** TEST 'lldb-api :: tools/lldb-dap/restart/TestDAP_restart.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --arch aarch64 --build-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --cmake-build-type Release /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/tools/lldb-dap/restart -p TestDAP_restart.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 23.0.0git (https://github.com/llvm/llvm-project.git revision 10aca26ffffe6a9ee049f479ed7fee9e07421dad)
  clang revision 10aca26ffffe6a9ee049f479ed7fee9e07421dad
  llvm revision 10aca26ffffe6a9ee049f479ed7fee9e07421dad
Skipping the following test categories: libc++, msvcstl, dsym, pdb, gmodules, debugserver, objc

--
Command Output (stderr):
--
========= DEBUG ADAPTER PROTOCOL LOGS =========
[13:59:53.432] (stdio) --> {"command":"initialize","type":"request","arguments":{"adapterID":"lldb-native","clientID":"vscode","columnsStartAt1":true,"linesStartAt1":true,"locale":"en-us","pathFormat":"path","supportsRunInTerminalRequest":true,"supportsVariablePaging":true,"supportsVariableType":true,"supportsStartDebuggingRequest":true,"supportsProgressReporting":true,"supportsInvalidatedEvent":true,"supportsMemoryEvent":true,"$__lldb_sourceInitFile":false},"seq":1}
[13:59:53.432] DAP.cpp:1002 (stdio) queued (command=initialize seq=1)
[13:59:53.433] (stdio) <-- {"body":{"$__lldb_version":"lldb version 23.0.0git (https://github.com/llvm/llvm-project.git revision 10aca26ffffe6a9ee049f479ed7fee9e07421dad)\n  clang revision 10aca26ffffe6a9ee049f479ed7fee9e07421dad\n  llvm revision 10aca26ffffe6a9ee049f479ed7fee9e07421dad","completionTriggerCharacters":["."," ","\t"],"exceptionBreakpointFilters":[{"description":"C++ Catch","filter":"cpp_catch","label":"C++ Catch","supportsCondition":true},{"description":"C++ Throw","filter":"cpp_throw","label":"C++ Throw","supportsCondition":true},{"description":"Objective-C Catch","filter":"objc_catch","label":"Objective-C Catch","supportsCondition":true},{"description":"Objective-C Throw","filter":"objc_throw","label":"Objective-C Throw","supportsCondition":true}],"supportTerminateDebuggee":true,"supportsBreakpointLocationsRequest":true,"supportsCancelRequest":true,"supportsClipboardContext":true,"supportsCompletionsRequest":true,"supportsConditionalBreakpoints":true,"supportsConfigurationDoneRequest":true,"supportsDataBreakpointBytes":true,"supportsDataBreakpoints":true,"supportsDelayedStackTraceLoading":true,"supportsDisassembleRequest":true,"supportsEvaluateForHovers":true,"supportsExceptionFilterOptions":true,"supportsExceptionInfoRequest":true,"supportsFunctionBreakpoints":true,"supportsHitConditionalBreakpoints":true,"supportsInstructionBreakpoints":true,"supportsLogPoints":true,"supportsModuleSymbolsRequest":true,"supportsModulesRequest":true,"supportsReadMemoryRequest":true,"supportsSetVariable":true,"supportsSteppingGranularity":true,"supportsValueFormattingOptions":true,"supportsWriteMemoryRequest":true},"command":"initialize","request_seq":1,"seq":1,"success":true,"type":"response"}
[13:59:53.433] (stdio) --> {"command":"launch","type":"request","arguments":{"program":"/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/tools/lldb-dap/restart/TestDAP_restart.test_arguments/a.out","initCommands":["settings clear --all","settings set symbols.enable-external-lookup false","settings set target.inherit-tcc true","settings set target.disable-aslr false","settings set target.detach-on-error false","settings set target.auto-apply-fixits false","settings set plugin.process.gdb-remote.packet-timeout 60","settings set symbols.clang-modules-cache-path \"/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"","settings set use-color false","settings set show-statusline false"],"disableASLR":false,"enableAutoVariableSummaries":false,"enableSyntheticChildDebugging":false,"displayExtendedBacktrace":false},"seq":2}
[13:59:53.433] DAP.cpp:1002 (stdio) queued (command=launch seq=2)
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"To get started with the debug console try \"<variable>\", \"<lldb-cmd>\" or \"help [<lldb-cmd>]\"\r\n"},"event":"output","seq":2,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"For more information visit https://lldb.llvm.org/use/lldbdap.html#debug-console.\r\n"},"event":"output","seq":3,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"Running initCommands:\n"},"event":"output","seq":4,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings clear --all\n"},"event":"output","seq":5,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set symbols.enable-external-lookup false\n"},"event":"output","seq":6,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.inherit-tcc true\n"},"event":"output","seq":7,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.disable-aslr false\n"},"event":"output","seq":8,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.detach-on-error false\n"},"event":"output","seq":9,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set target.auto-apply-fixits false\n"},"event":"output","seq":10,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set plugin.process.gdb-remote.packet-timeout 60\n"},"event":"output","seq":11,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set symbols.clang-modules-cache-path \"/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api\"\n"},"event":"output","seq":12,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set use-color false\n"},"event":"output","seq":13,"type":"event"}
[13:59:53.435] (stdio) <-- {"body":{"category":"console","output":"(lldb) settings set show-statusline false\n"},"event":"output","seq":14,"type":"event"}
[13:59:53.513] (stdio) <-- {"body":{"module":{"addressRange":"0xe714deddb000","id":"51E41459-D691-73BD-2119-1E0B2C35BDD1-B76053EE","name":"ld-linux-aarch64.so.1","path":"/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1","symbolStatus":"Symbols not found."},"reason":"new"},"event":"module","seq":15,"type":"event"}
[13:59:53.513] (stdio) <-- {"event":"initialized","seq":16,"type":"event"}

c-rhodes pushed a commit to llvmbot/llvm-project that referenced this pull request Jan 22, 2026
Allowing this can result in invalid tail calls to shared ZA functions.

It may be possible to limit this to the case where the caller is private
ZA and the callee shares ZA, but for now it is generally disabled.

(cherry picked from commit 10aca26)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

4 participants