aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Support/TargetParserTest.cpp
diff options
context:
space:
mode:
authorTomas Matheson <tomas.matheson@arm.com>2022-11-18 11:20:05 +0000
committerTomas Matheson <tomas.matheson@arm.com>2022-12-01 12:50:23 +0000
commit450de8008bb0ccb5dfc9dd69b6f5b434158772bd (patch)
treea8737f3bddfcef15e203f57169b4d59140cb9da7 /llvm/unittests/Support/TargetParserTest.cpp
parentf57f086714bc7a1399acf05d5ca1d665237cd725 (diff)
downloadllvm-450de8008bb0ccb5dfc9dd69b6f5b434158772bd.zip
llvm-450de8008bb0ccb5dfc9dd69b6f5b434158772bd.tar.gz
llvm-450de8008bb0ccb5dfc9dd69b6f5b434158772bd.tar.bz2
[AArch64] Improve TargetParser API
The TargetParser depends heavily on a collection of macros and enums to tie together information about architectures, CPUs and extensions. Over time this has led to some pretty awkward API choices. For example, recently a custom operator-- has been added to the enum, which effectively turns iteration into a graph traversal and makes the ordering of the macro calls in the header significant. More generally there is a lot of string <-> enum conversion going on. I think this shows the extent to which the current data structures are constraining us, and the need for a rethink. Key changes: - Get rid of Arch enum, which is used to bind fields together. Instead of passing around ArchKind, use the named ArchInfo objects directly or via references. - The list of all known ArchInfo becomes an array of pointers. - ArchKind::operator-- is replaced with ArchInfo::implies(), which defines which architectures are predecessors to each other. This allows features from predecessor architectures to be added in a more intuitive way. - Free functions of the form f(ArchKind) are converted to ArchInfo::f(). Some functions become unnecessary and are deleted. - Version number and profile are added to the ArchInfo. This makes comparison of architectures easier and moves a couple of functions out of clang and into AArch64TargetParser. - clang::AArch64TargetInfo ArchInfo is initialised to Armv8a not INVALID. - AArch64::ArchProfile which is distinct from ARM::ArchProfile - Give things sensible names and add some comments. Differential Revision: https://reviews.llvm.org/D138792
Diffstat (limited to 'llvm/unittests/Support/TargetParserTest.cpp')
-rw-r--r--llvm/unittests/Support/TargetParserTest.cpp292
1 files changed, 131 insertions, 161 deletions
diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp
index 5bcb131..a99df08 100644
--- a/llvm/unittests/Support/TargetParserTest.cpp
+++ b/llvm/unittests/Support/TargetParserTest.cpp
@@ -952,11 +952,11 @@ class AArch64CPUTestFixture
TEST_P(AArch64CPUTestFixture, testAArch64CPU) {
ARMCPUTestParams params = GetParam();
- AArch64::ArchKind AK = AArch64::parseCPUArch(params.CPUName);
- EXPECT_EQ(params.ExpectedArch, AArch64::getArchName(AK));
+ const AArch64::ArchInfo &AI = AArch64::parseCpu(params.CPUName).Arch;
+ EXPECT_EQ(params.ExpectedArch, AI.Name);
uint64_t default_extensions =
- AArch64::getDefaultExtensions(params.CPUName, AK);
+ AArch64::getDefaultExtensions(params.CPUName, AI);
EXPECT_PRED_FORMAT2(AssertSameExtensionFlags<ARM::ISAKind::AARCH64>,
params.ExpectedFlags, default_extensions);
}
@@ -1402,14 +1402,14 @@ TEST(TargetParserTest, testAArch64CPUArchList) {
// valid, and match the expected 'magic' count.
EXPECT_EQ(List.size(), NumAArch64CPUArchs);
for(StringRef CPU : List) {
- EXPECT_NE(AArch64::parseCPUArch(CPU), AArch64::ArchKind::INVALID);
+ EXPECT_NE(AArch64::parseCpu(CPU).Arch, AArch64::INVALID);
}
}
bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
unsigned ArchAttr) {
- AArch64::ArchKind AK = AArch64::parseArch(Arch);
- return AK != AArch64::ArchKind::INVALID;
+ const AArch64::ArchInfo &AI = AArch64::parseArch(Arch);
+ return AI != AArch64::INVALID;
}
TEST(TargetParserTest, testAArch64Arch) {
@@ -1445,148 +1445,81 @@ TEST(TargetParserTest, testAArch64Arch) {
ARMBuildAttrs::CPUArch::v8_A));
}
-bool testAArch64Extension(StringRef CPUName, AArch64::ArchKind AK,
+bool testAArch64Extension(StringRef CPUName, const AArch64::ArchInfo &AI,
StringRef ArchExt) {
- return AArch64::getDefaultExtensions(CPUName, AK) &
+ return AArch64::getDefaultExtensions(CPUName, AI) &
AArch64::parseArchExt(ArchExt);
}
TEST(TargetParserTest, testAArch64Extension) {
- EXPECT_FALSE(testAArch64Extension("cortex-a34",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a35",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a53",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("cortex-a55",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("cortex-a55",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_FALSE(testAArch64Extension("cortex-a55",
- AArch64::ArchKind::INVALID, "fp16fml"));
- EXPECT_TRUE(testAArch64Extension("cortex-a55",
- AArch64::ArchKind::INVALID, "dotprod"));
- EXPECT_FALSE(testAArch64Extension("cortex-a57",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a72",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a73",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("cortex-a75",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("cortex-a75",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_FALSE(testAArch64Extension("cortex-a75",
- AArch64::ArchKind::INVALID, "fp16fml"));
- EXPECT_TRUE(testAArch64Extension("cortex-a75",
- AArch64::ArchKind::INVALID, "dotprod"));
- EXPECT_TRUE(testAArch64Extension("cortex-r82",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("cortex-r82",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_TRUE(testAArch64Extension("cortex-r82",
- AArch64::ArchKind::INVALID, "fp16fml"));
- EXPECT_TRUE(testAArch64Extension("cortex-r82",
- AArch64::ArchKind::INVALID, "dotprod"));
- EXPECT_TRUE(testAArch64Extension("cortex-r82",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_FALSE(testAArch64Extension("cyclone",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_FALSE(testAArch64Extension("exynos-m3",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("exynos-m4",
- AArch64::ArchKind::INVALID, "dotprod"));
- EXPECT_TRUE(testAArch64Extension("exynos-m4",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_TRUE(testAArch64Extension("exynos-m4",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_TRUE(testAArch64Extension("exynos-m4",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("exynos-m4",
- AArch64::ArchKind::INVALID, "rdm"));
- EXPECT_TRUE(testAArch64Extension("exynos-m5",
- AArch64::ArchKind::INVALID, "dotprod"));
- EXPECT_TRUE(testAArch64Extension("exynos-m5",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_TRUE(testAArch64Extension("exynos-m5",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_TRUE(testAArch64Extension("exynos-m5",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("exynos-m5",
- AArch64::ArchKind::INVALID, "rdm"));
- EXPECT_TRUE(testAArch64Extension("falkor",
- AArch64::ArchKind::INVALID, "rdm"));
- EXPECT_FALSE(testAArch64Extension("kryo",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("saphira",
- AArch64::ArchKind::INVALID, "crc"));
- EXPECT_TRUE(testAArch64Extension("saphira",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_TRUE(testAArch64Extension("saphira",
- AArch64::ArchKind::INVALID, "rdm"));
- EXPECT_TRUE(testAArch64Extension("saphira",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("saphira",
- AArch64::ArchKind::INVALID, "rcpc"));
- EXPECT_TRUE(testAArch64Extension("saphira",
- AArch64::ArchKind::INVALID, "profile"));
- EXPECT_FALSE(testAArch64Extension("saphira",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_FALSE(testAArch64Extension("thunderx2t99",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_FALSE(testAArch64Extension("thunderx",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_FALSE(testAArch64Extension("thunderxt81",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_FALSE(testAArch64Extension("thunderxt83",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_FALSE(testAArch64Extension("thunderxt88",
- AArch64::ArchKind::INVALID, "lse"));
- EXPECT_TRUE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "crypto"));
- EXPECT_FALSE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "sha3"));
- EXPECT_FALSE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "sm4"));
- EXPECT_TRUE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "ras"));
- EXPECT_TRUE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "profile"));
- EXPECT_TRUE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_TRUE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "fp16fml"));
- EXPECT_TRUE(testAArch64Extension("tsv110",
- AArch64::ArchKind::INVALID, "dotprod"));
- EXPECT_TRUE(testAArch64Extension("a64fx",
- AArch64::ArchKind::INVALID, "fp16"));
- EXPECT_TRUE(testAArch64Extension("a64fx",
- AArch64::ArchKind::INVALID, "sve"));
- EXPECT_FALSE(testAArch64Extension("a64fx",
- AArch64::ArchKind::INVALID, "sve2"));
- EXPECT_TRUE(
- testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "crypto"));
- EXPECT_TRUE(
- testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "fp16"));
-
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8A, "ras"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_1A, "ras"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_2A, "profile"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_2A, "fp16"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_2A, "fp16fml"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_3A, "fp16"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_3A, "fp16fml"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_4A, "fp16"));
- EXPECT_FALSE(testAArch64Extension(
- "generic", AArch64::ArchKind::ARMV8_4A, "fp16fml"));
+ 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"));
}
TEST(TargetParserTest, AArch64ExtensionFeatures) {
@@ -1708,25 +1641,62 @@ TEST(TargetParserTest, AArch64ArchFeatures) {
EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8R), "+v8r");
}
-TEST(TargetParserTest, AArch64ArchV9toV8Conversion) {
- for (auto AK : AArch64::ArchKinds) {
- if (AK == AArch64::ArchKind::INVALID)
- EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
- else if (AK < AArch64::ArchKind::ARMV9A)
- EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
- else if (AK >= AArch64::ArchKind::ARMV8R)
- EXPECT_EQ(AArch64::ArchKind::INVALID, AArch64::convertV9toV8(AK));
- else
- EXPECT_TRUE(AArch64::convertV9toV8(AK) < AArch64::ArchKind::ARMV9A);
+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) {
+ EXPECT_FALSE(A->implies(AArch64::ARMV8R));
+ EXPECT_FALSE(AArch64::ARMV8R.implies(*A));
+ }
}
- EXPECT_EQ(AArch64::ArchKind::ARMV8_5A,
- AArch64::convertV9toV8(AArch64::ArchKind::ARMV9A));
- EXPECT_EQ(AArch64::ArchKind::ARMV8_6A,
- AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_1A));
- EXPECT_EQ(AArch64::ArchKind::ARMV8_7A,
- AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_2A));
- EXPECT_EQ(AArch64::ArchKind::ARMV8_8A,
- AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_3A));
+
+ for (const auto *A : {
+ &AArch64::ARMV8_1A,
+ &AArch64::ARMV8_2A,
+ &AArch64::ARMV8_3A,
+ &AArch64::ARMV8_4A,
+ &AArch64::ARMV8_5A,
+ &AArch64::ARMV8_6A,
+ &AArch64::ARMV8_7A,
+ &AArch64::ARMV8_8A,
+ &AArch64::ARMV8_9A,
+ })
+ EXPECT_TRUE(A->implies(AArch64::ARMV8A));
+
+ for (const auto *A : {&AArch64::ARMV9_1A, &AArch64::ARMV9_2A,
+ &AArch64::ARMV9_3A, &AArch64::ARMV9_4A})
+ EXPECT_TRUE(A->implies(AArch64::ARMV9A));
+
+ EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A));
+ EXPECT_TRUE(AArch64::ARMV8_2A.implies(AArch64::ARMV8_1A));
+ EXPECT_TRUE(AArch64::ARMV8_3A.implies(AArch64::ARMV8_2A));
+ EXPECT_TRUE(AArch64::ARMV8_4A.implies(AArch64::ARMV8_3A));
+ EXPECT_TRUE(AArch64::ARMV8_5A.implies(AArch64::ARMV8_4A));
+ EXPECT_TRUE(AArch64::ARMV8_6A.implies(AArch64::ARMV8_5A));
+ EXPECT_TRUE(AArch64::ARMV8_7A.implies(AArch64::ARMV8_6A));
+ EXPECT_TRUE(AArch64::ARMV8_8A.implies(AArch64::ARMV8_7A));
+ EXPECT_TRUE(AArch64::ARMV8_9A.implies(AArch64::ARMV8_8A));
+
+ EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV9A));
+ EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV9_1A));
+ EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV9_2A));
+ EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A));
+
+ EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A));
+ EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A));
+ EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV8_7A));
+ EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV8_8A));
+ EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV8_9A));
}
TEST(TargetParserTest, AArch64ArchExtFeature) {