[llvm] [AArch64] Fall back to SelectionDAG ISel if GISel is not feasible. (PR #196343)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 08:09:20 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-llvm-globalisel
Author: Sander de Smalen (sdesmalen-arm)
<details>
<summary>Changes</summary>
A function like the one below should still result in an SME prologue to set up ZA.
```
void bar() __arm_inout("za");
__attribute__((optnone)) __arm_new("za")
void foo() {
bar();
}
```
https://godbolt.org/z/aEcoKea4b
This worked in LLVM 22, but got broken by #<!-- -->174746.
---
Full diff: https://github.com/llvm/llvm-project/pull/196343.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp (+8-15)
- (added) llvm/test/CodeGen/AArch64/GlobalISel/optnone-sme.ll (+32)
``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
index 6cbfc1f2fbb98..4245d9430bad2 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -582,20 +582,6 @@ bool AArch64CallLowering::fallBackToDAGISel(const MachineFunction &MF) const {
auto &F = MF.getFunction();
const auto &TM = static_cast<const AArch64TargetMachine &>(MF.getTarget());
- const bool GlobalISelFlag =
- getCGPassBuilderOption().EnableGlobalISelOption.value_or(false);
-
- auto OptLevel = MF.getTarget().getOptLevel();
- auto EnableGlobalISelAtO = TM.getEnableGlobalISelAtO();
-
- // GlobalISel is currently only enabled when the opt level is less than or
- // equal to EnableGlobalISelAt or it was explicitly enabled via the CLI. If we
- // encounter this check, we know GlobalISel was enabled. If not by these two,
- // it must have been used as part of the SDAG pipeline to use GlobalISel for
- // optnone.
- if (static_cast<unsigned>(OptLevel) > EnableGlobalISelAtO && !GlobalISelFlag)
- return !F.hasOptNone();
-
if (!EnableSVEGISel && (F.getReturnType()->isScalableTy() ||
llvm::any_of(F.args(), [](const Argument &A) {
return A.getType()->isScalableTy();
@@ -613,7 +599,14 @@ bool AArch64CallLowering::fallBackToDAGISel(const MachineFunction &MF) const {
Attrs.hasStreamingCompatibleInterface())
return true;
- return false;
+ // Enable GlobalISel when feasible and when:
+ // * Forced by option to enable gisel
+ // * The current opt-level is supported by EnableGlobalISelAtO
+ // * The function is an optnone function.
+ auto OptLevel = MF.getTarget().getOptLevel();
+ return !(getCGPassBuilderOption().EnableGlobalISelOption.value_or(false) ||
+ static_cast<unsigned>(OptLevel) <= TM.getEnableGlobalISelAtO() ||
+ F.hasOptNone());
}
void AArch64CallLowering::saveVarArgRegisters(
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/optnone-sme.ll b/llvm/test/CodeGen/AArch64/GlobalISel/optnone-sme.ll
new file mode 100644
index 0000000000000..024abf7d26a4b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/optnone-sme.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -O3 < %s | FileCheck %s
+
+target triple = "aarch64"
+
+; Test that the compiler falls back to SelectionDAG ISel for an optnone function,
+; so that the lazy-save is generated (currently not yet supported by GlobalISel).
+define void @foo() noinline optnone "aarch64_new_za" "target-features"="+sme" {
+; CHECK-LABEL: foo:
+; CHECK: // %bb.0:
+; 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: cbnz x8, .LBB0_1
+; CHECK-NEXT: b .LBB0_2
+; CHECK-NEXT: .LBB0_1:
+; CHECK-NEXT: bl __arm_tpidr2_save
+; CHECK-NEXT: msr TPIDR2_EL0, xzr
+; CHECK-NEXT: zero {za}
+; CHECK-NEXT: b .LBB0_2
+; CHECK-NEXT: .LBB0_2:
+; CHECK-NEXT: smstart za
+; CHECK-NEXT: bl bar
+; CHECK-NEXT: smstop za
+; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT: ret
+ call void @bar()
+ ret void
+}
+
+declare void @bar() "aarch64_inout_za"
``````````
</details>
https://github.com/llvm/llvm-project/pull/196343
More information about the llvm-commits
mailing list