[llvm] [AArch64] Restore always-inline behaviour for incompatible SME attributes. (PR #218727)
Sander de Smalen via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 25 09:45:56 PDT 2026
https://github.com/sdesmalen-arm created https://github.com/llvm/llvm-project/pull/218727
PR #209345 changed inlining behaviour for 'alwaysinline' functions
when the callee's SME attributes were incompatible with the caller's
SME attributes. This is not desirable, as it would stop small utility
routines being inlined into streaming functions (such as std::max).
This PR restores the original behaviour from before #209345.
Fixes https://github.com/llvm/llvm-project/issues/217639
>From 45dba33e9006b29a68a9e2e9810eac38cf617d11 Mon Sep 17 00:00:00 2001
From: Sander de Smalen <sander.desmalen at arm.com>
Date: Tue, 25 Aug 2026 16:20:48 +0000
Subject: [PATCH 1/2] pre-commit test
---
.../Inline/AArch64/sme-always-inline.ll | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll
diff --git a/llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll b/llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll
new file mode 100644
index 0000000000000..0a5749a233813
--- /dev/null
+++ b/llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll
@@ -0,0 +1,27 @@
+; REQUIRES: aarch64-registered-target
+; RUN: opt -passes=always-inline -S < %s | FileCheck %s
+
+target triple = "aarch64"
+
+define internal float @callee(float %v) #0 {
+; CHECK-LABEL: define internal float @callee(
+; CHECK-SAME: float [[V:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[RES:%.*]] = tail call float @llvm.sin.f32(float [[V]])
+; CHECK-NEXT: ret float [[RES]]
+;
+ %res = tail call float @llvm.sin.f32(float %v)
+ ret float %res
+}
+
+define float @caller(float %v) #1 {
+; CHECK-LABEL: define float @caller(
+; CHECK-SAME: float [[V:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: [[RES:%.*]] = call float @callee(float [[V]])
+; CHECK-NEXT: ret float [[RES]]
+;
+ %res = call float @callee(float %v)
+ ret float %res
+}
+
+attributes #0 = { "target-features"="+sme2" nounwind alwaysinline }
+attributes #1 = { "target-features"="+sme2" nounwind "aarch64_pstate_sm_enabled" }
>From 641a498d1be8b47333f275260cd4454775e56fde Mon Sep 17 00:00:00 2001
From: Sander de Smalen <sander.desmalen at arm.com>
Date: Tue, 25 Aug 2026 16:20:55 +0000
Subject: [PATCH 2/2] [AArch64] Restore always-inline behaviour for
incompatible SME attributes.
PR #209345 changed inlining behaviour for 'alwaysinline' functions
when the callee's SME attributes were incompatible with the caller's
SME attributes. This is not desirable, as it would stop small utility
routines being inlined into streaming functions (such as std::max).
This PR restores the original behaviour from before #209345.
Fixes https://github.com/llvm/llvm-project/issues/217639
---
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp | 7 ++++++-
.../Transforms/Inline/AArch64/sme-always-inline.ll | 10 +++-------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 46d2ecfde484e..54a433fdf8f05 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -301,7 +301,12 @@ bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
if (CallAttrs.requiresLazySave() || CallAttrs.requiresSMChange() ||
CallAttrs.requiresPreservingZT0() ||
CallAttrs.requiresPreservingAllZAState()) {
- if (hasPossibleIncompatibleOps(Callee, *getTLI()))
+ // For always-inline functions we can ignore the SME attributes as we should
+ // be able to assume that the user knows what they're doing and that the
+ // front-end has given sufficient warning or error diagnostics to guard the
+ // user.
+ if (!Callee->hasFnAttribute(Attribute::AlwaysInline) &&
+ hasPossibleIncompatibleOps(Callee, *getTLI()))
return false;
}
diff --git a/llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll b/llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll
index 0a5749a233813..4ab23f97e8b5b 100644
--- a/llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll
+++ b/llvm/test/Transforms/Inline/AArch64/sme-always-inline.ll
@@ -4,19 +4,15 @@
target triple = "aarch64"
define internal float @callee(float %v) #0 {
-; CHECK-LABEL: define internal float @callee(
-; CHECK-SAME: float [[V:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[RES:%.*]] = tail call float @llvm.sin.f32(float [[V]])
-; CHECK-NEXT: ret float [[RES]]
-;
+; CHECK-NOT: define internal float @callee
%res = tail call float @llvm.sin.f32(float %v)
ret float %res
}
define float @caller(float %v) #1 {
; CHECK-LABEL: define float @caller(
-; CHECK-SAME: float [[V:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT: [[RES:%.*]] = call float @callee(float [[V]])
+; CHECK-SAME: float [[V:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[RES:%.*]] = call float @llvm.sin.f32(float [[V]])
; CHECK-NEXT: ret float [[RES]]
;
%res = call float @callee(float %v)
More information about the llvm-commits
mailing list