diff --git a/include/llvm/Support/AArch64TargetParser.def b/include/llvm/Support/AArch64TargetParser.def index 1394cf74a8c..0fd4117d93a 100644 --- a/include/llvm/Support/AArch64TargetParser.def +++ b/include/llvm/Support/AArch64TargetParser.def @@ -166,6 +166,8 @@ AARCH64_CPU_NAME("tsv110", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false, (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PROFILE)) +AARCH64_CPU_NAME("a64fx", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false, + (AArch64::AEK_FP16 | AArch64::AEK_SVE)) // Invalid CPU AARCH64_CPU_NAME("invalid", INVALID, FK_INVALID, true, AArch64::AEK_INVALID) #undef AARCH64_CPU_NAME diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index 9b9d60ef52f..2fb0c254165 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -219,6 +219,16 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) { } } + if (Implementer == "0x46") { // Fujitsu Ltd. + for (unsigned I = 0, E = Lines.size(); I != E; ++I) { + if (Lines[I].startswith("CPU part")) { + return StringSwitch(Lines[I].substr(8).ltrim("\t :")) + .Case("0x001", "a64fx") + .Default("generic"); + } + } + } + if (Implementer == "0x48") // HiSilicon Technologies, Inc. // Look for the CPU part line. for (unsigned I = 0, E = Lines.size(); I != E; ++I) diff --git a/lib/Target/AArch64/AArch64.td b/lib/Target/AArch64/AArch64.td index df35bb4b528..a6af2a1538e 100644 --- a/lib/Target/AArch64/AArch64.td +++ b/lib/Target/AArch64/AArch64.td @@ -563,6 +563,19 @@ def ProcA76 : SubtargetFeature<"a76", "ARMProcFamily", "CortexA76", FeatureSSBS ]>; +def ProcA64FX : SubtargetFeature<"a64fx", "ARMProcFamily", "A64FX", + "Fujitsu A64FX processors", [ + HasV8_2aOps, + FeatureFPARMv8, + FeatureNEON, + FeatureSHA2, + FeaturePerfMon, + FeatureFullFP16, + FeatureSVE, + FeaturePostRAScheduler, + FeatureComplxNum + ]>; + // Note that cyclone does not fuse AES instructions, but newer apple chips do // perform the fusion and cyclone is used by default when targetting apple OSes. def ProcAppleA7 : SubtargetFeature<"apple-a7", "ARMProcFamily", "AppleA7", @@ -901,6 +914,10 @@ def : ProcessorModel<"apple-s5", CycloneModel, [ProcAppleA12]>; // Alias for the latest Apple processor model supported by LLVM. def : ProcessorModel<"apple-latest", CycloneModel, [ProcAppleA13]>; +// Fujitsu A64FX +// FIXME: Scheduling model is not implemented yet. +def : ProcessorModel<"a64fx", NoSchedModel, [ProcA64FX]>; + //===----------------------------------------------------------------------===// // Assembly parser //===----------------------------------------------------------------------===// diff --git a/lib/Target/AArch64/AArch64Subtarget.cpp b/lib/Target/AArch64/AArch64Subtarget.cpp index 3636d8d2b62..dc744f55dfb 100644 --- a/lib/Target/AArch64/AArch64Subtarget.cpp +++ b/lib/Target/AArch64/AArch64Subtarget.cpp @@ -88,6 +88,11 @@ void AArch64Subtarget::initializeProperties() { case CortexA76: PrefFunctionLogAlignment = 4; break; + case A64FX: + CacheLineSize = 256; + PrefFunctionLogAlignment = 5; + PrefLoopLogAlignment = 5; + break; case AppleA7: case AppleA10: case AppleA11: diff --git a/lib/Target/AArch64/AArch64Subtarget.h b/lib/Target/AArch64/AArch64Subtarget.h index 79c2c161d3c..dca2b8b11ba 100644 --- a/lib/Target/AArch64/AArch64Subtarget.h +++ b/lib/Target/AArch64/AArch64Subtarget.h @@ -38,6 +38,7 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo { public: enum ARMProcFamilyEnum : uint8_t { Others, + A64FX, AppleA7, AppleA10, AppleA11, diff --git a/test/CodeGen/AArch64/cpus.ll b/test/CodeGen/AArch64/cpus.ll index a8a82b776dc..2d840037c4a 100644 --- a/test/CodeGen/AArch64/cpus.ll +++ b/test/CodeGen/AArch64/cpus.ll @@ -25,6 +25,7 @@ ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=thunderx2t99 2>&1 | FileCheck %s ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=tsv110 2>&1 | FileCheck %s ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=apple-latest 2>&1 | FileCheck %s +; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=a64fx 2>&1 | FileCheck %s ; RUN: llc < %s -mtriple=arm64-unknown-unknown -mcpu=invalidcpu 2>&1 | FileCheck %s --check-prefix=INVALID ; CHECK-NOT: {{.*}} is not a recognized processor for this target diff --git a/test/CodeGen/AArch64/preferred-function-alignment.ll b/test/CodeGen/AArch64/preferred-function-alignment.ll index 012fe4fb181..f3e69351502 100644 --- a/test/CodeGen/AArch64/preferred-function-alignment.ll +++ b/test/CodeGen/AArch64/preferred-function-alignment.ll @@ -8,6 +8,7 @@ ; RUN: llc -mtriple=aarch64-unknown-linux -mcpu=cortex-a73 < %s | FileCheck --check-prefixes=ALIGN4,CHECK %s ; RUN: llc -mtriple=aarch64-unknown-linux -mcpu=cortex-a75 < %s | FileCheck --check-prefixes=ALIGN4,CHECK %s ; RUN: llc -mtriple=aarch64-unknown-linux -mcpu=cortex-a76 < %s | FileCheck --check-prefixes=ALIGN4,CHECK %s +; RUN: llc -mtriple=aarch64-unknown-linux -mcpu=a64fx < %s | FileCheck --check-prefixes=ALIGN5,CHECK %s ; RUN: llc -mtriple=aarch64-unknown-linux -mcpu=cyclone < %s | FileCheck --check-prefixes=ALIGN2,CHECK %s ; RUN: llc -mtriple=aarch64-unknown-linux -mcpu=falkor < %s | FileCheck --check-prefixes=ALIGN2,CHECK %s ; RUN: llc -mtriple=aarch64-unknown-linux -mcpu=kryo < %s | FileCheck --check-prefixes=ALIGN2,CHECK %s diff --git a/unittests/Support/Host.cpp b/unittests/Support/Host.cpp index e5c28167f4d..36ca70a707b 100644 --- a/unittests/Support/Host.cpp +++ b/unittests/Support/Host.cpp @@ -249,6 +249,19 @@ CPU part : 0x0a1 EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x48\n" "CPU part : 0xd01"), "tsv110"); + + // Verify A64FX. + const std::string A64FXProcCpuInfo = R"( +processor : 0 +BogoMIPS : 200.00 +Features : fp asimd evtstrm sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm fcma dcpop sve +CPU implementer : 0x46 +CPU architecture: 8 +CPU variant : 0x1 +CPU part : 0x001 +)"; + + EXPECT_EQ(sys::detail::getHostCPUNameForARM(A64FXProcCpuInfo), "a64fx"); } #if defined(__APPLE__) || defined(_AIX) diff --git a/unittests/Support/TargetParserTest.cpp b/unittests/Support/TargetParserTest.cpp index 881dd4b1a82..2d68b4c7511 100644 --- a/unittests/Support/TargetParserTest.cpp +++ b/unittests/Support/TargetParserTest.cpp @@ -964,9 +964,15 @@ TEST(TargetParserTest, testAArch64CPU) { AArch64::AEK_RDM | AArch64::AEK_PROFILE | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_DOTPROD, "8.2-A")); + EXPECT_TRUE(testAArch64CPU( + "a64fx", "armv8.2-a", "crypto-neon-fp-armv8", + AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | + AArch64::AEK_SIMD | AArch64::AEK_FP16 | AArch64::AEK_RAS | + AArch64::AEK_LSE | AArch64::AEK_SVE | AArch64::AEK_RDM, + "8.2-A")); } -static constexpr unsigned NumAArch64CPUArchs = 36; +static constexpr unsigned NumAArch64CPUArchs = 37; TEST(TargetParserTest, testAArch64CPUArchList) { SmallVector List; @@ -1107,6 +1113,12 @@ TEST(TargetParserTest, testAArch64Extension) { 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_FALSE(testAArch64Extension( "generic", AArch64::ArchKind::ARMV8A, "ras"));