From fcd62f65d28978bbea3440014e4bbb0e09efc8b2 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 16 Jun 2024 01:59:59 -0700 Subject: [PATCH 1/2] [TargetParser][AArch64] Believe runtime feature detection --- llvm/lib/TargetParser/Host.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 616e4eda1dd29..e323e2eb6ade5 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1941,9 +1941,10 @@ const StringMap sys::getHostCPUFeatures() { } #if defined(__aarch64__) - // If we have all crypto bits we can add the feature - if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2)) - Features["crypto"] = true; + // LLVM has decided some AArch64 CPUs have all the instructions they _may_ + // have, as opposed to all the instructions they _must_ have, so allow runtime + // information to correct us on that. + Features["crypto"] = (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2)); #endif return Features; @@ -1952,12 +1953,13 @@ const StringMap sys::getHostCPUFeatures() { const StringMap sys::getHostCPUFeatures() { StringMap Features; - if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) - Features["neon"] = true; - if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) - Features["crc"] = true; - if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) - Features["crypto"] = true; + // If we're asking the OS at runtime, believe what the OS says + Features["neon"] = + IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE); + Features["crc"] = + IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); + Features["crypto"] = + IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); return Features; } From 0d9373cbc3fa5baaa006003299baf75bd0e2582d Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 17 Jun 2024 11:24:40 -0700 Subject: [PATCH 2/2] [TargetParser][AArch64] Split crypto feature detection into AES & SHA2 --- llvm/lib/TargetParser/Host.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index e323e2eb6ade5..14567af8590e6 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -1898,7 +1898,8 @@ const StringMap sys::getHostCPUFeatures() { } #if defined(__aarch64__) - // Keep track of which crypto features we have seen + // All of these are "crypto" features, but we must sift out actual features + // as the former meaning of "crypto" as a single feature is no more. enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 }; uint32_t crypto = 0; #endif @@ -1944,7 +1945,10 @@ const StringMap sys::getHostCPUFeatures() { // LLVM has decided some AArch64 CPUs have all the instructions they _may_ // have, as opposed to all the instructions they _must_ have, so allow runtime // information to correct us on that. - Features["crypto"] = (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2)); + uint32_t Aes = CAP_AES | CAP_PMULL; + uint32_t Sha2 = CAP_SHA1 | CAP_SHA2; + Features["aes"] = (crypto & Aes) == Aes; + Features["sha2"] = (crypto & Sha2) == Sha2; #endif return Features; @@ -1958,8 +1962,12 @@ const StringMap sys::getHostCPUFeatures() { IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE); Features["crc"] = IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); - Features["crypto"] = + + // Avoid inferring "crypto" means more than the traditional AES + SHA2 + bool TradCrypto = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); + Features["aes"] = TradCrypto; + Features["sha2"] = TradCrypto; return Features; }