diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- 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::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 @@ 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 @@ 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 @@ 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 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -123,8 +123,8 @@ 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 @@ 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 @@ 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 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -91,7 +91,6 @@ // 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 @@ {"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 @@ // 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 @@ 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 @@ // 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. @@ -487,8 +484,6 @@ {"ampere1", ARMV8_6A, (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS)}, - // Invalid CPU - {"invalid", INVALID, (AArch64::AEK_INVALID)}, }; // An alias for a CPU. @@ -508,13 +503,13 @@ // 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 --- 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 @@ 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 @@ // 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 @@ if (!ExtensionString.empty()) ExtensionString.split(RequestedExtensions, '+'); - ExpandCryptoAEK(ArchInfo, RequestedExtensions); + ExpandCryptoAEK(*ArchInfo, RequestedExtensions); FeatureBitset Features = STI.getFeatureBits(); for (auto Name : RequestedExtensions) { @@ -6987,19 +6988,17 @@ 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 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -31,8 +31,11 @@ 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 @@ 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 @@ 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 @@ 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 @@ } // 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 @@ 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 --- 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 @@ 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 @@ 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, @@ -1410,14 +1408,14 @@ // 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) { @@ -1453,81 +1451,92 @@ 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) { @@ -1559,9 +1568,7 @@ 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()); @@ -1633,7 +1640,6 @@ } 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"); @@ -1653,16 +1659,11 @@ } TEST(TargetParserTest, AArch64ArchPartialOrder) { - EXPECT_FALSE(AArch64::INVALID.implies(AArch64::INVALID)); - for (const auto *A : AArch64::ArchInfos) { EXPECT_EQ(*A, *A); if (!(*A == *A)) { EXPECT_NE(*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) {