Author: Ricardo Jesus Date: 2026-01-20T13:09:17Z New Revision: 9458d2a0f403f4e79130da56b74d7828867f332c
URL: https://github.com/llvm/llvm-project/commit/9458d2a0f403f4e79130da56b74d7828867f332c DIFF: https://github.com/llvm/llvm-project/commit/9458d2a0f403f4e79130da56b74d7828867f332c.diff LOG: [AArch64][Driver] Allow runtime detection to override default features. (#176340) Currently, most extensions controlled through -march and -mcpu options are handled in a bitset of AArch64::ExtensionSet. However, extensions detected at runtime for native compilation are handled in a separate list of CPU features; once most of the parsing logic has run, the bitset is converted to a feature list, added after the features detected at runtime, and the resulting list is used from there on out. This has the downside that runtime-detected features are unable to override default CPU extensions. For example, if a CPU enables +aes in its processor definition, but aes support is not detected at runtime, the feature currently remains enabled---even though unsupported---because default features are enabled after the runtime logic attempts to disable them. This patch inserts runtime-detected features directly into the extension set such that these options can take precedence over extensions enabled by default. The general parsing order for mcpu=native becomes: 1. CPU defaults; 2. Runtime detection; 3. +featureA+nofeatureB options; 4. Other parsing decisions. This allows features that are found to be unsupported at runtime to be removed from the list of features supported by targets that enable them by default. While at it, this also disables rng if not detected at runtime. Added: Modified: clang/lib/Driver/ToolChains/Arch/AArch64.cpp clang/test/Driver/aarch64-mcpu-native.c clang/test/Driver/print-enabled-extensions/aarch64-grace.c llvm/lib/TargetParser/Host.cpp Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 087ae9201a1a0..cc6e408f45e07 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -106,14 +106,33 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, return true; } +static bool DecodeAArch64HostFeatures(llvm::AArch64::ExtensionSet &Extensions) { + llvm::StringMap<bool> HostFeatures = llvm::sys::getHostCPUFeatures(); + + for (auto &[Feature, Enabled] : HostFeatures) { + std::string F = ("+" + Feature).str(); + if (auto AE = llvm::AArch64::targetFeatureToExtension(F)) { + if (Enabled) + Extensions.enable(AE->ID); + else + Extensions.disable(AE->ID); + continue; + } + return false; + } + + return true; +} + // Check if the CPU name and feature modifiers in -mcpu are legal. If yes, // decode CPU and feature. -static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, +static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, llvm::AArch64::ExtensionSet &Extensions) { std::pair<StringRef, StringRef> Split = Mcpu.split("+"); - CPU = Split.first; + StringRef CPU = Split.first; + const bool IsNative = CPU == "native"; - if (CPU == "native") + if (IsNative) CPU = llvm::sys::getHostCPUName(); const std::optional<llvm::AArch64::CpuInfo> CpuInfo = @@ -123,6 +142,9 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, Extensions.addCPUDefaults(*CpuInfo); + if (IsNative && !DecodeAArch64HostFeatures(Extensions)) + return false; + if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Extensions)) return false; @@ -153,40 +175,26 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, return true; } -static bool getAArch64ArchFeaturesFromMcpu( - const Driver &D, StringRef Mcpu, const ArgList &Args, - llvm::AArch64::ExtensionSet &Extensions, std::vector<StringRef> &Features) { - StringRef CPU; +static bool +getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, + const ArgList &Args, + llvm::AArch64::ExtensionSet &Extensions) { std::string McpuLowerCase = Mcpu.lower(); - if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Extensions)) - return false; - - if (Mcpu == "native") { - llvm::StringMap<bool> HostFeatures = llvm::sys::getHostCPUFeatures(); - for (auto &[Feature, Enabled] : HostFeatures) { - Features.push_back(Args.MakeArgString((Enabled ? "+" : "-") + Feature)); - } - } - - return true; + return DecodeAArch64Mcpu(D, McpuLowerCase, Extensions); } -static bool -getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, - const ArgList &Args, - std::vector<StringRef> &Features) { +static bool getAArch64MicroArchFeaturesFromMtune(const Driver &D, + StringRef Mtune, + const ArgList &Args) { // Check CPU name is valid, but ignore any extensions on it. std::string MtuneLowerCase = Mtune.lower(); llvm::AArch64::ExtensionSet Extensions; - StringRef Tune; - return DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, Extensions); + return DecodeAArch64Mcpu(D, MtuneLowerCase, Extensions); } -static bool -getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, - const ArgList &Args, - std::vector<StringRef> &Features) { - return getAArch64MicroArchFeaturesFromMtune(D, Mcpu, Args, Features); +static bool getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, + const ArgList &Args) { + return getAArch64MicroArchFeaturesFromMtune(D, Mcpu, Args); } void aarch64::getAArch64TargetFeatures(const Driver &D, @@ -213,24 +221,22 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Extensions); else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) - success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions, - Features); + success = + getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions); else if (isCPUDeterminedByTriple(Triple)) success = getAArch64ArchFeaturesFromMcpu( - D, getAArch64TargetCPU(Args, Triple, A), Args, Extensions, Features); + D, getAArch64TargetCPU(Args, Triple, A), Args, Extensions); else // Default to 'A' profile if the architecture is not specified. success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Extensions); if (success && (A = Args.getLastArg(options::OPT_mtune_EQ))) - success = - getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features); + success = getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args); else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ))) - success = - getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features); + success = getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args); else if (success && isCPUDeterminedByTriple(Triple)) success = getAArch64MicroArchFeaturesFromMcpu( - D, getAArch64TargetCPU(Args, Triple, A), Args, Features); + D, getAArch64TargetCPU(Args, Triple, A), Args); if (!success) { auto Diag = D.Diag(diag::err_drv_unsupported_option_argument); diff --git a/clang/test/Driver/aarch64-mcpu-native.c b/clang/test/Driver/aarch64-mcpu-native.c index db410bf1e000d..e132081062851 100644 --- a/clang/test/Driver/aarch64-mcpu-native.c +++ b/clang/test/Driver/aarch64-mcpu-native.c @@ -33,12 +33,10 @@ // CHECK-FEAT-CA57: Extensions enabled for the given AArch64 target // CHECK-FEAT-CA57-EMPTY: // CHECK-FEAT-CA57: Architecture Feature(s) Description -// CHECK-FEAT-CA57: FEAT_AES, FEAT_PMULL Enable AES support // CHECK-FEAT-CA57: FEAT_AdvSIMD Enable Advanced SIMD instructions // CHECK-FEAT-CA57: FEAT_CRC32 Enable Armv8.0-A CRC-32 checksum instructions // CHECK-FEAT-CA57: FEAT_FP Enable Armv8.0-A Floating Point Extensions // CHECK-FEAT-CA57: FEAT_PMUv3 Enable Armv8.0-A PMUv3 Performance Monitors extension -// CHECK-FEAT-CA57: FEAT_SHA1, FEAT_SHA256 Enable SHA1 and SHA256 support // RUN: export LLVM_CPUINFO=%S/Inputs/cpunative/cortex-a72 // RUN: %clang --target=aarch64 --print-enabled-extensions -mcpu=native | FileCheck --strict-whitespace --check-prefix=CHECK-FEAT-CA72 --implicit-check-not=FEAT_ %s diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-grace.c b/clang/test/Driver/print-enabled-extensions/aarch64-grace.c index d653476410b32..acb641e3b2c8d 100644 --- a/clang/test/Driver/print-enabled-extensions/aarch64-grace.c +++ b/clang/test/Driver/print-enabled-extensions/aarch64-grace.c @@ -1,7 +1,6 @@ // REQUIRES: aarch64-registered-target,aarch64-host,system-linux // RUN: %clang --target=aarch64 --print-enabled-extensions -mcpu=grace | FileCheck --strict-whitespace --implicit-check-not=FEAT_ %s -// FIXME: mcpu=native should disable FEAT_RNG. -// RUN: env LLVM_CPUINFO=%S/../Inputs/cpunative/grace %clang --target=aarch64 --print-enabled-extensions -mcpu=native | FileCheck --check-prefixes=CHECK,NATIVE --strict-whitespace --implicit-check-not=FEAT_ %s +// RUN: env LLVM_CPUINFO=%S/../Inputs/cpunative/grace %clang --target=aarch64 --print-enabled-extensions -mcpu=native | FileCheck --strict-whitespace --implicit-check-not=FEAT_ %s // CHECK: Extensions enabled for the given AArch64 target // CHECK-EMPTY: @@ -43,7 +42,6 @@ // CHECK-NEXT: FEAT_PMUv3 Enable Armv8.0-A PMUv3 Performance Monitors extension // CHECK-NEXT: FEAT_RAS, FEAT_RASv1p1 Enable Armv8.0-A Reliability, Availability and Serviceability Extensions // CHECK-NEXT: FEAT_RDM Enable Armv8.1-A Rounding Double Multiply Add/Subtract instructions -// NATIVE-NEXT: FEAT_RNG Enable Random Number generation instructions // CHECK-NEXT: FEAT_SB Enable Armv8.5-A Speculation Barrier // CHECK-NEXT: FEAT_SEL2 Enable Armv8.4-A Secure Exception Level 2 extension // CHECK-NEXT: FEAT_SHA1, FEAT_SHA256 Enable SHA1 and SHA256 support diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index f545bbfad22b0..eebad66b2da47 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2241,6 +2241,7 @@ StringMap<bool> sys::getHostCPUFeatures() { .Case("fp", "fp-armv8") .Case("crc32", "crc") .Case("atomics", "lse") + .Case("rng", "rand") .Case("sha3", "sha3") .Case("sm4", "sm4") .Case("sve", "sve") @@ -2290,6 +2291,10 @@ StringMap<bool> sys::getHostCPUFeatures() { // detect support at runtime. if (!Features.contains("sve")) Features["sve"] = false; + + // Also disable RNG if we can't detect support at runtime. + if (!Features.contains("rand")) + Features["rand"] = false; #endif return Features; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
