From 9ea00fc74c3c0032ff2d9a6774e13449a30e4549 Mon Sep 17 00:00:00 2001 From: Lucas Prates Date: Mon, 23 Jan 2023 11:12:38 +0000 Subject: [PATCH] [NFC][AArch64] Use optional returns in target parser instead of 'invalid' objects This updates the parsing methods in AArch64's Target Parser to make use of optional returns instead of "invalid" enum values, making the API's behaviour clearer. Reviewed By: lenary, tmatheson Differential Revision: https://reviews.llvm.org/D142539 --- clang/lib/Basic/Targets/AArch64.cpp | 25 +-- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 17 +- .../llvm/TargetParser/AArch64TargetParser.h | 29 ++-- .../Target/AArch64/AsmParser/AArch64AsmParser.cpp | 19 +-- llvm/lib/TargetParser/AArch64TargetParser.cpp | 41 +++-- llvm/unittests/TargetParser/TargetParserTest.cpp | 183 +++++++++++---------- 6 files changed, 156 insertions(+), 158 deletions(-) diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index dfed95f..5971489 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/AArch64TargetParser.h" #include "llvm/Support/ARMTargetParserCommon.h" +#include "llvm/TargetParser/AArch64TargetParser.h" #include using namespace clang; @@ -223,8 +224,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, } bool AArch64TargetInfo::isValidCPUName(StringRef Name) const { - return Name == "generic" || - llvm::AArch64::parseCpu(Name).Arch != llvm::AArch64::INVALID; + return Name == "generic" || llvm::AArch64::parseCpu(Name); } bool AArch64TargetInfo::setCPU(const std::string &Name) { @@ -681,19 +681,19 @@ void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap &Features, Features[Name] = Enabled; // If the feature is an architecture feature (like v8.2a), add all previous // architecture versions and any dependant target features. - const llvm::AArch64::ArchInfo &ArchInfo = + const std::optional ArchInfo = llvm::AArch64::ArchInfo::findBySubArch(Name); - if (ArchInfo == llvm::AArch64::INVALID) + if (!ArchInfo) return; // Not an architecure, nothing more to do. for (const auto *OtherArch : llvm::AArch64::ArchInfos) - if (ArchInfo.implies(*OtherArch)) + if (ArchInfo->implies(*OtherArch)) Features[OtherArch->getSubArch()] = Enabled; // Set any features implied by the architecture uint64_t Extensions = - llvm::AArch64::getDefaultExtensions("generic", ArchInfo); + llvm::AArch64::getDefaultExtensions("generic", *ArchInfo); std::vector CPUFeats; if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) { for (auto F : CPUFeats) { @@ -949,9 +949,9 @@ bool AArch64TargetInfo::initFeatureMap( const std::vector &FeaturesVec) const { std::vector UpdatedFeaturesVec; // Parse the CPU and add any implied features. - const llvm::AArch64::ArchInfo &Arch = llvm::AArch64::parseCpu(CPU).Arch; - if (Arch != llvm::AArch64::INVALID) { - uint64_t Exts = llvm::AArch64::getDefaultExtensions(CPU, Arch); + std::optional CpuInfo = llvm::AArch64::parseCpu(CPU); + if (CpuInfo) { + uint64_t Exts = llvm::AArch64::getDefaultExtensions(CPU, CpuInfo->Arch); std::vector CPUFeats; llvm::AArch64::getExtensionFeatures(Exts, CPUFeats); for (auto F : CPUFeats) { @@ -1033,13 +1033,14 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { FoundArch = true; std::pair Split = Feature.split("=").second.trim().split("+"); - const llvm::AArch64::ArchInfo &AI = llvm::AArch64::parseArch(Split.first); + const std::optional AI = + llvm::AArch64::parseArch(Split.first); // Parse the architecture version, adding the required features to // Ret.Features. - if (AI == llvm::AArch64::INVALID) + if (!AI) continue; - Ret.Features.push_back(AI.ArchFeature.str()); + Ret.Features.push_back(AI->ArchFeature.str()); // Add any extra features, after the + SplitAndAddFeatures(Split.second, Ret.Features); } else if (Feature.startswith("cpu=")) { diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 2c559cc..81b0245 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -123,8 +123,8 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, std::vector &Features) { std::pair Split = Mcpu.split("+"); + CPU = Split.first; const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A; - CPU = llvm::AArch64::resolveCPUAlias(Split.first); if (CPU == "native") CPU = llvm::sys::getHostCPUName(); @@ -132,9 +132,12 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, if (CPU == "generic") { Features.push_back("+neon"); } else { - ArchInfo = &llvm::AArch64::parseCpu(CPU).Arch; - if (*ArchInfo == llvm::AArch64::INVALID) + const std::optional CpuInfo = + llvm::AArch64::parseCpu(CPU); + if (!CpuInfo) return false; + ArchInfo = &CpuInfo->Arch; + Features.push_back(ArchInfo->ArchFeature); uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, *ArchInfo); @@ -156,11 +159,11 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, std::string MarchLowerCase = March.lower(); std::pair Split = StringRef(MarchLowerCase).split("+"); - const llvm::AArch64::ArchInfo *ArchInfo = - &llvm::AArch64::parseArch(Split.first); + std::optional ArchInfo = + llvm::AArch64::parseArch(Split.first); if (Split.first == "native") - ArchInfo = &llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str()); - if (*ArchInfo == llvm::AArch64::INVALID) + ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str()); + if (!ArchInfo) return false; Features.push_back(ArchInfo->ArchFeature); diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index 16bf393..ea06d7d 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -91,7 +91,6 @@ enum CPUFeatures { // feature name (though the canonical reference for those is AArch64.td) // clang-format off enum ArchExtKind : uint64_t { - AEK_INVALID = 0, AEK_NONE = 1, AEK_CRC = 1 << 1, // FEAT_CRC32 AEK_CRYPTO = 1 << 2, @@ -252,7 +251,6 @@ inline constexpr ExtensionInfo Extensions[] = { {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550}, // Special cases {"none", AArch64::AEK_NONE, {}, {}, FEAT_MAX, "", ExtensionInfo::MaxFMVPriority}, - {"invalid", AArch64::AEK_INVALID, {}, {}, FEAT_MAX, "", 0}, }; // clang-format on @@ -280,12 +278,12 @@ struct ArchInfo { // v v v v v // v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a; // - // v8r and INVALID have no relation to anything. This is used to - // determine which features to enable for a given architecture. See + // v8r has no relation to anything. This is used to determine which + // features to enable for a given architecture. See // AArch64TargetInfo::setFeatureEnabled. bool implies(const ArchInfo &Other) const { if (this->Profile != Other.Profile) - return false; // ARMV8R and INVALID + return false; // ARMV8R if (this->Version.getMajor() == Other.Version.getMajor()) { return this->Version > Other.Version; } @@ -300,11 +298,10 @@ struct ArchInfo { StringRef getSubArch() const { return ArchFeature.substr(1); } // Search for ArchInfo by SubArch name - static const ArchInfo &findBySubArch(StringRef SubArch); + static std::optional findBySubArch(StringRef SubArch); }; // clang-format off -inline constexpr ArchInfo INVALID = { VersionTuple{0, 0}, AProfile, "invalid", "+", (AArch64::AEK_NONE)}; inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (AArch64::AEK_FP | AArch64::AEK_SIMD), }; inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | AArch64::AEK_CRC | AArch64::AEK_LSE | AArch64::AEK_RDM)}; inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | AArch64::AEK_RAS)}; @@ -325,10 +322,10 @@ inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r", // clang-format on // The set of all architectures -static constexpr std::array ArchInfos = { - &INVALID, &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, - &ARMV8_5A, &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, - &ARMV9_1A, &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R, +static constexpr std::array ArchInfos = { + &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, &ARMV8_5A, + &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, &ARMV9_1A, + &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R, }; // Details of a specific CPU. @@ -495,8 +492,6 @@ inline constexpr CpuInfo CpuInfos[] = { (AArch64::AEK_FP16 | AArch64::AEK_RAND | AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_MTE | AArch64::AEK_SB | AArch64::AEK_SSBS)}, - // Invalid CPU - {"invalid", INVALID, (AArch64::AEK_INVALID)}, }; // An alias for a CPU. @@ -516,13 +511,13 @@ StringRef resolveCPUAlias(StringRef CPU); // Information by Name uint64_t getDefaultExtensions(StringRef CPU, const ArchInfo &AI); void getFeatureOption(StringRef Name, std::string &Feature); -const ArchInfo &getArchForCpu(StringRef CPU); +std::optional getArchForCpu(StringRef CPU); // Parser -const ArchInfo &parseArch(StringRef Arch); -ArchExtKind parseArchExt(StringRef ArchExt); +std::optional parseArch(StringRef Arch); +std::optional parseArchExtension(StringRef Extension); // Given the name of a CPU or alias, return the correponding CpuInfo. -const CpuInfo &parseCpu(StringRef Name); +std::optional parseCpu(StringRef Name); // Used by target parser tests void fillValidCPUArchList(SmallVectorImpl &Values); diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 993ce48..840f792 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -51,6 +51,7 @@ #include "llvm/Support/AArch64TargetParser.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/AArch64TargetParser.h" #include #include #include @@ -6880,8 +6881,8 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { std::tie(Arch, ExtensionString) = getParser().parseStringToEndOfStatement().trim().split('+'); - const AArch64::ArchInfo &ArchInfo = AArch64::parseArch(Arch); - if (ArchInfo == AArch64::INVALID) + std::optional ArchInfo = AArch64::parseArch(Arch); + if (!ArchInfo) return Error(ArchLoc, "unknown arch name"); if (parseToken(AsmToken::EndOfStatement)) @@ -6889,9 +6890,9 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { // Get the architecture and extension features. std::vector AArch64Features; - AArch64Features.push_back(ArchInfo.ArchFeature); + AArch64Features.push_back(ArchInfo->ArchFeature); AArch64::getExtensionFeatures( - AArch64::getDefaultExtensions("generic", ArchInfo), AArch64Features); + AArch64::getDefaultExtensions("generic", *ArchInfo), AArch64Features); MCSubtargetInfo &STI = copySTI(); std::vector ArchFeatures(AArch64Features.begin(), AArch64Features.end()); @@ -6902,7 +6903,7 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { if (!ExtensionString.empty()) ExtensionString.split(RequestedExtensions, '+'); - ExpandCryptoAEK(ArchInfo, RequestedExtensions); + ExpandCryptoAEK(*ArchInfo, RequestedExtensions); FeatureBitset Features = STI.getFeatureBits(); for (auto Name : RequestedExtensions) { @@ -6987,19 +6988,17 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { if (!ExtensionString.empty()) ExtensionString.split(RequestedExtensions, '+'); - // FIXME This is using tablegen data, but should be moved to ARMTargetParser - // once that is tablegen'ed - if (!getSTI().isCPUStringValid(CPU)) { + const std::optional CpuArch = llvm::AArch64::getArchForCpu(CPU); + if (!CpuArch) { Error(CurLoc, "unknown CPU name"); return false; } + ExpandCryptoAEK(*CpuArch, RequestedExtensions); MCSubtargetInfo &STI = copySTI(); STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, ""); CurLoc = incrementLoc(CurLoc, CPU.size()); - ExpandCryptoAEK(llvm::AArch64::getArchForCpu(CPU), RequestedExtensions); - for (auto Name : RequestedExtensions) { // Advance source location past '+'. CurLoc = incrementLoc(CurLoc, 1); diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp index 41d5c25..7dd0c45 100644 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -31,8 +31,11 @@ uint64_t AArch64::getDefaultExtensions(StringRef CPU, return AI.DefaultExts; // Note: this now takes cpu aliases into account - const CpuInfo &Cpu = parseCpu(CPU); - return Cpu.Arch.DefaultExts | Cpu.DefaultExtensions; + std::optional Cpu = parseCpu(CPU); + if (!Cpu) + return AI.DefaultExts; + + return Cpu->Arch.DefaultExts | Cpu->DefaultExtensions; } void AArch64::getFeatureOption(StringRef Name, std::string &Feature) { @@ -45,20 +48,22 @@ void AArch64::getFeatureOption(StringRef Name, std::string &Feature) { Feature = Name.str(); } -const AArch64::ArchInfo &AArch64::getArchForCpu(StringRef CPU) { +std::optional AArch64::getArchForCpu(StringRef CPU) { if (CPU == "generic") return ARMV8A; // Note: this now takes cpu aliases into account - const CpuInfo &Cpu = parseCpu(CPU); - return Cpu.Arch; + std::optional Cpu = parseCpu(CPU); + if (!Cpu) + return {}; + return Cpu->Arch; } -const AArch64::ArchInfo &AArch64::ArchInfo::findBySubArch(StringRef SubArch) { +std::optional AArch64::ArchInfo::findBySubArch(StringRef SubArch) { for (const auto *A : AArch64::ArchInfos) if (A->getSubArch() == SubArch) return *A; - return AArch64::INVALID; + return {}; } uint64_t AArch64::getCpuSupportsMask(ArrayRef FeatureStrs) { @@ -75,9 +80,6 @@ uint64_t AArch64::getCpuSupportsMask(ArrayRef FeatureStrs) { bool AArch64::getExtensionFeatures(uint64_t InputExts, std::vector &Features) { - if (InputExts == AArch64::AEK_INVALID) - return false; - for (const auto &E : Extensions) /* INVALID and NONE have no feature name. */ if ((InputExts & E.ID) && !E.Feature.empty()) @@ -110,7 +112,6 @@ StringRef AArch64::getArchExtFeature(StringRef ArchExt) { void AArch64::fillValidCPUArchList(SmallVectorImpl &Values) { for (const auto &C : CpuInfos) - if (C.Arch != INVALID) Values.push_back(C.Name); for (const auto &Alias : CpuAliases) @@ -123,28 +124,28 @@ bool AArch64::isX18ReservedByDefault(const Triple &TT) { } // Allows partial match, ex. "v8a" matches "armv8a". -const AArch64::ArchInfo &AArch64::parseArch(StringRef Arch) { +std::optional AArch64::parseArch(StringRef Arch) { Arch = llvm::ARM::getCanonicalArchName(Arch); if (checkArchVersion(Arch) < 8) - return AArch64::INVALID; + return {}; StringRef Syn = llvm::ARM::getArchSynonym(Arch); for (const auto *A : ArchInfos) { if (A->Name.endswith(Syn)) return *A; } - return AArch64::INVALID; + return {}; } -AArch64::ArchExtKind AArch64::parseArchExt(StringRef ArchExt) { +std::optional AArch64::parseArchExtension(StringRef ArchExt) { for (const auto &A : Extensions) { if (ArchExt == A.Name) - return static_cast(A.ID); + return A; } - return AArch64::AEK_INVALID; + return {}; } -const AArch64::CpuInfo &AArch64::parseCpu(StringRef Name) { +std::optional AArch64::parseCpu(StringRef Name) { // Resolve aliases first. Name = resolveCPUAlias(Name); @@ -153,7 +154,5 @@ const AArch64::CpuInfo &AArch64::parseCpu(StringRef Name) { if (Name == C.Name) return C; - // "generic" returns invalid. - assert(Name != "invalid" && "Unexpected recursion."); - return parseCpu("invalid"); + return {}; } diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 2d96716..2970e01 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -17,6 +17,7 @@ #include "llvm/TargetParser/Triple.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include #include using namespace llvm; @@ -961,11 +962,12 @@ class AArch64CPUTestFixture TEST_P(AArch64CPUTestFixture, testAArch64CPU) { ARMCPUTestParams params = GetParam(); - const AArch64::ArchInfo &AI = AArch64::parseCpu(params.CPUName).Arch; - EXPECT_EQ(params.ExpectedArch, AI.Name); + const std::optional Cpu = AArch64::parseCpu(params.CPUName); + EXPECT_TRUE(Cpu); + EXPECT_EQ(params.ExpectedArch, Cpu->Arch.Name); uint64_t default_extensions = - AArch64::getDefaultExtensions(params.CPUName, AI); + AArch64::getDefaultExtensions(params.CPUName, Cpu->Arch); EXPECT_PRED_FORMAT2( AssertSameExtensionFlags(params.CPUName), params.ExpectedFlags, default_extensions); @@ -974,10 +976,6 @@ TEST_P(AArch64CPUTestFixture, testAArch64CPU) { INSTANTIATE_TEST_SUITE_P( AArch64CPUTests, AArch64CPUTestFixture, ::testing::Values( - ARMCPUTestParams("invalid", "invalid", "invalid", AArch64::AEK_NONE, - ""), - ARMCPUTestParams("generic", "invalid", "none", AArch64::AEK_NONE, ""), - ARMCPUTestParams("cortex-a34", "armv8-a", "crypto-neon-fp-armv8", AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, @@ -1425,14 +1423,14 @@ TEST(TargetParserTest, testAArch64CPUArchList) { // valid, and match the expected 'magic' count. EXPECT_EQ(List.size(), NumAArch64CPUArchs); for(StringRef CPU : List) { - EXPECT_NE(AArch64::parseCpu(CPU).Arch, AArch64::INVALID); + EXPECT_TRUE(AArch64::parseCpu(CPU)); } } bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch, unsigned ArchAttr) { - const AArch64::ArchInfo &AI = AArch64::parseArch(Arch); - return AI != AArch64::INVALID; + const std::optional AI = AArch64::parseArch(Arch); + return AI.has_value(); } TEST(TargetParserTest, testAArch64Arch) { @@ -1468,81 +1466,92 @@ TEST(TargetParserTest, testAArch64Arch) { ARMBuildAttrs::CPUArch::v8_A)); } -bool testAArch64Extension(StringRef CPUName, const AArch64::ArchInfo &AI, - StringRef ArchExt) { - return AArch64::getDefaultExtensions(CPUName, AI) & - AArch64::parseArchExt(ArchExt); +bool testAArch64Extension(StringRef CPUName, StringRef ArchExt) { + std::optional Extension = + AArch64::parseArchExtension(ArchExt); + if (!Extension) + return false; + std::optional CpuInfo = AArch64::parseCpu(CPUName); + return (CpuInfo->Arch.DefaultExts | CpuInfo->DefaultExtensions) & Extension->ID; +} + +bool testAArch64Extension(const AArch64::ArchInfo &AI, StringRef ArchExt) { + std::optional Extension = + AArch64::parseArchExtension(ArchExt); + if (!Extension) + return false; + return AI.DefaultExts & Extension->ID; } TEST(TargetParserTest, testAArch64Extension) { - EXPECT_FALSE(testAArch64Extension("cortex-a34", AArch64::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a35", AArch64::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a53", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "fp16")); - EXPECT_FALSE(testAArch64Extension("cortex-a55", AArch64::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "dotprod")); - EXPECT_FALSE(testAArch64Extension("cortex-a57", AArch64::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a72", AArch64::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a73", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "fp16")); - EXPECT_FALSE(testAArch64Extension("cortex-a75", AArch64::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("cyclone", AArch64::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("exynos-m3", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "rdm")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "rdm")); - EXPECT_TRUE(testAArch64Extension("falkor", AArch64::INVALID, "rdm")); - EXPECT_FALSE(testAArch64Extension("kryo", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "crc")); - EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "rdm")); - EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "rcpc")); - EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "profile")); - EXPECT_FALSE(testAArch64Extension("saphira", AArch64::INVALID, "fp16")); - EXPECT_FALSE(testAArch64Extension("thunderx2t99", AArch64::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("thunderx", AArch64::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("thunderxt81", AArch64::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("thunderxt83", AArch64::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("thunderxt88", AArch64::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "crypto")); - EXPECT_FALSE(testAArch64Extension("tsv110", AArch64::INVALID, "sha3")); - EXPECT_FALSE(testAArch64Extension("tsv110", AArch64::INVALID, "sm4")); - EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "profile")); - EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("a64fx", AArch64::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("a64fx", AArch64::INVALID, "sve")); - EXPECT_FALSE(testAArch64Extension("a64fx", AArch64::INVALID, "sve2")); - EXPECT_TRUE(testAArch64Extension("carmel", AArch64::INVALID, "crypto")); - EXPECT_TRUE(testAArch64Extension("carmel", AArch64::INVALID, "fp16")); - - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8A, "ras")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_1A, "ras")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "profile")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "fp16")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "fp16fml")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_3A, "fp16")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_3A, "fp16fml")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_4A, "fp16")); - EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_4A, "fp16fml")); + EXPECT_FALSE(testAArch64Extension("cortex-a34", "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a35", "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a53", "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a55", "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a55", "fp16")); + EXPECT_FALSE(testAArch64Extension("cortex-a55", "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-a55", "dotprod")); + EXPECT_FALSE(testAArch64Extension("cortex-a57", "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a72", "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a73", "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a75", "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a75", "fp16")); + EXPECT_FALSE(testAArch64Extension("cortex-a75", "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-a75", "dotprod")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", "dotprod")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", "lse")); + EXPECT_FALSE(testAArch64Extension("cyclone", "ras")); + EXPECT_FALSE(testAArch64Extension("exynos-m3", "ras")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", "dotprod")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", "fp16")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", "lse")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", "ras")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", "rdm")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", "dotprod")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", "fp16")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", "lse")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", "ras")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", "rdm")); + EXPECT_TRUE(testAArch64Extension("falkor", "rdm")); + EXPECT_FALSE(testAArch64Extension("kryo", "ras")); + EXPECT_TRUE(testAArch64Extension("saphira", "crc")); + EXPECT_TRUE(testAArch64Extension("saphira", "lse")); + EXPECT_TRUE(testAArch64Extension("saphira", "rdm")); + EXPECT_TRUE(testAArch64Extension("saphira", "ras")); + EXPECT_TRUE(testAArch64Extension("saphira", "rcpc")); + EXPECT_TRUE(testAArch64Extension("saphira", "profile")); + EXPECT_FALSE(testAArch64Extension("saphira", "fp16")); + EXPECT_FALSE(testAArch64Extension("thunderx2t99", "ras")); + EXPECT_FALSE(testAArch64Extension("thunderx", "lse")); + EXPECT_FALSE(testAArch64Extension("thunderxt81", "lse")); + EXPECT_FALSE(testAArch64Extension("thunderxt83", "lse")); + EXPECT_FALSE(testAArch64Extension("thunderxt88", "lse")); + EXPECT_TRUE(testAArch64Extension("tsv110", "crypto")); + EXPECT_FALSE(testAArch64Extension("tsv110", "sha3")); + EXPECT_FALSE(testAArch64Extension("tsv110", "sm4")); + EXPECT_TRUE(testAArch64Extension("tsv110", "ras")); + EXPECT_TRUE(testAArch64Extension("tsv110", "profile")); + EXPECT_TRUE(testAArch64Extension("tsv110", "fp16")); + EXPECT_TRUE(testAArch64Extension("tsv110", "fp16fml")); + EXPECT_TRUE(testAArch64Extension("tsv110", "dotprod")); + EXPECT_TRUE(testAArch64Extension("a64fx", "fp16")); + EXPECT_TRUE(testAArch64Extension("a64fx", "sve")); + EXPECT_FALSE(testAArch64Extension("a64fx", "sve2")); + EXPECT_TRUE(testAArch64Extension("carmel", "crypto")); + EXPECT_TRUE(testAArch64Extension("carmel", "fp16")); + + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8A, "ras")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_1A, "ras")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "profile")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16fml")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16fml")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16")); + EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16fml")); } TEST(TargetParserTest, AArch64ExtensionFeatures) { @@ -1574,9 +1583,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { for (auto Ext : Extensions) ExtVal |= Ext; - // INVALID and NONE have no feature names. - EXPECT_FALSE(AArch64::getExtensionFeatures(AArch64::AEK_INVALID, Features)); - EXPECT_TRUE(!Features.size()); + // NONE has no feature names. // We return True here because NONE is a valid choice. EXPECT_TRUE(AArch64::getExtensionFeatures(AArch64::AEK_NONE, Features)); EXPECT_TRUE(!Features.size()); @@ -1648,7 +1655,6 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { } TEST(TargetParserTest, AArch64ArchFeatures) { - EXPECT_EQ(AArch64::INVALID.ArchFeature, "+"); EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a"); EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a"); EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a"); @@ -1668,13 +1674,8 @@ TEST(TargetParserTest, AArch64ArchFeatures) { } TEST(TargetParserTest, AArch64ArchPartialOrder) { - EXPECT_FALSE(AArch64::INVALID.implies(AArch64::INVALID)); - for (const auto *A : AArch64::ArchInfos) { EXPECT_EQ(*A, *A); - // Comparison with invalid is always false - EXPECT_FALSE(A->implies(AArch64::INVALID)); - EXPECT_FALSE(AArch64::INVALID.implies(*A)); // v8r has no relation to other valid architectures if (*A != AArch64::ARMV8R) { -- 2.7.4