Skip to content

Commit 8d58882

Browse files
committed
Revert "[AArch64] Decouple feature dependency expansion. (#94279)"
This reverts commit 2cf1439 since it broke the llvm test suite: SingleSource/UnitTests/AArch64/acle-fmv-features.c:59:9: error: instruction requires: altnzcv SingleSource/UnitTests/AArch64/acle-fmv-features.c:117:10: error: instruction requires: aes ... Looks like the FMV dependencies were used in the target attribute and now features that are FMVOnly (have AEK_NONE) cannot be expanded in parseTargetAttr using the ExtensionSet. This suggests that either the tests are wrong (they are using an FMVOnly feature in a target attribute), or that we need to turn the FMVOnly features into Extensions (these two are tablegen classes).
1 parent 3c8e0b8 commit 8d58882

File tree

12 files changed

+222
-213
lines changed

12 files changed

+222
-213
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,6 +3203,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
32033203
/// valid feature names.
32043204
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
32053205

3206+
std::vector<std::string>
3207+
filterFunctionTargetVersionAttrs(const TargetVersionAttr *TV) const;
3208+
32063209
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
32073210
const FunctionDecl *) const;
32083211
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,

clang/lib/AST/ASTContext.cpp

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@
8787
#include "llvm/Support/MD5.h"
8888
#include "llvm/Support/MathExtras.h"
8989
#include "llvm/Support/raw_ostream.h"
90-
#include "llvm/TargetParser/AArch64TargetParser.h"
9190
#include "llvm/TargetParser/Triple.h"
9291
#include <algorithm>
9392
#include <cassert>
@@ -13664,20 +13663,17 @@ QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const {
1366413663
}
1366513664
}
1366613665

