aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/TargetParser/TargetParserTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/TargetParser/TargetParserTest.cpp')
-rw-r--r--llvm/unittests/TargetParser/TargetParserTest.cpp341
1 files changed, 338 insertions, 3 deletions
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 63b43bc..f41b856 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -8,9 +8,10 @@
#include "llvm/TargetParser/TargetParser.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TargetParser/AArch64TargetParser.h"
#include "llvm/TargetParser/ARMTargetParser.h"
@@ -24,6 +25,9 @@
using namespace llvm;
+using ::testing::Contains;
+using ::testing::StrEq;
+
namespace {
const char *ARMArch[] = {
"armv4", "armv4t", "armv5", "armv5t", "armv5e",
@@ -1659,8 +1663,8 @@ TEST(TargetParserTest, testAArch64CPUArchList) {
bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
unsigned ArchAttr) {
- const std::optional<AArch64::ArchInfo> AI = AArch64::parseArch(Arch);
- return AI.has_value();
+ const AArch64::ArchInfo *AI = AArch64::parseArch(Arch);
+ return AI != nullptr;
}
TEST(TargetParserTest, testAArch64Arch) {
@@ -2099,4 +2103,335 @@ TEST(TargetParserTest, AArch64PrintSupportedExtensions) {
EXPECT_EQ(std::string::npos, captured.find("ssbs2"));
}
+struct AArch64ExtensionDependenciesBaseArchTestParams {
+ const llvm::AArch64::ArchInfo &Arch;
+ std::vector<StringRef> Modifiers;
+ std::vector<StringRef> ExpectedPos;
+ std::vector<StringRef> ExpectedNeg;
+};
+
+class AArch64ExtensionDependenciesBaseArchTestFixture
+ : public ::testing::TestWithParam<
+ AArch64ExtensionDependenciesBaseArchTestParams> {};
+
+struct AArch64ExtensionDependenciesBaseCPUTestParams {
+ StringRef CPUName;
+ std::vector<StringRef> Modifiers;
+ std::vector<StringRef> ExpectedPos;
+ std::vector<StringRef> ExpectedNeg;
+};
+
+class AArch64ExtensionDependenciesBaseCPUTestFixture
+ : public ::testing::TestWithParam<
+ AArch64ExtensionDependenciesBaseCPUTestParams> {};
+
+TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture,
+ AArch64ExtensionDependenciesBaseArch) {
+ auto Params = GetParam();
+
+ llvm::AArch64::ExtensionSet Extensions;
+ Extensions.addArchDefaults(Params.Arch);
+ for (auto M : Params.Modifiers) {
+ bool success = Extensions.parseModifier(M);
+ EXPECT_TRUE(success);
+ }
+ std::vector<StringRef> Features;
+ Extensions.toLLVMFeatureList(Features);
+
+ for (auto E : Params.ExpectedPos) {
+ std::string PosString = "+";
+ PosString += E;
+ std::string NegString = "-";
+ NegString += E;
+ ASSERT_THAT(Features, Contains(StrEq(PosString)));
+ ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));
+ }
+
+ for (auto E : Params.ExpectedNeg) {
+ std::string PosString = "+";
+ PosString += E;
+ ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
+ // Features default to off, so the negative string is not expected in many
+ // cases.
+ }
+}
+
+TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture,
+ AArch64ExtensionDependenciesBaseCPU) {
+ auto Params = GetParam();
+
+ llvm::AArch64::ExtensionSet Extensions;
+ const std::optional<llvm::AArch64::CpuInfo> CPU =
+ llvm::AArch64::parseCpu(Params.CPUName);
+ EXPECT_TRUE(CPU);
+ Extensions.addCPUDefaults(*CPU);
+ for (auto M : Params.Modifiers) {
+ bool success = Extensions.parseModifier(M);
+ EXPECT_TRUE(success);
+ }
+ std::vector<StringRef> Features;
+ Extensions.toLLVMFeatureList(Features);
+
+ for (auto E : Params.ExpectedPos) {
+ std::string PosString = "+";
+ PosString += E;
+ std::string NegString = "-";
+ NegString += E;
+ ASSERT_THAT(Features, Contains(StrEq(PosString)));
+ ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));
+ }
+
+ for (auto E : Params.ExpectedNeg) {
+ std::string PosString = "+";
+ PosString += E;
+ ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
+ // Features default to off, so the negative string is not expected in many
+ // cases.
+ }
+}
+
+AArch64ExtensionDependenciesBaseArchTestParams
+ AArch64ExtensionDependenciesArchData[] = {
+ // Base architecture features
+ {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}},
+ {AArch64::ARMV8_1A,
+ {},
+ {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},
+ {}},
+ {AArch64::ARMV9_5A, {}, {"v9.5a", "sve", "sve2", "mops", "cpa"}, {}},
+
+ // Positive modifiers
+ {AArch64::ARMV8A, {"fp16"}, {"fullfp16"}, {}},
+ {AArch64::ARMV8A, {"dotprod"}, {"dotprod"}, {}},
+
+ // Negative modifiers
+ {AArch64::ARMV8A, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}},
+
+ // Mixed modifiers
+ {AArch64::ARMV8A,
+ {"fp16", "nofp16"},
+ {"v8a", "fp-armv8", "neon"},
+ {"fullfp16"}},
+ {AArch64::ARMV8A,
+ {"fp16", "nofp"},
+ {"v8a"},
+ {"fp-armv8", "neon", "fullfp16"}},
+
+ // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp
+ {AArch64::ARMV8A,
+ {"nofp", "sve2-bitperm"},
+ {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"},
+ {}},
+ {AArch64::ARMV8A,
+ {"sve2-bitperm", "nofp16"},
+ {"fp-armv8"},
+ {"full-fp16", "sve", "sve2", "sve2-bitperm"}},
+
+ // Meaning of +crypto varies with base architecture.
+ {AArch64::ARMV8A, {"crypto"}, {"aes", "sha2"}, {}},
+ {AArch64::ARMV8_4A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
+ {AArch64::ARMV9A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
+
+ // -crypto always disables all crypto features, even if it wouldn't
+ // enable them.
+ {AArch64::ARMV8A,
+ {"aes", "sha2", "sha3", "sm4", "nocrypto"},
+ {},
+ {"aes", "sha2", "sha3", "sm4"}},
+ {AArch64::ARMV8_4A,
+ {"aes", "sha2", "sha3", "sm4", "nocrypto"},
+ {},
+ {"aes", "sha2", "sha3", "sm4"}},
+
+ // +sve implies +f32mm if the base architecture is v8.6A+ or v9.1A+, but
+ // not earlier architectures.
+ {AArch64::ARMV8_5A, {"sve"}, {"sve"}, {"f32mm"}},
+ {AArch64::ARMV9A, {"sve"}, {"sve"}, {"f32mm"}},
+ {AArch64::ARMV8_6A, {"sve"}, {"sve", "f32mm"}, {}},
+ {AArch64::ARMV9_1A, {"sve"}, {"sve", "f32mm"}, {}},
+
+ // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
+ {AArch64::ARMV8_3A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
+ {AArch64::ARMV9A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
+ {AArch64::ARMV8_4A, {"fp16"}, {"fullfp16", "fp16fml"}, {}},
+
+ // fp -> fp16
+ {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},
+ {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},
+
+ // fp -> simd
+ {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},
+ {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},
+
+ // fp -> jscvt
+ {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},
+ {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},
+
+ // simd -> {aes, sha2, sha3, sm4}
+ {AArch64::ARMV8A, {"nosimd", "aes"}, {"neon", "aes"}, {}},
+ {AArch64::ARMV8A, {"aes", "nosimd"}, {}, {"neon", "aes"}},
+ {AArch64::ARMV8A, {"nosimd", "sha2"}, {"neon", "sha2"}, {}},
+ {AArch64::ARMV8A, {"sha2", "nosimd"}, {}, {"neon", "sha2"}},
+ {AArch64::ARMV8A, {"nosimd", "sha3"}, {"neon", "sha3"}, {}},
+ {AArch64::ARMV8A, {"sha3", "nosimd"}, {}, {"neon", "sha3"}},
+ {AArch64::ARMV8A, {"nosimd", "sm4"}, {"neon", "sm4"}, {}},
+ {AArch64::ARMV8A, {"sm4", "nosimd"}, {}, {"neon", "sm4"}},
+
+ // simd -> {rdm, dotprod, fcma}
+ {AArch64::ARMV8A, {"nosimd", "rdm"}, {"neon", "rdm"}, {}},
+ {AArch64::ARMV8A, {"rdm", "nosimd"}, {}, {"neon", "rdm"}},
+ {AArch64::ARMV8A, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}},
+ {AArch64::ARMV8A, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}},
+ {AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}},
+ {AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}},
+
+ // fp16 -> {fp16fml, sve}
+ {AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}},
+ {AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}},
+ {AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}},
+ {AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}},
+
+ // bf16 -> {sme, b16b16}
+ {AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}},
+ {AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}},
+ {AArch64::ARMV8A, {"nobf16", "b16b16"}, {"bf16", "b16b16"}, {}},
+ {AArch64::ARMV8A, {"b16b16", "nobf16"}, {}, {"bf16", "b16b16"}},
+
+ // sve -> {sve2, f32mm, f64mm}
+ {AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}},
+ {AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}},
+ {AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}},
+ {AArch64::ARMV8A, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}},
+ {AArch64::ARMV8A, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}},
+ {AArch64::ARMV8A, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}},
+
+ // sve2 -> {sve2p1, sve2-bitperm, sve2-aes, sve2-sha3, sve2-sm4}
+ {AArch64::ARMV8A, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}},
+ {AArch64::ARMV8A, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}},
+ {AArch64::ARMV8A,
+ {"nosve2", "sve2-bitperm"},
+ {"sve2", "sve2-bitperm"},
+ {}},
+ {AArch64::ARMV8A,
+ {"sve2-bitperm", "nosve2"},
+ {},
+ {"sve2", "sve2-bitperm"}},
+ {AArch64::ARMV8A, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}},
+ {AArch64::ARMV8A, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}},
+ {AArch64::ARMV8A, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}},
+ {AArch64::ARMV8A, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}},
+ {AArch64::ARMV8A, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}},
+ {AArch64::ARMV8A, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}},
+
+ // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64}
+ {AArch64::ARMV8A, {"nosme", "sme2"}, {"sme", "sme2"}, {}},
+ {AArch64::ARMV8A, {"sme2", "nosme"}, {}, {"sme", "sme2"}},
+ {AArch64::ARMV8A, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}},
+ {AArch64::ARMV8A, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}},
+ {AArch64::ARMV8A, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}},
+ {AArch64::ARMV8A, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}},
+ {AArch64::ARMV8A, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}},
+ {AArch64::ARMV8A, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}},
+ {AArch64::ARMV8A, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}},
+ {AArch64::ARMV8A, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}},
+
+ // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16,
+ // sme-f8f32}
+ {AArch64::ARMV8A, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}},
+ {AArch64::ARMV8A, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}},
+ {AArch64::ARMV8A,
+ {"nosme2", "ssve-fp8fma"},
+ {"sme2", "ssve-fp8fma"},
+ {}},
+ {AArch64::ARMV8A,
+ {"ssve-fp8fma", "nosme2"},
+ {},
+ {"sme2", "ssve-fp8fma"}},
+ {AArch64::ARMV8A,
+ {"nosme2", "ssve-fp8dot2"},
+ {"sme2", "ssve-fp8dot2"},
+ {}},
+ {AArch64::ARMV8A,
+ {"ssve-fp8dot2", "nosme2"},
+ {},
+ {"sme2", "ssve-fp8dot2"}},
+ {AArch64::ARMV8A,
+ {"nosme2", "ssve-fp8dot4"},
+ {"sme2", "ssve-fp8dot4"},
+ {}},
+ {AArch64::ARMV8A,
+ {"ssve-fp8dot4", "nosme2"},
+ {},
+ {"sme2", "ssve-fp8dot4"}},
+ {AArch64::ARMV8A, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}},
+ {AArch64::ARMV8A, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}},
+ {AArch64::ARMV8A, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}},
+ {AArch64::ARMV8A, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}},
+
+ // fp8 -> {sme-f8f16, sme-f8f32}
+ {AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},
+ {AArch64::ARMV8A, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}},
+ {AArch64::ARMV8A, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}},
+ {AArch64::ARMV8A, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}},
+
+ // lse -> lse128
+ {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
+ {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
+
+ // predres -> predres2
+ {AArch64::ARMV8A,
+ {"nopredres", "predres2"},
+ {"predres", "specres2"},
+ {}},
+ {AArch64::ARMV8A,
+ {"predres2", "nopredres"},
+ {},
+ {"predres", "specres2"}},
+
+ // ras -> ras2
+ {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},
+ {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},
+
+ // rcpc -> rcpc3
+ {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},
+ {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ AArch64ExtensionDependenciesBaseArch,
+ AArch64ExtensionDependenciesBaseArchTestFixture,
+ ::testing::ValuesIn(AArch64ExtensionDependenciesArchData));
+
+AArch64ExtensionDependenciesBaseCPUTestParams
+ AArch64ExtensionDependenciesCPUData[] = {
+ // Base CPU features
+ {"cortex-a57",
+ {},
+ {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},
+ {}},
+ {"cortex-r82",
+ {},
+ {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",
+ "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},
+ {}},
+ {"cortex-a520",
+ {},
+ {"v9.2a", "bf16", "crc", "dotprod", "f32mm", "flagm",
+ "fp-armv8", "fullfp16", "fp16fml", "i8mm", "lse", "mte",
+ "pauth", "perfmon", "predres", "ras", "rcpc", "rdm",
+ "sb", "neon", "ssbs", "sve", "sve2-bitperm", "sve2"},
+ {}},
+
+ // Negative modifiers
+ {"cortex-r82",
+ {"nofp"},
+ {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"},
+ {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}},
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ AArch64ExtensionDependenciesBaseCPU,
+ AArch64ExtensionDependenciesBaseCPUTestFixture,
+ ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData));
+
} // namespace