[clang] [llvm] [AArch64][clang] Use tablegen rather than hard-coded feature dependencies (NFCI) (PR #190959)
Jonathan Thackray via cfe-commits
cfe-commits at lists.llvm.org
Fri May 1 09:24:22 PDT 2026
https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/190959
>From 95a79df6be5b803453af532fecdf456b6e5c20ca Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Fri, 3 Apr 2026 01:14:47 +0100
Subject: [PATCH 1/2] [AArch64][clang] Use tablegen rather than hard-coded
feature dependencies
Refactor AArch64 frontend feature handling so extension relationships come
from the TargetParser extension graph instead of hand-written dependency
code in C++. This makes `llvm::AArch64::ExtensionSet` the source of
truth for dependency expansion while still keeping the short `Has...` names
used in the frontend code.
This removes a large amount of duplicated implication logic from
`handleTargetFeatures` and related feature queries. The frontend now
rebuilds its extension state from TableGen-derived data and then derives
its cached feature state from that, rather than maintaining parallel
dependency rules in C++.
I also preserved several pieces of historical frontend behaviour that are
not represented directly in the extension graph. Explicit disables such as
`no-sme` still win after implied-feature expansion, direct `+fullfp16` and
`+jscvt` still restore the expected NEON-facing state, and SME-family
features no longer incorrectly appear to enable AdvSIMD/NEON.
Finally, I added regression coverage for the direct-feature and explicit
disable cases uncovered during review, including raw `-target-feature`
combinations and target-attribute cases such as `no-sme`.
---
clang/lib/Basic/Targets/AArch64.cpp | 517 ++++++++----------
clang/lib/Basic/Targets/AArch64.h | 80 +--
.../Targets/AArch64TargetInfoFeatures.inc | 69 +++
clang/lib/Sema/SemaARM.cpp | 6 +-
clang/lib/Sema/SemaChecking.cpp | 2 +-
.../Preprocessor/aarch64-target-features.c | 22 +
...-sme-func-attrs-without-target-feature.cpp | 5 +
7 files changed, 346 insertions(+), 355 deletions(-)
create mode 100644 clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 9b951e69cce33..399d9ed5ae052 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -254,7 +254,8 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
const LangOptions &LO,
StringRef &Err) const {
llvm::ARM::ParsedBranchProtection PBP;
- if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))
+ if (!llvm::ARM::parseBranchProtection(
+ Spec, PBP, Err, hasExtension(llvm::AArch64::AEK_PAUTHLR)))
return false;
// GCS is currently untested with ptrauth-returns, but enabling this could be
@@ -494,6 +495,13 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (FPU & SveMode)
Builder.defineMacro("__ARM_FEATURE_SVE", "1");
+ const bool HasSVE = FPU & SveMode;
+ const bool HasNeon = FPU & NeonMode;
+#define AARCH64_EXTENSION_FEATURE(Name, Ext) \
+ [[maybe_unused]] const bool Name = hasExtension(llvm::AArch64::AEK_##Ext);
+#include "AArch64TargetInfoFeatures.inc"
+#undef AARCH64_EXTENSION_FEATURE
+
if (HasSVE2)
Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
@@ -621,7 +629,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__ARM_FEATURE_SM4", "1");
}
- if (HasPAuth)
+ if (hasPAuth())
Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
if (HasPAuthLR)
@@ -633,10 +641,10 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasUnalignedAccess)
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
- if ((FPU & NeonMode) && HasFullFP16)
+ if ((FPU & NeonMode) && hasFullFP16())
Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
- if (HasFullFP16)
- Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
+ if (hasFullFP16())
+ Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
if (HasDotProd)
Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
@@ -644,7 +652,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasMTE)
Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
- if (HasMatMul)
+ if (HasI8MM)
Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
if (HasLSE)
@@ -657,20 +665,20 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
}
- if ((FPU & SveMode) && HasBFloat16) {
+ if (HasSVE && HasBFloat16) {
Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
}
- if ((FPU & SveMode) && HasMatmulFP64)
+ if (HasSVE && HasF64MM)
Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");
- if ((FPU & SveMode) && HasMatmulFP32)
+ if (HasSVE && HasF32MM)
Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");
- if ((FPU & SveMode) && HasMatMul)
+ if (HasSVE && HasI8MM)
Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");
- if ((FPU & NeonMode) && HasFP16FML)
+ if (HasNeon && HasFP16FML)
Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");
if (Opts.hasSignReturnAddress()) {
@@ -869,11 +877,19 @@ struct FeatureLookupBuilder {
};
void AArch64TargetInfo::computeFeatureLookup() {
+ const bool HasFP = FPU & FPUMode;
+ const bool HasNeon = FPU & NeonMode;
+ const bool HasSVE = FPU & SveMode;
+#define AARCH64_EXTENSION_FEATURE(Name, Ext) \
+ [[maybe_unused]] const bool Name = hasExtension(llvm::AArch64::AEK_##Ext);
+#include "AArch64TargetInfoFeatures.inc"
+#undef AARCH64_EXTENSION_FEATURE
+
FeatureLookupBuilder(HasFeatureLookup)
.Cases({"aarch64", "arm64", "arm"}, true)
.Case("fmv", HasFMV)
- .Case("fp", FPU & FPUMode)
- .Cases({"neon", "simd"}, FPU & NeonMode)
+ .Case("fp", HasFP)
+ .Cases({"neon", "simd"}, HasNeon)
.Case("jscvt", HasJSCVT)
.Case("fcma", HasFCMA)
.Case("rng", HasRandGen)
@@ -889,24 +905,24 @@ void AArch64TargetInfo::computeFeatureLookup() {
.Case("sha2", HasSHA2)
.Case("sha3", HasSHA3)
.Cases({"aes", "pmull"}, HasAES)
- .Cases({"fp16", "fullfp16"}, HasFullFP16)
+ .Cases({"fp16", "fullfp16"}, hasFullFP16())
.Case("dit", HasDIT)
.Case("dpb", HasCCPP)
.Case("dpb2", HasCCDP)
.Case("rcpc", HasRCPC)
.Case("frintts", HasFRInt3264)
- .Case("i8mm", HasMatMul)
+ .Case("i8mm", HasI8MM)
.Case("bf16", HasBFloat16)
- .Case("sve", FPU & SveMode)
+ .Case("sve", HasSVE)
.Case("sve-b16b16", HasSVEB16B16)
- .Case("f32mm", FPU & SveMode && HasMatmulFP32)
- .Case("f64mm", FPU & SveMode && HasMatmulFP64)
- .Case("sve2", FPU & SveMode && HasSVE2)
+ .Case("f32mm", HasSVE && HasF32MM)
+ .Case("f64mm", HasSVE && HasF64MM)
+ .Case("sve2", HasSVE && HasSVE2)
.Case("sve-aes", HasSVEAES)
.Case("sve-bitperm", FPU & HasSVEBitPerm)
- .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
- .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
- .Case("sve2p1", FPU & SveMode && HasSVE2p1)
+ .Case("sve2-sha3", HasSVE && HasSVE2SHA3)
+ .Case("sve2-sm4", HasSVE && HasSVE2SM4)
+ .Case("sve2p1", HasSVE && HasSVE2p1)
.Case("sme", HasSME)
.Case("sme2", HasSME2)
.Case("sme2p1", HasSME2p1)
@@ -939,7 +955,7 @@ void AArch64TargetInfo::computeFeatureLookup() {
.Case("sve-bfscale", HasSVE_BFSCALE)
.Case("sve-aes2", HasSVE_AES2)
.Case("ssve-aes", HasSSVE_AES)
- .Case("sve2p2", FPU & SveMode && HasSVE2p2)
+ .Case("sve2p2", HasSVE && HasSVE2p2)
.Case("sme2p2", HasSME2p2);
}
@@ -947,6 +963,142 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
return HasFeatureLookup.contains(Feature);
}
+bool AArch64TargetInfo::hasExtension(llvm::AArch64::ArchExtKind Ext) const {
+ return EnabledExtensions.test(Ext);
+}
+
+bool AArch64TargetInfo::hasPAuth() const {
+ return hasExtension(llvm::AArch64::AEK_PAUTH) ||
+ hasExtension(llvm::AArch64::AEK_PAUTHLR);
+}
+
+bool AArch64TargetInfo::hasFullFP16() const {
+ return hasExtension(llvm::AArch64::AEK_FP16) ||
+ hasExtension(llvm::AArch64::AEK_SVEAES) ||
+ hasExtension(llvm::AArch64::AEK_SVEBITPERM);
+}
+
+// Find the most specific explicit architecture feature in a target-feature
+// list, e.g. "+v8.6a +v9.2a +sve2" would return the ArchInfo for v9.2a.
+static std::optional<llvm::AArch64::ArchInfo>
+findExplicitBaseArchForTargetFeatures(ArrayRef<std::string> Features) {
+ std::optional<llvm::AArch64::ArchInfo> BaseArch;
+ for (const std::string &Feature : Features) {
+ StringRef Name = Feature;
+ if (!Name.starts_with("+"))
+ continue;
+ if (std::optional<llvm::AArch64::ArchInfo> Candidate =
+ llvm::AArch64::ArchInfo::findBySubArch(Name.drop_front())) {
+ if (!BaseArch || Candidate->Profile != BaseArch->Profile ||
+ Candidate->Version > BaseArch->Version)
+ BaseArch = Candidate;
+ }
+ }
+ return BaseArch;
+}
+
+// Map the frontend's legacy target-feature spellings onto the backend
+// extension names before consulting the AArch64 extension graph.
+static StringRef canonicalizeExtensionLookupFeature(StringRef Feature) {
+ return llvm::StringSwitch<StringRef>(Feature)
+ .Case("+fcma", "+complxnum")
+ .Case("-fcma", "-complxnum")
+ .Case("+jscvt", "+jsconv")
+ .Case("-jscvt", "-jsconv")
+ .Default(Feature);
+}
+
+static std::optional<llvm::AArch64::ExtensionInfo>
+lookupExtensionForTargetFeature(StringRef Feature) {
+ return llvm::AArch64::targetFeatureToExtension(
+ canonicalizeExtensionLookupFeature(Feature));
+}
+
+static std::optional<llvm::AArch64::ExtensionInfo>
+lookupExtensionForFeatureName(StringRef Name) {
+ return lookupExtensionForTargetFeature(("+" + Name).str());
+}
+
+// Direct feature spellings that historically force Clang's NEON-facing FPU
+// state.
+static bool enablesNeonFPUCompat(StringRef Feature) {
+ return llvm::StringSwitch<bool>(Feature)
+ .Cases({"+neon", "+simd", "+fp-armv8", "+jscvt", "+jsconv"}, true)
+ .Cases({"+fcma", "+fullfp16", "+dotprod", "+fp16fml"}, true)
+ .Cases({"+aes", "+sha2", "+sha3", "+sm4", "+rdm"}, true)
+ .Default(false);
+}
+
+// Rebuild a temporary extension set from the frontend feature map so AArch64
+// implied-feature queries can follow the extension dependency graph.
+static llvm::AArch64::ExtensionSet
+buildExtensionSetFromFeatureMap(const llvm::StringMap<bool> &Features) {
+ llvm::AArch64::ExtensionSet FeatureBits;
+ SmallVector<llvm::AArch64::ArchInfo, 4> EnabledArchs;
+ SmallVector<llvm::AArch64::ArchExtKind, 16> ExplicitEnables;
+ SmallVector<llvm::AArch64::ArchExtKind, 16> ExplicitDisables;
+
+ for (const auto &Feature : Features) {
+ if (std::optional<llvm::AArch64::ArchInfo> AI =
+ llvm::AArch64::ArchInfo::findBySubArch(Feature.getKey())) {
+ if (Feature.getValue())
+ EnabledArchs.push_back(*AI);
+ continue;
+ }
+
+ std::string TargetFeature =
+ (Feature.getValue() ? "+" : "-") + Feature.getKey().str();
+ if (auto ExtInfo = lookupExtensionForTargetFeature(TargetFeature)) {
+ if (Feature.getValue())
+ ExplicitEnables.push_back(ExtInfo->ID);
+ else
+ ExplicitDisables.push_back(ExtInfo->ID);
+ }
+ }
+
+ for (const llvm::AArch64::ArchInfo &AI : EnabledArchs)
+ FeatureBits.addArchDefaults(AI);
+ for (llvm::AArch64::ArchExtKind Ext : ExplicitEnables)
+ FeatureBits.enable(Ext);
+ for (llvm::AArch64::ArchExtKind Ext : ExplicitDisables)
+ FeatureBits.disable(Ext);
+
+ return FeatureBits;
+}
+
+// Synchronize the frontend's cached booleans and FPU mode bits from the
+// expanded extension bitset, then reapply Clang-specific compatibility rules
+// that are not represented directly in the extension graph
+void AArch64TargetInfo::setFeatureStateFromEnabledExtensions(
+ const llvm::AArch64::ExtensionBitset &Exts) {
+
+ EnabledExtensions = Exts;
+ const bool HasSVEAES = hasExtension(llvm::AArch64::AEK_SVEAES);
+ const bool HasSVEBitPerm = hasExtension(llvm::AArch64::AEK_SVEBITPERM);
+
+ // clear the cached FPU mode bits (FPUMode, NeonMode, SveMode)
+ FPU &= ~(FPUMode | NeonMode | SveMode);
+
+ // re-enable FPUMode if the fp extension is present
+ if (EnabledExtensions.test(llvm::AArch64::AEK_FP))
+ FPU |= FPUMode;
+
+ // re-enable SveMode if the sve extension is present
+ if (EnabledExtensions.test(llvm::AArch64::AEK_SVE))
+ FPU |= SveMode;
+
+ // Frontend FPU mode historically treats SVE as also enabling AdvSIMD, even
+ // though that dependency is not modeled as an architecture extension.
+ if (FPU & SveMode)
+ FPU |= NeonMode;
+
+ // Keep the frontend's historical FPU compatibility for explicit feature
+ // strings such as +aes, +jscvt and +fullfp16 that are not pure ext-bit logic.
+ FPU |= ExplicitFPUCompat & (NeonMode | SveMode);
+ if (HasSVEAES || HasSVEBitPerm)
+ FPU |= NeonMode;
+}
+
void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
StringRef Name, bool Enabled) const {
Features[Name] = Enabled;
@@ -976,221 +1128,78 @@ void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
}
}
+// Reconstruct enough of the AArch64 extension graph to answer implied-feature
+// queries without over-expanding the generic frontend feature map.
+bool AArch64TargetInfo::hasFeatureEnabled(const llvm::StringMap<bool> &Features,
+ StringRef Name) const {
+ auto QueryExt = lookupExtensionForFeatureName(Name);
+ if (!QueryExt)
+ return TargetInfo::hasFeatureEnabled(Features, Name);
+
+ llvm::AArch64::ExtensionSet FeatureBits =
+ buildExtensionSetFromFeatureMap(Features);
+ return FeatureBits.Enabled.test(QueryExt->ID);
+}
+
bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) {
- for (const auto &Feature : Features) {
+ llvm::AArch64::ExtensionSet FeatureBits;
+ ExplicitFPUCompat = 0;
+ FeatureBits.enable(llvm::AArch64::AEK_FP);
+
+ if (std::optional<llvm::AArch64::ArchInfo> BaseArch =
+ findExplicitBaseArchForTargetFeatures(Features)) {
+ FeatureBits.addArchDefaults(*BaseArch);
+ if (BaseArch->DefaultExts.test(llvm::AArch64::AEK_SIMD))
+ ExplicitFPUCompat |= NeonMode;
+ if (BaseArch->DefaultExts.test(llvm::AArch64::AEK_SVE))
+ ExplicitFPUCompat |= SveMode;
+ }
+
+ std::vector<std::string> ExpandedFeatures;
+ ExpandedFeatures.reserve(Features.size());
+
+ for (const std::string &Feature : Features) {
+ if (enablesNeonFPUCompat(Feature))
+ ExplicitFPUCompat |= NeonMode;
+
+ if (auto ExtInfo = lookupExtensionForTargetFeature(Feature)) {
+ if (!Feature.empty() && Feature[0] == '+')
+ FeatureBits.enable(ExtInfo->ID);
+ else if (!Feature.empty() && Feature[0] == '-') {
+ switch (ExtInfo->ID) {
+ case llvm::AArch64::AEK_FP:
+ HasNoFP = true;
+ break;
+ case llvm::AArch64::AEK_SIMD:
+ HasNoNeon = true;
+ break;
+ case llvm::AArch64::AEK_SVE:
+ HasNoSVE = true;
+ break;
+ default:
+ break;
+ }
+ FeatureBits.disable(ExtInfo->ID);
+ }
+ continue;
+ }
+ ExpandedFeatures.push_back(Feature);
+ }
+ FeatureBits.toLLVMFeatureList(ExpandedFeatures);
+ llvm::sort(ExpandedFeatures);
+
+ for (const auto &Feature : ExpandedFeatures) {
if (Feature == "-fp-armv8")
HasNoFP = true;
if (Feature == "-neon")
HasNoNeon = true;
if (Feature == "-sve")
HasNoSVE = true;
-
- if (Feature == "+neon" || Feature == "+fp-armv8")
- FPU |= NeonMode;
- if (Feature == "+jscvt") {
- HasJSCVT = true;
- FPU |= NeonMode;
- }
- if (Feature == "+fcma") {
- HasFCMA = true;
- FPU |= NeonMode;
- }
-
- if (Feature == "+sve") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasFullFP16 = true;
- }
- if (Feature == "+sve2") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasFullFP16 = true;
- HasSVE2 = true;
- }
- if (Feature == "+sve2p1") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasFullFP16 = true;
- HasSVE2 = true;
- HasSVE2p1 = true;
- }
- if (Feature == "+sve-aes") {
- FPU |= NeonMode;
- HasFullFP16 = true;
- HasSVEAES = true;
- }
- if (Feature == "+sve2-sha3") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasFullFP16 = true;
- HasSVE2 = true;
- HasSVE2SHA3 = true;
- }
- if (Feature == "+sve2-sm4") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasFullFP16 = true;
- HasSVE2 = true;
- HasSVE2SM4 = true;
- }
- if (Feature == "+sve-b16b16")
- HasSVEB16B16 = true;
- if (Feature == "+sve-bitperm") {
- FPU |= NeonMode;
- HasFullFP16 = true;
- HasSVEBitPerm = true;
- }
- if (Feature == "+f32mm") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasFullFP16 = true;
- HasMatmulFP32 = true;
- }
- if (Feature == "+f64mm") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasFullFP16 = true;
- HasMatmulFP64 = true;
- }
- if (Feature == "+sme") {
- HasSME = true;
- HasBFloat16 = true;
- HasFullFP16 = true;
- }
- if (Feature == "+sme2") {
- HasSME = true;
- HasSME2 = true;
- HasBFloat16 = true;
- HasFullFP16 = true;
- }
- if (Feature == "+sme2p1") {
- HasSME = true;
- HasSME2 = true;
- HasSME2p1 = true;
- HasBFloat16 = true;
- HasFullFP16 = true;
- }
- if (Feature == "+sme-f64f64") {
- HasSME = true;
- HasSMEF64F64 = true;
- HasBFloat16 = true;
- HasFullFP16 = true;
- }
- if (Feature == "+sme-i16i64") {
- HasSME = true;
- HasSMEI16I64 = true;
- HasBFloat16 = true;
- HasFullFP16 = true;
- }
- if (Feature == "+sme-fa64") {
- FPU |= NeonMode;
- FPU |= SveMode;
- HasSME = true;
- HasSVE2 = true;
- HasSMEFA64 = true;
- }
- if (Feature == "+sme-f16f16") {
- HasSME = true;
- HasSME2 = true;
- HasBFloat16 = true;
- HasFullFP16 = true;
- HasSMEF16F16 = true;
- }
- if (Feature == "+sme-b16b16") {
- HasSME = true;
- HasSME2 = true;
- HasBFloat16 = true;
- HasFullFP16 = true;
- HasSVEB16B16 = true;
- HasSMEB16B16 = true;
- }
-
- if (Feature == "+fp8")
- HasFP8 = true;
- if (Feature == "+fp8fma")
- HasFP8FMA = true;
- if (Feature == "+fp8dot2")
- HasFP8DOT2 = true;
- if (Feature == "+fp8dot4")
- HasFP8DOT4 = true;
- if (Feature == "+ssve-fp8dot2")
- HasSSVE_FP8DOT2 = true;
- if (Feature == "+ssve-fp8dot4")
- HasSSVE_FP8DOT4 = true;
- if (Feature == "+ssve-fp8fma")
- HasSSVE_FP8FMA = true;
- if (Feature == "+sme-f8f32")
- HasSME_F8F32 = true;
- if (Feature == "+sme-f8f16")
- HasSME_F8F16 = true;
- if (Feature == "+sb")
- HasSB = true;
- if (Feature == "+predres")
- HasPredRes = true;
- if (Feature == "+ssbs")
- HasSSBS = true;
- if (Feature == "+bti")
- HasBTI = true;
- if (Feature == "+wfxt")
- HasWFxT = true;
if (Feature == "-fmv")
HasFMV = false;
- if (Feature == "+crc")
- HasCRC = true;
- if (Feature == "+rcpc")
- HasRCPC = true;
- if (Feature == "+aes") {
- FPU |= NeonMode;
- HasAES = true;
- }
- if (Feature == "+sha2") {
- FPU |= NeonMode;
- HasSHA2 = true;
- }
- if (Feature == "+sha3") {
- FPU |= NeonMode;
- HasSHA2 = true;
- HasSHA3 = true;
- }
- if (Feature == "+rdm") {
- FPU |= NeonMode;
- HasRDM = true;
- }
- if (Feature == "+dit")
- HasDIT = true;
- if (Feature == "+cccp")
- HasCCPP = true;
- if (Feature == "+ccdp") {
- HasCCPP = true;
- HasCCDP = true;
- }
- if (Feature == "+fptoint")
- HasFRInt3264 = true;
- if (Feature == "+sm4") {
- FPU |= NeonMode;
- HasSM4 = true;
- }
if (Feature == "+strict-align")
HasUnalignedAccess = false;
- if (Feature == "+fprcvt")
- HasFPRCVT = true;
- if (Feature == "+f8f16mm")
- HasF8F16MM = true;
- if (Feature == "+f8f32mm")
- HasF8F32MM = true;
- if (Feature == "+sve-f16f32mm")
- HasSVE_F16F32MM = true;
- if (Feature == "+sve-bfscale")
- HasSVE_BFSCALE = true;
- if (Feature == "+sve-aes2")
- HasSVE_AES2 = true;
- if (Feature == "+ssve-aes")
- HasSSVE_AES = true;
- if (Feature == "+sve2p2")
- HasSVE2p2 = true;
- if (Feature == "+sme2p2")
- HasSME2p2 = true;
// All predecessor archs are added but select the latest one for ArchKind.
if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
@@ -1247,62 +1256,9 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
ArchInfo = &llvm::AArch64::ARMV9_7A;
if (Feature == "+v8r")
ArchInfo = &llvm::AArch64::ARMV8R;
- if (Feature == "+fullfp16") {
- FPU |= NeonMode;
- HasFullFP16 = true;
- }
- if (Feature == "+dotprod") {
- FPU |= NeonMode;
- HasDotProd = true;
- }
- if (Feature == "+fp16fml") {
- FPU |= NeonMode;
- HasFullFP16 = true;
- HasFP16FML = true;
- }
- if (Feature == "+mte")
- HasMTE = true;
- if (Feature == "+pauth")
- HasPAuth = true;
- if (Feature == "+i8mm")
- HasMatMul = true;
- if (Feature == "+bf16")
- HasBFloat16 = true;
- if (Feature == "+lse")
- HasLSE = true;
- if (Feature == "+ls64")
- HasLS64 = true;
- if (Feature == "+rand")
- HasRandGen = true;
- if (Feature == "+flagm")
- HasFlagM = true;
- if (Feature == "+altnzcv") {
- HasFlagM = true;
- HasAlternativeNZCV = true;
- }
- if (Feature == "+mops")
- HasMOPS = true;
- if (Feature == "+d128")
- HasD128 = true;
- if (Feature == "+gcs")
- HasGCS = true;
- if (Feature == "+rcpc3")
- HasRCPC3 = true;
- if (Feature == "+pauth-lr") {
- HasPAuthLR = true;
- HasPAuth = true;
- }
- if (Feature == "+cssc")
- HasCSSC = true;
}
- // Check features that are manually disabled by command line options.
- // This needs to be checked after architecture-related features are handled,
- // making sure they are properly disabled when required.
- for (const auto &Feature : Features) {
- if (Feature == "-d128")
- HasD128 = false;
- }
+ setFeatureStateFromEnabledExtensions(FeatureBits.Enabled);
resetDataLayout();
@@ -1678,6 +1634,7 @@ bool AArch64TargetInfo::validateConstraintModifier(
return true;
case 'z':
case 'r': {
+ const bool HasLS64 = hasExtension(llvm::AArch64::AEK_LS64);
switch (Modifier) {
case 'x':
case 'w':
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 0a29bad81939b..b0c1fcedbc183 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -69,87 +69,23 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
};
unsigned FPU = FPUMode;
- bool HasCRC = false;
- bool HasCSSC = false;
- bool HasAES = false;
- bool HasSHA2 = false;
- bool HasSHA3 = false;
- bool HasSM4 = false;
- bool HasFullFP16 = false;
- bool HasDotProd = false;
- bool HasFP16FML = false;
- bool HasMTE = false;
- bool HasPAuth = false;
- bool HasLS64 = false;
- bool HasRandGen = false;
- bool HasMatMul = false;
- bool HasBFloat16 = false;
- bool HasSVE2 = false;
- bool HasSVE2p1 = false;
- bool HasSVEAES = false;
- bool HasSVE2SHA3 = false;
- bool HasSVE2SM4 = false;
- bool HasSVEB16B16 = false;
- bool HasSVEBitPerm = false;
- bool HasMatmulFP64 = false;
- bool HasMatmulFP32 = false;
- bool HasLSE = false;
- bool HasFlagM = false;
- bool HasAlternativeNZCV = false;
- bool HasMOPS = false;
- bool HasD128 = false;
- bool HasRCPC = false;
- bool HasRDM = false;
- bool HasDIT = false;
- bool HasCCPP = false;
- bool HasCCDP = false;
- bool HasFRInt3264 = false;
- bool HasSME = false;
- bool HasSME2 = false;
- bool HasSMEF64F64 = false;
- bool HasSMEI16I64 = false;
- bool HasSMEF16F16 = false;
- bool HasSMEB16B16 = false;
- bool HasSME2p1 = false;
- bool HasFP8 = false;
- bool HasFP8FMA = false;
- bool HasFP8DOT2 = false;
- bool HasFP8DOT4 = false;
- bool HasSSVE_FP8DOT2 = false;
- bool HasSSVE_FP8DOT4 = false;
- bool HasSSVE_FP8FMA = false;
- bool HasSME_F8F32 = false;
- bool HasSME_F8F16 = false;
- bool HasSB = false;
- bool HasPredRes = false;
- bool HasSSBS = false;
- bool HasBTI = false;
- bool HasWFxT = false;
- bool HasJSCVT = false;
- bool HasFCMA = false;
+ llvm::AArch64::ExtensionBitset EnabledExtensions;
+ unsigned ExplicitFPUCompat = 0;
bool HasNoFP = false;
bool HasNoNeon = false;
bool HasNoSVE = false;
bool HasFMV = true;
- bool HasGCS = false;
- bool HasRCPC3 = false;
- bool HasSMEFA64 = false;
- bool HasPAuthLR = false;
- bool HasFPRCVT = false;
- bool HasF8F16MM = false;
- bool HasF8F32MM = false;
- bool HasSVE_F16F32MM = false;
- bool HasSVE_BFSCALE = false;
- bool HasSVE_AES2 = false;
- bool HasSSVE_AES = false;
- bool HasSVE2p2 = false;
- bool HasSME2p2 = false;
const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
AArch64FeatureSet HasFeatureLookup;
void computeFeatureLookup();
+ bool hasExtension(llvm::AArch64::ArchExtKind Ext) const;
+ bool hasPAuth() const;
+ bool hasFullFP16() const;
+ void setFeatureStateFromEnabledExtensions(
+ const llvm::AArch64::ExtensionBitset &EnabledExtensions);
protected:
std::string ABI;
@@ -159,6 +95,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
StringRef getABI() const override;
bool setABI(const std::string &Name) override;
+ bool hasFeatureEnabled(const llvm::StringMap<bool> &Features,
+ StringRef Name) const override;
bool validateBranchProtection(StringRef Spec, StringRef Arch,
BranchProtectionInfo &BPI,
diff --git a/clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc b/clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc
new file mode 100644
index 0000000000000..018866eafb6ef
--- /dev/null
+++ b/clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc
@@ -0,0 +1,69 @@
+AARCH64_EXTENSION_FEATURE(HasJSCVT, JSCVT)
+AARCH64_EXTENSION_FEATURE(HasFCMA, FCMA)
+AARCH64_EXTENSION_FEATURE(HasRandGen, RAND)
+AARCH64_EXTENSION_FEATURE(HasFlagM, FLAGM)
+AARCH64_EXTENSION_FEATURE(HasAlternativeNZCV, ALTERNATIVENZCV)
+AARCH64_EXTENSION_FEATURE(HasFP16FML, FP16FML)
+AARCH64_EXTENSION_FEATURE(HasDotProd, DOTPROD)
+AARCH64_EXTENSION_FEATURE(HasSM4, SM4)
+AARCH64_EXTENSION_FEATURE(HasRDM, RDM)
+AARCH64_EXTENSION_FEATURE(HasLSE, LSE)
+AARCH64_EXTENSION_FEATURE(HasCRC, CRC)
+AARCH64_EXTENSION_FEATURE(HasCSSC, CSSC)
+AARCH64_EXTENSION_FEATURE(HasSHA2, SHA2)
+AARCH64_EXTENSION_FEATURE(HasSHA3, SHA3)
+AARCH64_EXTENSION_FEATURE(HasAES, AES)
+AARCH64_EXTENSION_FEATURE(HasDIT, DIT)
+AARCH64_EXTENSION_FEATURE(HasCCPP, CCPP)
+AARCH64_EXTENSION_FEATURE(HasCCDP, CCDP)
+AARCH64_EXTENSION_FEATURE(HasRCPC, RCPC)
+AARCH64_EXTENSION_FEATURE(HasFRInt3264, FRINT3264)
+AARCH64_EXTENSION_FEATURE(HasI8MM, I8MM)
+AARCH64_EXTENSION_FEATURE(HasBFloat16, BF16)
+AARCH64_EXTENSION_FEATURE(HasSVEB16B16, SVEB16B16)
+AARCH64_EXTENSION_FEATURE(HasF32MM, F32MM)
+AARCH64_EXTENSION_FEATURE(HasF64MM, F64MM)
+AARCH64_EXTENSION_FEATURE(HasSVE2, SVE2)
+AARCH64_EXTENSION_FEATURE(HasSVEAES, SVEAES)
+AARCH64_EXTENSION_FEATURE(HasSVEBitPerm, SVEBITPERM)
+AARCH64_EXTENSION_FEATURE(HasSVE2SHA3, SVE2SHA3)
+AARCH64_EXTENSION_FEATURE(HasSVE2SM4, SVE2SM4)
+AARCH64_EXTENSION_FEATURE(HasSVE2p1, SVE2P1)
+AARCH64_EXTENSION_FEATURE(HasSME, SME)
+AARCH64_EXTENSION_FEATURE(HasSME2, SME2)
+AARCH64_EXTENSION_FEATURE(HasSME2p1, SME2P1)
+AARCH64_EXTENSION_FEATURE(HasSMEF64F64, SMEF64F64)
+AARCH64_EXTENSION_FEATURE(HasSMEI16I64, SMEI16I64)
+AARCH64_EXTENSION_FEATURE(HasSMEFA64, SMEFA64)
+AARCH64_EXTENSION_FEATURE(HasSMEF16F16, SMEF16F16)
+AARCH64_EXTENSION_FEATURE(HasSMEB16B16, SMEB16B16)
+AARCH64_EXTENSION_FEATURE(HasMTE, MTE)
+AARCH64_EXTENSION_FEATURE(HasSB, SB)
+AARCH64_EXTENSION_FEATURE(HasPredRes, PREDRES)
+AARCH64_EXTENSION_FEATURE(HasSSBS, SSBS)
+AARCH64_EXTENSION_FEATURE(HasBTI, BTI)
+AARCH64_EXTENSION_FEATURE(HasLS64, LS64)
+AARCH64_EXTENSION_FEATURE(HasWFxT, WFXT)
+AARCH64_EXTENSION_FEATURE(HasRCPC3, RCPC3)
+AARCH64_EXTENSION_FEATURE(HasFP8, FP8)
+AARCH64_EXTENSION_FEATURE(HasFP8FMA, FP8FMA)
+AARCH64_EXTENSION_FEATURE(HasFP8DOT2, FP8DOT2)
+AARCH64_EXTENSION_FEATURE(HasFP8DOT4, FP8DOT4)
+AARCH64_EXTENSION_FEATURE(HasSSVE_FP8DOT2, SSVE_FP8DOT2)
+AARCH64_EXTENSION_FEATURE(HasSSVE_FP8DOT4, SSVE_FP8DOT4)
+AARCH64_EXTENSION_FEATURE(HasSSVE_FP8FMA, SSVE_FP8FMA)
+AARCH64_EXTENSION_FEATURE(HasSME_F8F32, SMEF8F32)
+AARCH64_EXTENSION_FEATURE(HasSME_F8F16, SMEF8F16)
+AARCH64_EXTENSION_FEATURE(HasFPRCVT, FPRCVT)
+AARCH64_EXTENSION_FEATURE(HasF8F16MM, F8F16MM)
+AARCH64_EXTENSION_FEATURE(HasF8F32MM, F8F32MM)
+AARCH64_EXTENSION_FEATURE(HasSVE_F16F32MM, SVE_F16F32MM)
+AARCH64_EXTENSION_FEATURE(HasSVE_BFSCALE, SVE_BFSCALE)
+AARCH64_EXTENSION_FEATURE(HasSVE_AES2, SVE_AES2)
+AARCH64_EXTENSION_FEATURE(HasSSVE_AES, SSVE_AES)
+AARCH64_EXTENSION_FEATURE(HasSVE2p2, SVE2P2)
+AARCH64_EXTENSION_FEATURE(HasSME2p2, SME2P2)
+AARCH64_EXTENSION_FEATURE(HasPAuthLR, PAUTHLR)
+AARCH64_EXTENSION_FEATURE(HasMOPS, MOPS)
+AARCH64_EXTENSION_FEATURE(HasD128, D128)
+AARCH64_EXTENSION_FEATURE(HasGCS, GCS)
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index 7871fd624a467..01dc6915471ad 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1471,7 +1471,7 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
if (UsesSM || UsesZA) {
llvm::StringMap<bool> FeatureMap;
Context.getFunctionFeatureMap(FeatureMap, FD);
- if (!FeatureMap.contains("sme")) {
+ if (!Context.getTargetInfo().hasFeatureEnabled(FeatureMap, "sme")) {
if (UsesSM)
Diag(FD->getLocation(),
diag::err_sme_definition_using_sm_in_non_sme_target);
@@ -1483,7 +1483,7 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
if (UsesZT0) {
llvm::StringMap<bool> FeatureMap;
Context.getFunctionFeatureMap(FeatureMap, FD);
- if (!FeatureMap.contains("sme2")) {
+ if (!Context.getTargetInfo().hasFeatureEnabled(FeatureMap, "sme2")) {
Diag(FD->getLocation(),
diag::err_sme_definition_using_zt0_in_non_sme2_target);
}
@@ -1760,7 +1760,7 @@ bool SemaARM::checkSVETypeSupport(QualType Ty, SourceLocation Loc,
return false;
// No SVE environment available.
- if (!FeatureMap.lookup("sme"))
+ if (!getASTContext().getTargetInfo().hasFeatureEnabled(FeatureMap, "sme"))
return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
// SVE environment only available to streaming functions.
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index eb957df6f1e97..f311fbde97e93 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -4357,7 +4357,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
if (auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
llvm::StringMap<bool> CallerFeatureMap;
Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
- if (!CallerFeatureMap.contains("sme"))
+ if (!Context.getTargetInfo().hasFeatureEnabled(CallerFeatureMap, "sme"))
Diag(Loc, diag::err_sme_call_in_non_sme_target);
} else if (!Context.getTargetInfo().hasFeature("sme")) {
Diag(Loc, diag::err_sme_call_in_non_sme_target);
diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c
index 60ddaad639d48..41393e423f17f 100644
--- a/clang/test/Preprocessor/aarch64-target-features.c
+++ b/clang/test/Preprocessor/aarch64-target-features.c
@@ -235,6 +235,7 @@
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-aes -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2AES %s
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve-aes+sve2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2AES %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2AES %s
// CHECK-SVE2AES: __ARM_FEATURE_AES 1
// CHECK-SVE2AES: __ARM_FEATURE_SVE2 1
// CHECK-SVE2AES: __ARM_FEATURE_SVE2_AES 1
@@ -253,10 +254,12 @@
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-bitperm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve-bitperm+sve2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s
// CHECK-SVE2BITPERM: __ARM_FEATURE_SVE2 1
// CHECK-SVE2BITPERM: __ARM_FEATURE_SVE2_BITPERM 1
// RUN: %clang -target aarch64-none-linux-gnu -march=armv9-a+sve2p1 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p1 %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p1 %s
// CHECK-SVE2p1: __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
// CHECK-SVE2p1: __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
// CHECK-SVE2p1: __ARM_FEATURE_SVE2 1
@@ -271,6 +274,16 @@
// CHECK-DOTPROD: __ARM_NEON 1
// CHECK-DOTPROD: __ARM_NEON_FP 0xE
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +jscvt -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-JSCVT-DIRECT %s
+// CHECK-JSCVT-DIRECT: #define __ARM_NEON 1
+// CHECK-JSCVT-DIRECT: #define __ARM_NEON_FP 0xE
+
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SME-DIRECT %s
+// CHECK-SME-DIRECT-NOT: #define __ARM_NEON 1
+// CHECK-SME-DIRECT-NOT: #define __ARM_NEON_FP 0xE
+// CHECK-SME-DIRECT: #define __ARM_FEATURE_LOCALLY_STREAMING 1
+// CHECK-SME-DIRECT: #define __ARM_FEATURE_SME
+
// On ARMv8.2-A and above, +fp16fml implies +fp16.
// On ARMv8.4-A and above, +fp16 implies +fp16fml.
// RUN: %clang --target=aarch64 -march=armv8.2-a+nofp16fml+fp16 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-NOFML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
@@ -283,12 +296,18 @@
// RUN: %clang --target=aarch64 -march=armv8.4-a+fp16+nofp16fml -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-NOFML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
// RUN: %clang --target=aarch64 -march=armv8.4-a+fp16fml -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-FML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
// RUN: %clang --target=aarch64 -march=armv8.4-a+fp16 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-FML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +fullfp16 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-DIRECT %s
// CHECK-FULLFP16-FML: #define __ARM_FEATURE_FP16_FML 1
// CHECK-FULLFP16-NOFML-NOT: #define __ARM_FEATURE_FP16_FML 1
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FP 0xE
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FP16_FORMAT_IEEE 1
+// CHECK-FULLFP16-DIRECT: #define __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
+// CHECK-FULLFP16-DIRECT: #define __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
+// CHECK-FULLFP16-DIRECT: #define __ARM_FP 0xE
+// CHECK-FULLFP16-DIRECT: #define __ARM_FP16_FORMAT_IEEE 1
+// CHECK-FULLFP16-DIRECT: #define __ARM_NEON 1
// +fp16fml+nosimd doesn't make sense as the fp16fml instructions all require SIMD.
// However, as +fp16fml implies +fp16 there is a set of defines that we would expect.
@@ -736,12 +755,14 @@
// CHECK-SVEB16B16: __ARM_FEATURE_SVE_B16B16 1
// RUN: %clang --target=aarch64 -march=armv9-a+sme-f16f16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEF16F16 %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme-f16f16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEF16F16 %s
// CHECK-SMEF16F16: __ARM_FEATURE_LOCALLY_STREAMING 1
// CHECK-SMEF16F16: __ARM_FEATURE_SME 1
// CHECK-SMEF16F16: __ARM_FEATURE_SME2 1
// CHECK-SMEF16F16: __ARM_FEATURE_SME_F16F16 1
// RUN: %clang --target=aarch64 -march=armv9-a+sme-b16b16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEB16B16 %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme-b16b16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEB16B16 %s
// CHECK-SMEB16B16: __ARM_FEATURE_LOCALLY_STREAMING 1
// CHECK-SMEB16B16: __ARM_FEATURE_SME 1
// CHECK-SMEB16B16: __ARM_FEATURE_SME2 1
@@ -818,6 +839,7 @@
// CHECK-SSVE-AES: __ARM_FEATURE_SVE2_AES 1
// RUN: %clang -target aarch64-none-linux-gnu -march=armv9-a+sve2p2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p2 %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p2 %s
// CHECK-SVE2p2: __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
// CHECK-SVE2p2: __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
// CHECK-SVE2p2: __ARM_FEATURE_SVE2 1
diff --git a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
index 2ba266a93f94f..821c0082a3458 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
+++ b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
@@ -21,6 +21,11 @@ __arm_locally_streaming __attribute__((target("sme"))) void locally_streaming_de
// Test that it also works with the target("sme2") attribute.
__attribute__((target("sme2"))) void streaming_def_sme2_attr() __arm_streaming { } // OK
+// Explicit target disables must win over arch/default SME implications.
+__attribute__((target("arch=armv9.3-a,no-sme"))) void streaming_def_arch_no_sme() __arm_streaming { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
+__attribute__((target("sme2,no-sme"))) void streaming_def_sme2_no_sme() __arm_streaming { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
+__attribute__((target("sme2,no-sme"))) void inout_zt0_def_sme2_no_sme() __arm_inout("zt0") { } // expected-error {{function using ZT0 state requires 'sme2'}}
+
// No code is generated for declarations, so it should be fine to declare using the attribute.
void streaming_compatible_decl() __arm_streaming_compatible; // OK
void streaming_decl() __arm_streaming; // OK
>From 166c29e2ad3bd125ab7d626e4acda0231d99a8c2 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Wed, 8 Apr 2026 15:25:27 +0100
Subject: [PATCH 2/2] fixup! Don't checkin AArch64TargetInfoFeatures.inc but
generate from tablegen
---
clang/lib/Basic/Targets/AArch64.cpp | 24 ++++---
.../Targets/AArch64TargetInfoFeatures.inc | 69 -------------------
.../Preprocessor/aarch64-target-features.c | 22 ------
...-sme-func-attrs-without-target-feature.cpp | 5 --
.../TableGen/Basic/ARMTargetDefEmitter.cpp | 23 +++++++
5 files changed, 39 insertions(+), 104 deletions(-)
delete mode 100644 clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 399d9ed5ae052..0bb7b489e1d00 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -42,6 +42,20 @@ static_assert(NumBuiltins ==
(NumNeonBuiltins + NumFp16Builtins + NumSVEBuiltins +
NumSVENeonBridgeBuiltins + NumSMEBuiltins + NumAArch64Builtins));
+#define AARCH64_HAS_EXT(ArchExtKind) hasExtension(llvm::AArch64::ArchExtKind)
+#define EMIT_EXTENSION_FEATURE_LOCAL_DECLS
+#include "llvm/TargetParser/AArch64TargetParserDef.inc"
+#define DECLARE_AARCH64_EXTENSION_FEATURE_LOCALS() \
+ AARCH64_DECLARE_EXTENSION_FEATURE_LOCALS(AARCH64_HAS_EXT) \
+ [[maybe_unused]] const bool HasFCMA = HasComplxNum; \
+ [[maybe_unused]] const bool HasJSCVT = HasJS; \
+ [[maybe_unused]] const bool HasBFloat16 = HasBF16; \
+ [[maybe_unused]] const bool HasI8MM = HasMatMulInt8; \
+ [[maybe_unused]] const bool HasF32MM = HasMatMulFP32; \
+ [[maybe_unused]] const bool HasF64MM = HasMatMulFP64; \
+ [[maybe_unused]] const bool HasSME_F8F32 = HasSMEF8F32; \
+ [[maybe_unused]] const bool HasSME_F8F16 = HasSMEF8F16;
+
namespace clang {
namespace AArch64 {
#define GET_BUILTIN_STR_TABLE
@@ -497,10 +511,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
const bool HasSVE = FPU & SveMode;
const bool HasNeon = FPU & NeonMode;
-#define AARCH64_EXTENSION_FEATURE(Name, Ext) \
- [[maybe_unused]] const bool Name = hasExtension(llvm::AArch64::AEK_##Ext);
-#include "AArch64TargetInfoFeatures.inc"
-#undef AARCH64_EXTENSION_FEATURE
+ DECLARE_AARCH64_EXTENSION_FEATURE_LOCALS()
if (HasSVE2)
Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
@@ -880,10 +891,7 @@ void AArch64TargetInfo::computeFeatureLookup() {
const bool HasFP = FPU & FPUMode;
const bool HasNeon = FPU & NeonMode;
const bool HasSVE = FPU & SveMode;
-#define AARCH64_EXTENSION_FEATURE(Name, Ext) \
- [[maybe_unused]] const bool Name = hasExtension(llvm::AArch64::AEK_##Ext);
-#include "AArch64TargetInfoFeatures.inc"
-#undef AARCH64_EXTENSION_FEATURE
+ DECLARE_AARCH64_EXTENSION_FEATURE_LOCALS()
FeatureLookupBuilder(HasFeatureLookup)
.Cases({"aarch64", "arm64", "arm"}, true)
diff --git a/clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc b/clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc
deleted file mode 100644
index 018866eafb6ef..0000000000000
--- a/clang/lib/Basic/Targets/AArch64TargetInfoFeatures.inc
+++ /dev/null
@@ -1,69 +0,0 @@
-AARCH64_EXTENSION_FEATURE(HasJSCVT, JSCVT)
-AARCH64_EXTENSION_FEATURE(HasFCMA, FCMA)
-AARCH64_EXTENSION_FEATURE(HasRandGen, RAND)
-AARCH64_EXTENSION_FEATURE(HasFlagM, FLAGM)
-AARCH64_EXTENSION_FEATURE(HasAlternativeNZCV, ALTERNATIVENZCV)
-AARCH64_EXTENSION_FEATURE(HasFP16FML, FP16FML)
-AARCH64_EXTENSION_FEATURE(HasDotProd, DOTPROD)
-AARCH64_EXTENSION_FEATURE(HasSM4, SM4)
-AARCH64_EXTENSION_FEATURE(HasRDM, RDM)
-AARCH64_EXTENSION_FEATURE(HasLSE, LSE)
-AARCH64_EXTENSION_FEATURE(HasCRC, CRC)
-AARCH64_EXTENSION_FEATURE(HasCSSC, CSSC)
-AARCH64_EXTENSION_FEATURE(HasSHA2, SHA2)
-AARCH64_EXTENSION_FEATURE(HasSHA3, SHA3)
-AARCH64_EXTENSION_FEATURE(HasAES, AES)
-AARCH64_EXTENSION_FEATURE(HasDIT, DIT)
-AARCH64_EXTENSION_FEATURE(HasCCPP, CCPP)
-AARCH64_EXTENSION_FEATURE(HasCCDP, CCDP)
-AARCH64_EXTENSION_FEATURE(HasRCPC, RCPC)
-AARCH64_EXTENSION_FEATURE(HasFRInt3264, FRINT3264)
-AARCH64_EXTENSION_FEATURE(HasI8MM, I8MM)
-AARCH64_EXTENSION_FEATURE(HasBFloat16, BF16)
-AARCH64_EXTENSION_FEATURE(HasSVEB16B16, SVEB16B16)
-AARCH64_EXTENSION_FEATURE(HasF32MM, F32MM)
-AARCH64_EXTENSION_FEATURE(HasF64MM, F64MM)
-AARCH64_EXTENSION_FEATURE(HasSVE2, SVE2)
-AARCH64_EXTENSION_FEATURE(HasSVEAES, SVEAES)
-AARCH64_EXTENSION_FEATURE(HasSVEBitPerm, SVEBITPERM)
-AARCH64_EXTENSION_FEATURE(HasSVE2SHA3, SVE2SHA3)
-AARCH64_EXTENSION_FEATURE(HasSVE2SM4, SVE2SM4)
-AARCH64_EXTENSION_FEATURE(HasSVE2p1, SVE2P1)
-AARCH64_EXTENSION_FEATURE(HasSME, SME)
-AARCH64_EXTENSION_FEATURE(HasSME2, SME2)
-AARCH64_EXTENSION_FEATURE(HasSME2p1, SME2P1)
-AARCH64_EXTENSION_FEATURE(HasSMEF64F64, SMEF64F64)
-AARCH64_EXTENSION_FEATURE(HasSMEI16I64, SMEI16I64)
-AARCH64_EXTENSION_FEATURE(HasSMEFA64, SMEFA64)
-AARCH64_EXTENSION_FEATURE(HasSMEF16F16, SMEF16F16)
-AARCH64_EXTENSION_FEATURE(HasSMEB16B16, SMEB16B16)
-AARCH64_EXTENSION_FEATURE(HasMTE, MTE)
-AARCH64_EXTENSION_FEATURE(HasSB, SB)
-AARCH64_EXTENSION_FEATURE(HasPredRes, PREDRES)
-AARCH64_EXTENSION_FEATURE(HasSSBS, SSBS)
-AARCH64_EXTENSION_FEATURE(HasBTI, BTI)
-AARCH64_EXTENSION_FEATURE(HasLS64, LS64)
-AARCH64_EXTENSION_FEATURE(HasWFxT, WFXT)
-AARCH64_EXTENSION_FEATURE(HasRCPC3, RCPC3)
-AARCH64_EXTENSION_FEATURE(HasFP8, FP8)
-AARCH64_EXTENSION_FEATURE(HasFP8FMA, FP8FMA)
-AARCH64_EXTENSION_FEATURE(HasFP8DOT2, FP8DOT2)
-AARCH64_EXTENSION_FEATURE(HasFP8DOT4, FP8DOT4)
-AARCH64_EXTENSION_FEATURE(HasSSVE_FP8DOT2, SSVE_FP8DOT2)
-AARCH64_EXTENSION_FEATURE(HasSSVE_FP8DOT4, SSVE_FP8DOT4)
-AARCH64_EXTENSION_FEATURE(HasSSVE_FP8FMA, SSVE_FP8FMA)
-AARCH64_EXTENSION_FEATURE(HasSME_F8F32, SMEF8F32)
-AARCH64_EXTENSION_FEATURE(HasSME_F8F16, SMEF8F16)
-AARCH64_EXTENSION_FEATURE(HasFPRCVT, FPRCVT)
-AARCH64_EXTENSION_FEATURE(HasF8F16MM, F8F16MM)
-AARCH64_EXTENSION_FEATURE(HasF8F32MM, F8F32MM)
-AARCH64_EXTENSION_FEATURE(HasSVE_F16F32MM, SVE_F16F32MM)
-AARCH64_EXTENSION_FEATURE(HasSVE_BFSCALE, SVE_BFSCALE)
-AARCH64_EXTENSION_FEATURE(HasSVE_AES2, SVE_AES2)
-AARCH64_EXTENSION_FEATURE(HasSSVE_AES, SSVE_AES)
-AARCH64_EXTENSION_FEATURE(HasSVE2p2, SVE2P2)
-AARCH64_EXTENSION_FEATURE(HasSME2p2, SME2P2)
-AARCH64_EXTENSION_FEATURE(HasPAuthLR, PAUTHLR)
-AARCH64_EXTENSION_FEATURE(HasMOPS, MOPS)
-AARCH64_EXTENSION_FEATURE(HasD128, D128)
-AARCH64_EXTENSION_FEATURE(HasGCS, GCS)
diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c
index 41393e423f17f..60ddaad639d48 100644
--- a/clang/test/Preprocessor/aarch64-target-features.c
+++ b/clang/test/Preprocessor/aarch64-target-features.c
@@ -235,7 +235,6 @@
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-aes -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2AES %s
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve-aes+sve2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2AES %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-aes -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2AES %s
// CHECK-SVE2AES: __ARM_FEATURE_AES 1
// CHECK-SVE2AES: __ARM_FEATURE_SVE2 1
// CHECK-SVE2AES: __ARM_FEATURE_SVE2_AES 1
@@ -254,12 +253,10 @@
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve2-bitperm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve-bitperm+sve2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2-bitperm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2BITPERM %s
// CHECK-SVE2BITPERM: __ARM_FEATURE_SVE2 1
// CHECK-SVE2BITPERM: __ARM_FEATURE_SVE2_BITPERM 1
// RUN: %clang -target aarch64-none-linux-gnu -march=armv9-a+sve2p1 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p1 %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p1 %s
// CHECK-SVE2p1: __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
// CHECK-SVE2p1: __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
// CHECK-SVE2p1: __ARM_FEATURE_SVE2 1
@@ -274,16 +271,6 @@
// CHECK-DOTPROD: __ARM_NEON 1
// CHECK-DOTPROD: __ARM_NEON_FP 0xE
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +jscvt -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-JSCVT-DIRECT %s
-// CHECK-JSCVT-DIRECT: #define __ARM_NEON 1
-// CHECK-JSCVT-DIRECT: #define __ARM_NEON_FP 0xE
-
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SME-DIRECT %s
-// CHECK-SME-DIRECT-NOT: #define __ARM_NEON 1
-// CHECK-SME-DIRECT-NOT: #define __ARM_NEON_FP 0xE
-// CHECK-SME-DIRECT: #define __ARM_FEATURE_LOCALLY_STREAMING 1
-// CHECK-SME-DIRECT: #define __ARM_FEATURE_SME
-
// On ARMv8.2-A and above, +fp16fml implies +fp16.
// On ARMv8.4-A and above, +fp16 implies +fp16fml.
// RUN: %clang --target=aarch64 -march=armv8.2-a+nofp16fml+fp16 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-NOFML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
@@ -296,18 +283,12 @@
// RUN: %clang --target=aarch64 -march=armv8.4-a+fp16+nofp16fml -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-NOFML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
// RUN: %clang --target=aarch64 -march=armv8.4-a+fp16fml -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-FML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
// RUN: %clang --target=aarch64 -march=armv8.4-a+fp16 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-FML --check-prefix=CHECK-FULLFP16-VECTOR-SCALAR %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +fullfp16 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-FULLFP16-DIRECT %s
// CHECK-FULLFP16-FML: #define __ARM_FEATURE_FP16_FML 1
// CHECK-FULLFP16-NOFML-NOT: #define __ARM_FEATURE_FP16_FML 1
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FP 0xE
// CHECK-FULLFP16-VECTOR-SCALAR: #define __ARM_FP16_FORMAT_IEEE 1
-// CHECK-FULLFP16-DIRECT: #define __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
-// CHECK-FULLFP16-DIRECT: #define __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
-// CHECK-FULLFP16-DIRECT: #define __ARM_FP 0xE
-// CHECK-FULLFP16-DIRECT: #define __ARM_FP16_FORMAT_IEEE 1
-// CHECK-FULLFP16-DIRECT: #define __ARM_NEON 1
// +fp16fml+nosimd doesn't make sense as the fp16fml instructions all require SIMD.
// However, as +fp16fml implies +fp16 there is a set of defines that we would expect.
@@ -755,14 +736,12 @@
// CHECK-SVEB16B16: __ARM_FEATURE_SVE_B16B16 1
// RUN: %clang --target=aarch64 -march=armv9-a+sme-f16f16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEF16F16 %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme-f16f16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEF16F16 %s
// CHECK-SMEF16F16: __ARM_FEATURE_LOCALLY_STREAMING 1
// CHECK-SMEF16F16: __ARM_FEATURE_SME 1
// CHECK-SMEF16F16: __ARM_FEATURE_SME2 1
// CHECK-SMEF16F16: __ARM_FEATURE_SME_F16F16 1
// RUN: %clang --target=aarch64 -march=armv9-a+sme-b16b16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEB16B16 %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme-b16b16 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SMEB16B16 %s
// CHECK-SMEB16B16: __ARM_FEATURE_LOCALLY_STREAMING 1
// CHECK-SMEB16B16: __ARM_FEATURE_SME 1
// CHECK-SMEB16B16: __ARM_FEATURE_SME2 1
@@ -839,7 +818,6 @@
// CHECK-SSVE-AES: __ARM_FEATURE_SVE2_AES 1
// RUN: %clang -target aarch64-none-linux-gnu -march=armv9-a+sve2p2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p2 %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p2 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE2p2 %s
// CHECK-SVE2p2: __ARM_FEATURE_FP16_SCALAR_ARITHMETIC 1
// CHECK-SVE2p2: __ARM_FEATURE_FP16_VECTOR_ARITHMETIC 1
// CHECK-SVE2p2: __ARM_FEATURE_SVE2 1
diff --git a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
index 821c0082a3458..2ba266a93f94f 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
+++ b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
@@ -21,11 +21,6 @@ __arm_locally_streaming __attribute__((target("sme"))) void locally_streaming_de
// Test that it also works with the target("sme2") attribute.
__attribute__((target("sme2"))) void streaming_def_sme2_attr() __arm_streaming { } // OK
-// Explicit target disables must win over arch/default SME implications.
-__attribute__((target("arch=armv9.3-a,no-sme"))) void streaming_def_arch_no_sme() __arm_streaming { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
-__attribute__((target("sme2,no-sme"))) void streaming_def_sme2_no_sme() __arm_streaming { } // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
-__attribute__((target("sme2,no-sme"))) void inout_zt0_def_sme2_no_sme() __arm_inout("zt0") { } // expected-error {{function using ZT0 state requires 'sme2'}}
-
// No code is generated for declarations, so it should be fine to declare using the attribute.
void streaming_compatible_decl() __arm_streaming_compatible; // OK
void streaming_decl() __arm_streaming; // OK
diff --git a/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp
index a18fed082207f..4d62215d3d395 100644
--- a/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp
@@ -150,6 +150,29 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
<< "#endif // EMIT_EXTENSIONS\n"
<< "\n";
+ // Emit a macro that expands to local bool declarations for each extension,
+ // parameterized by a caller-provided extension test helper.
+ OS << "#ifdef EMIT_EXTENSION_FEATURE_LOCAL_DECLS\n"
+ << "#ifndef AARCH64_DECLARE_EXTENSION_FEATURE_LOCALS\n"
+ << "#define AARCH64_DECLARE_EXTENSION_FEATURE_LOCALS(TEST_EXT) \\\n";
+ for (size_t I = 0; I < SortedExtensions.size(); ++I) {
+ const Record *Rec = SortedExtensions[I];
+ std::string FieldName(Rec->getValueAsString("FieldName"));
+ if (FieldName == "HasSVE")
+ FieldName = "HasSVEExt";
+ auto AEK = Rec->getValueAsString("ArchExtKindSpelling").upper();
+ OS << " [[maybe_unused]] const bool " << FieldName << " = TEST_EXT(" << AEK
+ << ");";
+ if (I + 1 != SortedExtensions.size())
+ OS << " \\\n";
+ else
+ OS << "\n";
+ }
+ OS << "#endif\n"
+ << "#undef EMIT_EXTENSION_FEATURE_LOCAL_DECLS\n"
+ << "#endif // EMIT_EXTENSION_FEATURE_LOCAL_DECLS\n"
+ << "\n";
+
// Emit FMV information
auto FMVExts = RK.getAllDerivedDefinitionsIfDefined("FMVExtension");
OS << "#ifdef EMIT_FMV_INFO\n"
More information about the cfe-commits
mailing list