13667-
// Given a list of FMV features, return a concatenated list of the
13668-
// corresponding backend features (which may contain duplicates).
13669-
static std::vector<std::string> getFMVBackendFeaturesFor(
13670-
const llvm::SmallVectorImpl<StringRef> &FMVFeatStrings) {
13671-
std::vector<std::string> BackendFeats;
13672-
for (StringRef F : FMVFeatStrings) {
13673-
if (auto FMVExt = llvm::AArch64::parseArchExtension(F)) {
13674-
SmallVector<StringRef, 8> Feats;
13675-
FMVExt->DependentFeatures.split(Feats, ',', -1, false);
13676-
for (StringRef F : Feats)
13677-
BackendFeats.push_back(F.str());
13678-
}
13679-
}
13680-
return BackendFeats;
13666+
std::vector<std::string> ASTContext::filterFunctionTargetVersionAttrs(
13667+
const TargetVersionAttr *TV) const {
13668+
assert(TV != nullptr);
13669+
llvm::SmallVector<StringRef, 8> Feats;
13670+
std::vector<std::string> ResFeats;
13671+
TV->getFeatures(Feats);
13672+
for (auto &Feature : Feats)
13673+
if (Target->validateCpuSupports(Feature.str()))
13674+
// Use '?' to mark features that came from TargetVersion.
13675+
ResFeats.push_back("?" + Feature.str());
13676+
return ResFeats;
1368113677
}
1368213678

1368313679
ParsedTargetAttr
@@ -13712,12 +13708,10 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
1371213708

1371313709
// Make a copy of the features as passed on the command line into the
1371413710
// beginning of the additional features from the function to override.
13715-
// AArch64 handles command line option features in parseTargetAttr().
13716-
if (!Target->getTriple().isAArch64())
13717-
ParsedAttr.Features.insert(
13718-
ParsedAttr.Features.begin(),
13719-
Target->getTargetOpts().FeaturesAsWritten.begin(),
13720-
Target->getTargetOpts().FeaturesAsWritten.end());
13711+
ParsedAttr.Features.insert(
13712+
ParsedAttr.Features.begin(),
13713+
Target->getTargetOpts().FeaturesAsWritten.begin(),
13714+
Target->getTargetOpts().FeaturesAsWritten.end());
1372113715

1372213716
if (ParsedAttr.CPU != "" && Target->isValidCPUName(ParsedAttr.CPU))
1372313717
TargetCPU = ParsedAttr.CPU;
@@ -13738,31 +13732,32 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
1373813732
Target->getTargetOpts().FeaturesAsWritten.end());
1373913733
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
1374013734
} else if (const auto *TC = FD->getAttr<TargetClonesAttr>()) {
13735+
std::vector<std::string> Features;
1374113736
if (Target->getTriple().isAArch64()) {
13737+
// TargetClones for AArch64
1374213738
llvm::SmallVector<StringRef, 8> Feats;
1374313739
TC->getFeatures(Feats, GD.getMultiVersionIndex());
13744-
std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);
13740+
for (StringRef Feat : Feats)
13741+
if (Target->validateCpuSupports(Feat.str()))
13742+
// Use '?' to mark features that came from AArch64 TargetClones.
13743+
Features.push_back("?" + Feat.str());
1374513744
Features.insert(Features.begin(),
1374613745
Target->getTargetOpts().FeaturesAsWritten.begin(),
1374713746
Target->getTargetOpts().FeaturesAsWritten.end());
13748-
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
1374913747
} else {
13750-
std::vector<std::string> Features;
1375113748
StringRef VersionStr = TC->getFeatureStr(GD.getMultiVersionIndex());
1375213749
if (VersionStr.starts_with("arch="))
1375313750
TargetCPU = VersionStr.drop_front(sizeof("arch=") - 1);
1375413751
else if (VersionStr != "default")
1375513752
Features.push_back((StringRef{"+"} + VersionStr).str());
13756-
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
1375713753
}
13758-
} else if (const auto *TV = FD->getAttr<TargetVersionAttr>()) {
13759-
llvm::SmallVector<StringRef, 8> Feats;
13760-
TV->getFeatures(Feats);
13761-
std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);
13762-
Features.insert(Features.begin(),
13763-
Target->getTargetOpts().FeaturesAsWritten.begin(),
13764-
Target->getTargetOpts().FeaturesAsWritten.end());
1376513754
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
13755+
} else if (const auto *TV = FD->getAttr<TargetVersionAttr>()) {
13756+
std::vector<std::string> Feats = filterFunctionTargetVersionAttrs(TV);
13757+
Feats.insert(Feats.begin(),
13758+
Target->getTargetOpts().FeaturesAsWritten.begin(),
13759+
Target->getTargetOpts().FeaturesAsWritten.end());
13760+
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Feats);
1376613761
} else {
1376713762
FeatureMap = Target->getTargetOpts().FeatureMap;
1376813763
}

clang/lib/AST/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,4 @@ add_clang_library(clangAST
139139
omp_gen
140140
ClangDriverOptions
141141
intrinsics_gen
142-
# These generated headers are included transitively.
143-
AArch64TargetParserTableGen
144142
)

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,18 +1052,57 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
10521052
return true;
10531053
}
10541054

