https://github.com/rj-jesus updated https://github.com/llvm/llvm-project/pull/176340
>From b883d9ce6fb09ab76db79d39f6ef83282583a024 Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <[email protected]> Date: Thu, 15 Jan 2026 06:31:26 -0800 Subject: [PATCH 1/2] [AArch64][Driver] Allow runtime detection to override default feaures. 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 list of features, added after the features detected at runtime, and the resulting list is used from there on. 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 is not found 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. Further +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. --- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 80 +++++++++++--------- clang/test/Driver/aarch64-mcpu-native.c | 2 - 2 files changed, 43 insertions(+), 39 deletions(-) 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 >From 02a6500e7b001dabca7ddfef35a56a1ff36201bd Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <[email protected]> Date: Mon, 19 Jan 2026 03:52:48 -0800 Subject: [PATCH 2/2] Include RNG fix for -mcpu=native. --- clang/test/Driver/print-enabled-extensions/aarch64-grace.c | 4 +--- llvm/lib/TargetParser/Host.cpp | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) 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
