[llvm-branch-commits] [clang] [CIR][CodeGen][NFC] Share the Arm SME inlinability check (PR #223425)
Henrich Lauko via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 29 04:23:17 PDT 2026
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/223425
>From d1aac337511152a1fb0a027c6ed914fb31b47621 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Tue, 29 Sep 2026 09:56:29 +0000
Subject: [PATCH] [CIR][CodeGen][NFC] Share the Arm SME inlinability check
Deduplicates `ArmSMEInlinability` and `getArmSMEInlinability` between CIR and
classic CodeGen into a new `TargetUtils.h`.
---
.../include/clang/CodeGenUtils/TargetUtils.h | 51 ++++++++++++
clang/lib/CIR/CodeGen/Targets/AArch64.cpp | 55 +------------
clang/lib/CodeGen/Targets/AArch64.cpp | 78 +++++--------------
clang/lib/CodeGenUtils/CMakeLists.txt | 1 +
clang/lib/CodeGenUtils/TargetUtils.cpp | 50 ++++++++++++
5 files changed, 123 insertions(+), 112 deletions(-)
create mode 100644 clang/include/clang/CodeGenUtils/TargetUtils.h
create mode 100644 clang/lib/CodeGenUtils/TargetUtils.cpp
diff --git a/clang/include/clang/CodeGenUtils/TargetUtils.h b/clang/include/clang/CodeGenUtils/TargetUtils.h
new file mode 100644
index 0000000000000..23d3a9e8dd6c2
--- /dev/null
+++ b/clang/include/clang/CodeGenUtils/TargetUtils.h
@@ -0,0 +1,51 @@
+//===--- TargetUtils.h - Shared target-specific AST queries -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file holds the target-specific AST queries that both classic CodeGen
+// and CIR CodeGen need.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGENUTILS_TARGETUTILS_H
+#define LLVM_CLANG_CODEGENUTILS_TARGETUTILS_H
+
+#include "llvm/ADT/BitmaskEnum.h"
+
+#include <cstdint>
+
+namespace clang {
+class FunctionDecl;
+} // namespace clang
+
+namespace clang::CodeGenUtils {
+
+/// The Arm SME ABI issues that can prevent inlining one function into another.
+enum class ArmSMEInlinability : uint8_t {
+ Ok = 0,
+ ErrorCalleeRequiresNewZA = 1 << 0,
+ ErrorCalleeRequiresNewZT0 = 1 << 1,
+ WarnIncompatibleStreamingModes = 1 << 2,
+ ErrorIncompatibleStreamingModes = 1 << 3,
+
+ IncompatibleStreamingModes = WarnIncompatibleStreamingModes |
+ ErrorIncompatibleStreamingModes,
+
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ErrorIncompatibleStreamingModes),
+};
+
+// Enable the bitwise operators on ArmSMEInlinability.
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+/// Determines if there are any Arm SME ABI issues with inlining \p Callee into
+/// \p Caller. Returns the issue (if any) in the ArmSMEInlinability bit enum.
+ArmSMEInlinability getArmSMEInlinability(const FunctionDecl *Caller,
+ const FunctionDecl *Callee);
+
+} // namespace clang::CodeGenUtils
+
+#endif // LLVM_CLANG_CODEGENUTILS_TARGETUTILS_H
diff --git a/clang/lib/CIR/CodeGen/Targets/AArch64.cpp b/clang/lib/CIR/CodeGen/Targets/AArch64.cpp
index cf69ca681f3f7..48791b9fa931f 100644
--- a/clang/lib/CIR/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CIR/CodeGen/Targets/AArch64.cpp
@@ -16,6 +16,7 @@
#include "TargetInfo.h"
#include "clang/AST/Decl.h"
#include "clang/CIR/MissingFeatures.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
using namespace clang;
using namespace clang::CIRGen;
@@ -56,61 +57,11 @@ class AArch64TargetCIRGenInfo : public TargetCIRGenInfo {
} // namespace
-// TODO(cir): Find a way to share this with classic codegen.
-enum class ArmSMEInlinability : uint8_t {
- Ok = 0,
- ErrorCalleeRequiresNewZA = 1 << 0,
- ErrorCalleeRequiresNewZT0 = 1 << 1,
- WarnIncompatibleStreamingModes = 1 << 2,
- ErrorIncompatibleStreamingModes = 1 << 3,
-
- IncompatibleStreamingModes =
- WarnIncompatibleStreamingModes | ErrorIncompatibleStreamingModes,
-
- LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ErrorIncompatibleStreamingModes),
-};
-
-static bool isStreamingCompatible(const FunctionDecl *fd) {
- if (const auto *fpt = fd->getType()->getAs<FunctionProtoType>())
- return fpt->getAArch64SMEAttributes() &
- clang::FunctionType::SME_PStateSMCompatibleMask;
- return false;
-}
-
-/// Determines if there are any Arm SME ABI issues with inlining \p Callee into
-/// \p Caller. Returns the issue (if any) in the ArmSMEInlinability bit enum.
-static ArmSMEInlinability getArmSMEInlinability(const FunctionDecl *caller,
- const FunctionDecl *callee) {
- bool callerIsStreaming =
- clang::IsArmStreamingFunction(caller, /*IncludeLocallyStreaming=*/true);
- bool calleeIsStreaming =
- clang::IsArmStreamingFunction(callee, /*IncludeLocallyStreaming=*/true);
- bool callerIsStreamingCompatible = isStreamingCompatible(caller);
- bool calleeIsStreamingCompatible = isStreamingCompatible(callee);
-
- ArmSMEInlinability inlinability = ArmSMEInlinability::Ok;
-
- if (!calleeIsStreamingCompatible &&
- (callerIsStreaming != calleeIsStreaming || callerIsStreamingCompatible)) {
- if (calleeIsStreaming)
- inlinability |= ArmSMEInlinability::ErrorIncompatibleStreamingModes;
- else
- inlinability |= ArmSMEInlinability::WarnIncompatibleStreamingModes;
- }
- if (auto *newAttr = callee->getAttr<ArmNewAttr>()) {
- if (newAttr->isNewZA())
- inlinability |= ArmSMEInlinability::ErrorCalleeRequiresNewZA;
- if (newAttr->isNewZT0())
- inlinability |= ArmSMEInlinability::ErrorCalleeRequiresNewZT0;
- }
-
- return inlinability;
-}
-
bool AArch64TargetCIRGenInfo::wouldInliningViolateFunctionCallABI(
const FunctionDecl *caller, const FunctionDecl *callee) const {
return caller && callee &&
- getArmSMEInlinability(caller, callee) != ArmSMEInlinability::Ok;
+ CodeGenUtils::getArmSMEInlinability(caller, callee) !=
+ CodeGenUtils::ArmSMEInlinability::Ok;
}
std::unique_ptr<TargetCIRGenInfo>
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 23a4e5c0ce9ec..e76d7fa21b807 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -10,6 +10,7 @@
#include "TargetInfo.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
#include "llvm/TargetParser/AArch64TargetParser.h"
using namespace clang;
@@ -1191,13 +1192,6 @@ RValue AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
CharUnits::fromQuantity(8), AllowHigherAlign, Slot);
}
-static bool isStreamingCompatible(const FunctionDecl *F) {
- if (const auto *T = F->getType()->getAs<FunctionProtoType>())
- return T->getAArch64SMEAttributes() &
- FunctionType::SME_PStateSMCompatibleMask;
- return false;
-}
-
// Report an error if an argument or return value of type Ty would need to be
// passed in a floating-point register.
static void diagnoseIfNeedsFPReg(DiagnosticsEngine &Diags,
@@ -1233,74 +1227,37 @@ void AArch64TargetCodeGenInfo::checkFunctionABI(
}
}
-enum class ArmSMEInlinability : uint8_t {
- Ok = 0,
- ErrorCalleeRequiresNewZA = 1 << 0,
- ErrorCalleeRequiresNewZT0 = 1 << 1,
- WarnIncompatibleStreamingModes = 1 << 2,
- ErrorIncompatibleStreamingModes = 1 << 3,
-
- IncompatibleStreamingModes =
- WarnIncompatibleStreamingModes | ErrorIncompatibleStreamingModes,
-
- LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ErrorIncompatibleStreamingModes),
-};
-
-/// Determines if there are any Arm SME ABI issues with inlining \p Callee into
-/// \p Caller. Returns the issue (if any) in the ArmSMEInlinability bit enum.
-static ArmSMEInlinability GetArmSMEInlinability(const FunctionDecl *Caller,
- const FunctionDecl *Callee) {
- bool CallerIsStreaming =
- IsArmStreamingFunction(Caller, /*IncludeLocallyStreaming=*/true);
- bool CalleeIsStreaming =
- IsArmStreamingFunction(Callee, /*IncludeLocallyStreaming=*/true);
- bool CallerIsStreamingCompatible = isStreamingCompatible(Caller);
- bool CalleeIsStreamingCompatible = isStreamingCompatible(Callee);
-
- ArmSMEInlinability Inlinability = ArmSMEInlinability::Ok;
-
- if (!CalleeIsStreamingCompatible &&
- (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible)) {
- if (CalleeIsStreaming)
- Inlinability |= ArmSMEInlinability::ErrorIncompatibleStreamingModes;
- else
- Inlinability |= ArmSMEInlinability::WarnIncompatibleStreamingModes;
- }
- if (auto *NewAttr = Callee->getAttr<ArmNewAttr>()) {
- if (NewAttr->isNewZA())
- Inlinability |= ArmSMEInlinability::ErrorCalleeRequiresNewZA;
- if (NewAttr->isNewZT0())
- Inlinability |= ArmSMEInlinability::ErrorCalleeRequiresNewZT0;
- }
-
- return Inlinability;
-}
-
void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(
CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller,
const FunctionDecl *Callee) const {
if (!Caller || !Callee || !Callee->hasAttr<AlwaysInlineAttr>())
return;
- ArmSMEInlinability Inlinability = GetArmSMEInlinability(Caller, Callee);
+ CodeGenUtils::ArmSMEInlinability Inlinability =
+ CodeGenUtils::getArmSMEInlinability(Caller, Callee);
- if ((Inlinability & ArmSMEInlinability::IncompatibleStreamingModes) !=
- ArmSMEInlinability::Ok)
+ if ((Inlinability &
+ CodeGenUtils::ArmSMEInlinability::IncompatibleStreamingModes) !=
+ CodeGenUtils::ArmSMEInlinability::Ok)
CGM.getDiags().Report(
CallLoc,
- (Inlinability & ArmSMEInlinability::ErrorIncompatibleStreamingModes) ==
- ArmSMEInlinability::ErrorIncompatibleStreamingModes
+ (Inlinability &
+ CodeGenUtils::ArmSMEInlinability::ErrorIncompatibleStreamingModes) ==
+ CodeGenUtils::ArmSMEInlinability::
+ ErrorIncompatibleStreamingModes
? diag::err_function_always_inline_attribute_mismatch
: diag::warn_function_always_inline_attribute_mismatch)
<< Caller->getDeclName() << Callee->getDeclName() << "streaming";
- if ((Inlinability & ArmSMEInlinability::ErrorCalleeRequiresNewZA) ==
- ArmSMEInlinability::ErrorCalleeRequiresNewZA)
+ if ((Inlinability &
+ CodeGenUtils::ArmSMEInlinability::ErrorCalleeRequiresNewZA) ==
+ CodeGenUtils::ArmSMEInlinability::ErrorCalleeRequiresNewZA)
CGM.getDiags().Report(CallLoc, diag::err_function_always_inline_new_za)
<< Callee->getDeclName();
- if ((Inlinability & ArmSMEInlinability::ErrorCalleeRequiresNewZT0) ==
- ArmSMEInlinability::ErrorCalleeRequiresNewZT0)
+ if ((Inlinability &
+ CodeGenUtils::ArmSMEInlinability::ErrorCalleeRequiresNewZT0) ==
+ CodeGenUtils::ArmSMEInlinability::ErrorCalleeRequiresNewZT0)
CGM.getDiags().Report(CallLoc, diag::err_function_always_inline_new_zt0)
<< Callee->getDeclName();
}
@@ -1339,7 +1296,8 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABI(CodeGenModule &CGM,
bool AArch64TargetCodeGenInfo::wouldInliningViolateFunctionCallABI(
const FunctionDecl *Caller, const FunctionDecl *Callee) const {
return Caller && Callee &&
- GetArmSMEInlinability(Caller, Callee) != ArmSMEInlinability::Ok;
+ CodeGenUtils::getArmSMEInlinability(Caller, Callee) !=
+ CodeGenUtils::ArmSMEInlinability::Ok;
}
void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
diff --git a/clang/lib/CodeGenUtils/CMakeLists.txt b/clang/lib/CodeGenUtils/CMakeLists.txt
index f46ac572a0ce9..edd32da5b5f7c 100644
--- a/clang/lib/CodeGenUtils/CMakeLists.txt
+++ b/clang/lib/CodeGenUtils/CMakeLists.txt
@@ -12,6 +12,7 @@ add_clang_library(clangCodeGenUtils
ItaniumCXXABIUtils.cpp
ModuleUtils.cpp
RecordLayoutUtils.cpp
+ TargetUtils.cpp
LINK_LIBS
clangAST
diff --git a/clang/lib/CodeGenUtils/TargetUtils.cpp b/clang/lib/CodeGenUtils/TargetUtils.cpp
new file mode 100644
index 0000000000000..2561d6760773b
--- /dev/null
+++ b/clang/lib/CodeGenUtils/TargetUtils.cpp
@@ -0,0 +1,50 @@
+//===--- TargetUtils.cpp - Shared target-specific AST queries ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGenUtils/TargetUtils.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+
+namespace clang::CodeGenUtils {
+
+static bool isStreamingCompatible(const FunctionDecl *F) {
+ if (const auto *T = F->getType()->getAs<FunctionProtoType>())
+ return T->getAArch64SMEAttributes() &
+ FunctionType::SME_PStateSMCompatibleMask;
+ return false;
+}
+
+ArmSMEInlinability getArmSMEInlinability(const FunctionDecl *Caller,
+ const FunctionDecl *Callee) {
+ bool CallerIsStreaming =
+ IsArmStreamingFunction(Caller, /*IncludeLocallyStreaming=*/true);
+ bool CalleeIsStreaming =
+ IsArmStreamingFunction(Callee, /*IncludeLocallyStreaming=*/true);
+ bool CallerIsStreamingCompatible = isStreamingCompatible(Caller);
+ bool CalleeIsStreamingCompatible = isStreamingCompatible(Callee);
+
+ ArmSMEInlinability Inlinability = ArmSMEInlinability::Ok;
+
+ if (!CalleeIsStreamingCompatible &&
+ (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible)) {
+ if (CalleeIsStreaming)
+ Inlinability |= ArmSMEInlinability::ErrorIncompatibleStreamingModes;
+ else
+ Inlinability |= ArmSMEInlinability::WarnIncompatibleStreamingModes;
+ }
+ if (auto *NewAttr = Callee->getAttr<ArmNewAttr>()) {
+ if (NewAttr->isNewZA())
+ Inlinability |= ArmSMEInlinability::ErrorCalleeRequiresNewZA;
+ if (NewAttr->isNewZT0())
+ Inlinability |= ArmSMEInlinability::ErrorCalleeRequiresNewZT0;
+ }
+
+ return Inlinability;
+}
+
+} // namespace clang::CodeGenUtils
More information about the llvm-branch-commits
mailing list