1055+
bool AArch64TargetInfo::initFeatureMap(
1056+
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
1057+
const std::vector<std::string> &FeaturesVec) const {
1058+
std::vector<std::string> UpdatedFeaturesVec;
1059+
// Parse the CPU and add any implied features.
1060+
std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU);
1061+
if (CpuInfo) {
1062+
auto Exts = CpuInfo->getImpliedExtensions();
1063+
std::vector<StringRef> CPUFeats;
1064+
llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
1065+
for (auto F : CPUFeats) {
1066+
assert((F[0] == '+' || F[0] == '-') && "Expected +/- in target feature!");
1067+
UpdatedFeaturesVec.push_back(F.str());
1068+
}
1069+
}
1070+
1071+
// Process target and dependent features. This is done in two loops collecting
1072+
// them into UpdatedFeaturesVec: first to add dependent '+'features, second to
1073+
// add target '+/-'features that can later disable some of features added on
1074+
// the first loop. Function Multi Versioning features begin with '?'.
1075+
for (const auto &Feature : FeaturesVec)
1076+
if (((Feature[0] == '?' || Feature[0] == '+')) &&
1077+
AArch64TargetInfo::doesFeatureAffectCodeGen(Feature.substr(1))) {
1078+
StringRef DepFeatures =
1079+
AArch64TargetInfo::getFeatureDependencies(Feature.substr(1));
1080+
SmallVector<StringRef, 1> AttrFeatures;
1081+
DepFeatures.split(AttrFeatures, ",");
1082+
for (auto F : AttrFeatures)
1083+
UpdatedFeaturesVec.push_back(F.str());
1084+
}
1085+
for (const auto &Feature : FeaturesVec)
1086+
if (Feature[0] != '?') {
1087+
std::string UpdatedFeature = Feature;
1088+
if (Feature[0] == '+') {
1089+
std::optional<llvm::AArch64::ExtensionInfo> Extension =
1090+
llvm::AArch64::parseArchExtension(Feature.substr(1));
1091+
if (Extension)
1092+
UpdatedFeature = Extension->Feature.str();
1093+
}
1094+
UpdatedFeaturesVec.push_back(UpdatedFeature);
1095+
}
1096+
1097+
return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
1098+
}
1099+
10551100
// Parse AArch64 Target attributes, which are a comma separated list of:
10561101
// "arch=<arch>" - parsed to features as per -march=..
10571102
// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
10581103
// "tune=<cpu>" - TuneCPU set to <cpu>
10591104
// "feature", "no-feature" - Add (or remove) feature.
10601105
// "+feature", "+nofeature" - Add (or remove) feature.
1061-
//
1062-
// A feature may correspond to an Extension (anything with a corresponding
1063-
// AEK_), in which case an ExtensionSet is used to parse it and expand its
1064-
// dependencies. Otherwise the feature is passed through (e.g. +v8.1a,
1065-
// +outline-atomics, -fmv, etc). Features coming from the command line are
1066-
// already parsed, therefore their dependencies do not need expansion.
10671106
ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
10681107
ParsedTargetAttr Ret;
10691108
if (Features == "default")
@@ -1073,26 +1112,23 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
10731112
bool FoundArch = false;
10741113

10751114
auto SplitAndAddFeatures = [](StringRef FeatString,
1076-
std::vector<std::string> &Features,
1077-
llvm::AArch64::ExtensionSet &FeatureBits) {
1115+
std::vector<std::string> &Features) {
10781116
SmallVector<StringRef, 8> SplitFeatures;
10791117
FeatString.split(SplitFeatures, StringRef("+"), -1, false);
10801118
for (StringRef Feature : SplitFeatures) {
1081-
if (FeatureBits.parseModifier(Feature, /* AllowNoDashForm = */ true))
1082-
continue;
1083-
// Pass through features that are not extensions, e.g. +v8.1a,
1084-
// +outline-atomics, -fmv, etc.
1085-
if (Feature.starts_with("no"))
1086-
Features.push_back("-" + Feature.drop_front(2).str());
1119+
StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1120+
if (!FeatureName.empty())
1121+
Features.push_back(FeatureName.str());
10871122
else
1088-
Features.push_back("+" + Feature.str());
1123+
// Pushing the original feature string to give a sema error later on
1124+
// when they get checked.
1125+
if (Feature.starts_with("no"))
1126+
Features.push_back("-" + Feature.drop_front(2).str());
1127+
else
1128+
Features.push_back("+" + Feature.str());
10891129
}
10901130
};
10911131

