https://github.com/rj-jesus updated https://github.com/llvm/llvm-project/pull/166387
>From 66450a937f415c302793901ddcb67a2ba161265c Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <[email protected]> Date: Thu, 15 Jan 2026 06:31:26 -0800 Subject: [PATCH 1/4] [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 feature 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 9b54adb16d567a75bef2ffd4e7192df3398f25f1 Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <[email protected]> Date: Thu, 15 Jan 2026 06:31:53 -0800 Subject: [PATCH 2/4] [AArch64] Disable FEAT_RNG on Grace. This also disabled rng if not found at runtime. --- clang/test/Driver/print-enabled-extensions/aarch64-grace.c | 1 - llvm/lib/Target/AArch64/AArch64Processors.td | 2 +- llvm/lib/TargetParser/Host.cpp | 5 +++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-grace.c b/clang/test/Driver/print-enabled-extensions/aarch64-grace.c index b66e649965489..acb641e3b2c8d 100644 --- a/clang/test/Driver/print-enabled-extensions/aarch64-grace.c +++ b/clang/test/Driver/print-enabled-extensions/aarch64-grace.c @@ -42,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 -// CHECK-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/Target/AArch64/AArch64Processors.td b/llvm/lib/Target/AArch64/AArch64Processors.td index af0813e43a960..6f38673c50e23 100644 --- a/llvm/lib/Target/AArch64/AArch64Processors.td +++ b/llvm/lib/Target/AArch64/AArch64Processors.td @@ -1379,7 +1379,7 @@ def ProcessorFeatures { FeatureSSBS, FeatureCCIDX, FeatureJS, FeatureLSE, FeatureRAS, FeatureRCPC, FeatureRDM]; list<SubtargetFeature> GB10 = !listconcat(X925, [FeatureSVEAES, FeatureSVESHA3, FeatureSVESM4]); - list<SubtargetFeature> Grace = !listconcat(NeoverseV2, [FeatureSVESM4, FeatureSVEAES, FeatureSVESHA3]); + list<SubtargetFeature> Grace = !listconcat(!listremove(NeoverseV2, [FeatureRandGen]), [FeatureSVESM4, FeatureSVEAES, FeatureSVESHA3]); // ETE and TRBE are future architecture extensions. We temporarily enable them // by default for users targeting generic AArch64. The extensions do not 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; >From 18f06c3f153054482e75989bf51883054a0e0139 Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <[email protected]> Date: Mon, 19 Jan 2026 03:23:22 -0800 Subject: [PATCH 3/4] Revert "[AArch64][Driver] Allow runtime detection to override default feaures." This reverts commit 66450a937f415c302793901ddcb67a2ba161265c. --- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 80 +++++++++----------- clang/test/Driver/aarch64-mcpu-native.c | 2 + 2 files changed, 39 insertions(+), 43 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index cc6e408f45e07..087ae9201a1a0 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -106,33 +106,14 @@ 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, +static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, llvm::AArch64::ExtensionSet &Extensions) { std::pair<StringRef, StringRef> Split = Mcpu.split("+"); - StringRef CPU = Split.first; - const bool IsNative = CPU == "native"; + CPU = Split.first; - if (IsNative) + if (CPU == "native") CPU = llvm::sys::getHostCPUName(); const std::optional<llvm::AArch64::CpuInfo> CpuInfo = @@ -142,9 +123,6 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, Extensions.addCPUDefaults(*CpuInfo); - if (IsNative && !DecodeAArch64HostFeatures(Extensions)) - return false; - if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Extensions)) return false; @@ -175,26 +153,40 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, return true; } -static bool -getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, - const ArgList &Args, - llvm::AArch64::ExtensionSet &Extensions) { +static bool getAArch64ArchFeaturesFromMcpu( + const Driver &D, StringRef Mcpu, const ArgList &Args, + llvm::AArch64::ExtensionSet &Extensions, std::vector<StringRef> &Features) { + StringRef CPU; std::string McpuLowerCase = Mcpu.lower(); - return DecodeAArch64Mcpu(D, McpuLowerCase, Extensions); + 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; } -static bool getAArch64MicroArchFeaturesFromMtune(const Driver &D, - StringRef Mtune, - const ArgList &Args) { +static bool +getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, + const ArgList &Args, + std::vector<StringRef> &Features) { // Check CPU name is valid, but ignore any extensions on it. std::string MtuneLowerCase = Mtune.lower(); llvm::AArch64::ExtensionSet Extensions; - return DecodeAArch64Mcpu(D, MtuneLowerCase, Extensions); + StringRef Tune; + return DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, Extensions); } -static bool getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, - const ArgList &Args) { - return getAArch64MicroArchFeaturesFromMtune(D, Mcpu, Args); +static bool +getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, + const ArgList &Args, + std::vector<StringRef> &Features) { + return getAArch64MicroArchFeaturesFromMtune(D, Mcpu, Args, Features); } void aarch64::getAArch64TargetFeatures(const Driver &D, @@ -221,22 +213,24 @@ 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); + success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions, + Features); else if (isCPUDeterminedByTriple(Triple)) success = getAArch64ArchFeaturesFromMcpu( - D, getAArch64TargetCPU(Args, Triple, A), Args, Extensions); + D, getAArch64TargetCPU(Args, Triple, A), Args, Extensions, Features); 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); + success = + getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features); else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ))) - success = getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args); + success = + getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features); else if (success && isCPUDeterminedByTriple(Triple)) success = getAArch64MicroArchFeaturesFromMcpu( - D, getAArch64TargetCPU(Args, Triple, A), Args); + D, getAArch64TargetCPU(Args, Triple, A), Args, Features); 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 e132081062851..db410bf1e000d 100644 --- a/clang/test/Driver/aarch64-mcpu-native.c +++ b/clang/test/Driver/aarch64-mcpu-native.c @@ -33,10 +33,12 @@ // 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 3cb1cc833496db965ed969b6022a099a89a35b6f Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <[email protected]> Date: Mon, 19 Jan 2026 03:37:34 -0800 Subject: [PATCH 4/4] Drop Host.cpp changes. --- clang/test/Driver/print-enabled-extensions/aarch64-grace.c | 4 +++- llvm/lib/TargetParser/Host.cpp | 5 ----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-grace.c b/clang/test/Driver/print-enabled-extensions/aarch64-grace.c index acb641e3b2c8d..d653476410b32 100644 --- a/clang/test/Driver/print-enabled-extensions/aarch64-grace.c +++ b/clang/test/Driver/print-enabled-extensions/aarch64-grace.c @@ -1,6 +1,7 @@ // 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 -// RUN: env LLVM_CPUINFO=%S/../Inputs/cpunative/grace %clang --target=aarch64 --print-enabled-extensions -mcpu=native | 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 // CHECK: Extensions enabled for the given AArch64 target // CHECK-EMPTY: @@ -42,6 +43,7 @@ // 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 eebad66b2da47..f545bbfad22b0 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2241,7 +2241,6 @@ 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") @@ -2291,10 +2290,6 @@ 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
