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

Reply via email to