1092-
llvm::AArch64::ExtensionSet FeatureBits;
1093-
// Reconstruct the bitset from the command line option features.
1094-
FeatureBits.reconstructFromParsedFeatures(getTargetOpts().FeaturesAsWritten);
1095-
10961132
for (auto &Feature : AttrFeatures) {
10971133
Feature = Feature.trim();
10981134
if (Feature.starts_with("fpmath="))
@@ -1115,9 +1151,9 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11151151
// Ret.Features.
11161152
if (!AI)
11171153
continue;
1118-
FeatureBits.addArchDefaults(*AI);
1154+
Ret.Features.push_back(AI->ArchFeature.str());
11191155
// Add any extra features, after the +
1120-
SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1156+
SplitAndAddFeatures(Split.second, Ret.Features);
11211157
} else if (Feature.starts_with("cpu=")) {
11221158
if (!Ret.CPU.empty())
11231159
Ret.Duplicate = "cpu=";
@@ -1127,30 +1163,33 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
11271163
std::pair<StringRef, StringRef> Split =
11281164
Feature.split("=").second.trim().split("+");
11291165
Ret.CPU = Split.first;
1130-
if (auto CpuInfo = llvm::AArch64::parseCpu(Ret.CPU)) {
1131-
FeatureBits.addCPUDefaults(*CpuInfo);
1132-
SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1133-
}
1166+
SplitAndAddFeatures(Split.second, Ret.Features);
11341167
}
11351168
} else if (Feature.starts_with("tune=")) {
11361169
if (!Ret.Tune.empty())
11371170
Ret.Duplicate = "tune=";
11381171
else
11391172
Ret.Tune = Feature.split("=").second.trim();
11401173
} else if (Feature.starts_with("+")) {
1141-
SplitAndAddFeatures(Feature, Ret.Features, FeatureBits);
1174+
SplitAndAddFeatures(Feature, Ret.Features);
1175+
} else if (Feature.starts_with("no-")) {
1176+
StringRef FeatureName =
1177+
llvm::AArch64::getArchExtFeature(Feature.split("-").second);
1178+
if (!FeatureName.empty())
1179+
Ret.Features.push_back("-" + FeatureName.drop_front(1).str());
1180+
else
1181+
Ret.Features.push_back("-" + Feature.split("-").second.str());
11421182
} else {
1143-
if (FeatureBits.parseModifier(Feature, /* AllowNoDashForm = */ true))
1144-
continue;
1145-
// Pass through features that are not extensions, e.g. +v8.1a,
1146-
// +outline-atomics, -fmv, etc.
1147-
if (Feature.starts_with("no-"))
1148-
Ret.Features.push_back("-" + Feature.drop_front(3).str());
1183+
// Try parsing the string to the internal target feature name. If it is
1184+
// invalid, add the original string (which could already be an internal
1185+
// name). These should be checked later by isValidFeatureName.
1186+
StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1187+
if (!FeatureName.empty())
1188+
Ret.Features.push_back(FeatureName.str());
11491189
else
11501190
Ret.Features.push_back("+" + Feature.str());
11511191
}
11521192
}
1153-
FeatureBits.toLLVMFeatureList(Ret.Features);
11541193
return Ret;
11551194
}
11561195

clang/lib/Basic/Targets/AArch64.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
107107
unsigned multiVersionSortPriority(StringRef Name) const override;
108108
unsigned multiVersionFeatureCost() const override;
109109

110+
bool
111+
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
112+
StringRef CPU,
113+
const std::vector<std::string> &FeaturesVec) const override;
110114
bool useFP16ConversionIntrinsics() const override {
111115
return false;
112116
}

clang/test/CodeGen/aarch64-cpu-supports-target.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,5 @@ int test_versions() {
4848
return code();
4949
}
5050
// CHECK: attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
51-
// CHECK: attributes #1 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" }
52-
// CHECK: attributes #2 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+sve" }
51+
// CHECK: attributes #1 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+neon" }
52+
// CHECK: attributes #2 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }

clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +bf16 \
1+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme \
22
// RUN: -disable-O0-optnone -Werror -emit-llvm -o - %s \
33
// RUN: | opt -S -passes=mem2reg \
44
// RUN: | opt -S -passes=inline \

0 commit comments

Comments
 (0)