https://gcc.gnu.org/g:818745a862daee49a02a54202f26972f7cf622cd

commit r17-5531-g818745a862daee49a02a54202f26972f7cf622cd
Author: Tamar Christina <[email protected]>
Date:   Sat Oct 24 11:41:35 2026 +0100

    AArch64: have -mcpu=native make educated guess on minimum arch level
    
    When -mcpu=native encounters a CPU whose MIDR we don't recognize, we 
currently
    fall back to generic-armv8-a and add the extensions reported in 
/proc/cpuinfo.
    
    For a CPU reporting SVE2, we can make a better guess and use 
generic-armv9-a as
    the starting point.  This patch uses the detected extensions to choose 
between
    the two generic CPUs.  The -march=native path uses the architecture of that 
CPU,
    and unknown heterogeneous systems use the same fallback.
    
    The important detail is that SVE2 doesn't establish all the other features
    enabled by the Armv9 baseline.  For example, if cpuinfo reports SVE2 but 
doesn't
    report atomics, we still need to turn off LSE.  The existing 
extension-string
    handling already does this for features with cpuinfo tokens.
    
    There is also a less obvious case: PREDRES is part of the Armv9 baseline 
but has
    no cpuinfo token. For a known CPU we can use the architecture from the CPU 
table
    to establish support.  For an unknown CPU we only have the inferred 
baseline, so
    inheriting PREDRES from it would be an unsupported assumption.
    
    This patch therefore limits the unreported features we inherit for unknown 
CPUs
    to the Armv8-A baseline.  The extension-string handling then adds the 
reported
    extensions and disables unverified defaults from the inferred architecture.
    
    For example, an unknown CPU reporting SVE2 and all the reportable Armv9-A
    baseline features gives
    
      -mcpu=generic-armv9-a+crc+nopredres
    
    Here PREDRES remains disabled because cpuinfo cannot establish it.  With 
fewer
    reported features, the option string also disables the missing baseline
    extensions.  Without SVE2 we continue to select generic-armv8-a.
    
    The lookup includes extensions that depend on SVE2, so later SVE2 versions 
can
    also guide the selection even though the parsed feature flags aren't
    transitively closed.
    
    The tests cover unknown single-core and heterogeneous systems, both native 
CPU
    and architecture selection, the fallback without SVE2, and the case with all
    reportable Armv9-A baseline features present.
    
    gcc/ChangeLog:
    
            * config/aarch64/driver-aarch64.cc (DEFAULT_ARCH, DEFAULT_CPU):
            Remove.
            (get_cpu_from_ext): New function.  Select a generic CPU using
            SVE2 and extensions that depend on it.
            (host_detect_local_cpu): Use the inferred generic CPU and its
            architecture for unknown CPUs, including heterogeneous systems.
            Limit inherited features without cpuinfo tokens to the Armv8-A
            baseline when the CPU is unknown.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/cpunative/native_cpu_16.c: Update the expected
            architecture and extensions for the generic Armv9 fallback.
            * gcc.target/aarch64/cpunative/native_cpu_17.c: Likewise.
            * gcc.target/aarch64/cpunative/native_cpu_34.c: Likewise.
            * gcc.target/aarch64/cpunative/info_37: New cpuinfo fixture for an
            unknown CPU with SVE2.1 and missing Armv9 baseline features.
            * gcc.target/aarch64/cpunative/info_38: New cpuinfo fixture for an
            unknown CPU without SVE2.
            * gcc.target/aarch64/cpunative/info_41: New cpuinfo fixture for an
            unknown CPU with SVE2 and all reportable Armv9-A baseline features.
            * gcc.target/aarch64/cpunative/native_cpu_37.c: New test.
            * gcc.target/aarch64/cpunative/native_cpu_38.c: New test.
            * gcc.target/aarch64/cpunative/native_cpu_39.c: New test.
            * gcc.target/aarch64/cpunative/native_cpu_40.c: New test.
            * gcc.target/aarch64/cpunative/native_cpu_41.c: New test.

Diff:
---
 gcc/config/aarch64/driver-aarch64.cc               | 33 ++++++++++++++--------
 gcc/testsuite/gcc.target/aarch64/cpunative/info_37 |  8 ++++++
 gcc/testsuite/gcc.target/aarch64/cpunative/info_38 |  9 ++++++
 gcc/testsuite/gcc.target/aarch64/cpunative/info_41 |  9 ++++++
 .../gcc.target/aarch64/cpunative/native_cpu_16.c   |  2 +-
 .../gcc.target/aarch64/cpunative/native_cpu_17.c   |  2 +-
 .../gcc.target/aarch64/cpunative/native_cpu_34.c   |  2 +-
 .../gcc.target/aarch64/cpunative/native_cpu_37.c   | 12 ++++++++
 .../gcc.target/aarch64/cpunative/native_cpu_38.c   | 12 ++++++++
 .../gcc.target/aarch64/cpunative/native_cpu_39.c   | 12 ++++++++
 .../gcc.target/aarch64/cpunative/native_cpu_40.c   | 12 ++++++++
 .../gcc.target/aarch64/cpunative/native_cpu_41.c   | 13 +++++++++
 12 files changed, 111 insertions(+), 15 deletions(-)

diff --git a/gcc/config/aarch64/driver-aarch64.cc 
b/gcc/config/aarch64/driver-aarch64.cc
index 7433ba90267c..a599f6c2b63a 100644
--- a/gcc/config/aarch64/driver-aarch64.cc
+++ b/gcc/config/aarch64/driver-aarch64.cc
@@ -58,9 +58,6 @@ struct aarch64_core_data
 #define INVALID_IMP ((unsigned char) -1)
 #define INVALID_CORE ((unsigned)-1)
 #define ALL_VARIANTS ((unsigned)-1)
-/* Default architecture to use if -mcpu=native did not detect a known CPU.  */
-#define DEFAULT_ARCH "8A"
-#define DEFAULT_CPU "generic-armv8-a"
 
 #define AARCH64_CORE(CORE_NAME, CORE_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, 
PART, VARIANT) \
   { CORE_NAME, #ARCH, IMP, PART, unsigned(VARIANT), 
feature_deps::cpu_##CORE_IDENT },
@@ -71,7 +68,6 @@ static constexpr const aarch64_core_data aarch64_cpu_data[] =
   { NULL, NULL, INVALID_IMP, INVALID_CORE, ALL_VARIANTS, 0 }
 };
 
-
 struct aarch64_arch_driver_info
 {
   const char* id;
@@ -119,6 +115,15 @@ get_cpu_from_id (const char* name)
   return NULL;
 }
 
+/* Choose a generic CPU for unknown cores using FLAGS.  Include extensions
+   that require SVE2, since cpuinfo flags aren't transitively closed.  */
+static const aarch64_core_data *
+get_cpu_from_ext (aarch64_feature_flags flags)
+{
+  return get_cpu_from_id (flags & feature_deps::get_flags_off (AARCH64_FL_SVE2)
+                         ? "generic-armv9-a" : "generic-armv8-a");
+}
+
 /* Check whether the CORE array is the same as the big.LITTLE BL_CORE.
    For an example CORE={0xd08, 0xd03} and
    BL_CORE=AARCH64_BIG_LITTLE (0xd08, 0xd03) will return true.  */
@@ -428,12 +433,13 @@ host_detect_local_cpu (int argc, const char **argv)
                 || variants[0] == aarch64_cpu_data[i].variant))
          break;
 
+      auto cpu_info = (aarch64_cpu_data[i].name
+                          ? &aarch64_cpu_data[i]
+                          : get_cpu_from_ext (extension_flags));
+      gcc_assert (cpu_info);
       if (arch)
        {
-         const char *arch_id = (aarch64_cpu_data[i].name
-                                ? aarch64_cpu_data[i].arch
-                                : DEFAULT_ARCH);
-         auto arch_info = get_arch_from_id (arch_id);
+         auto arch_info = get_arch_from_id (cpu_info->arch);
 
          /* We got some arch identifier that's not in aarch64-arches.def?  */
          if (!arch_info)
@@ -444,9 +450,6 @@ host_detect_local_cpu (int argc, const char **argv)
        }
       else if (cpu || aarch64_cpu_data[i].name)
        {
-         auto cpu_info = (aarch64_cpu_data[i].name
-                          ? &aarch64_cpu_data[i]
-                          : get_cpu_from_id (DEFAULT_CPU));
          default_flags = cpu_info->flags;
          res = concat ("-m",
                        cpu ? "cpu" : "tune", "=",
@@ -476,7 +479,7 @@ host_detect_local_cpu (int argc, const char **argv)
         the feature flags from any of the cpus.  */
       if (cpu && aarch64_cpu_data[i].name == NULL)
        {
-         auto cpu_info = get_cpu_from_id (DEFAULT_CPU);
+         auto cpu_info = get_cpu_from_ext (extension_flags);
 
          gcc_assert (cpu_info);
 
@@ -491,6 +494,12 @@ host_detect_local_cpu (int argc, const char **argv)
   if (tune)
     return res;
 
+  /* An inferred architecture does not establish support for features that
+     cpuinfo cannot report.  Only retain the Armv8-A baseline in that case;
+     the extension string below disables other unverified defaults.  */
+  if (aarch64_cpu_data[i].name == NULL)
+    unchecked_extension_flags &= feature_deps::V8A ().enable;
+
   /* Add any features that should be present, but can't be verified using
      the /proc/cpuinfo "Features" list.  */
   extension_flags |= unchecked_extension_flags & default_flags;
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_37 
b/gcc/testsuite/gcc.target/aarch64/cpunative/info_37
new file mode 100644
index 000000000000..d7e1912c15da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_37
@@ -0,0 +1,8 @@
+processor      : 0
+BogoMIPS       : 100.00
+Features       : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 
sve2p1 fphp asimdhp fcma
+CPU implementer        : 0xfe
+CPU architecture: 8
+CPU variant    : 0x0
+CPU part       : 0xd08
+CPU revision   : 2
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_38 
b/gcc/testsuite/gcc.target/aarch64/cpunative/info_38
new file mode 100644
index 000000000000..78659e0f63a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_38
@@ -0,0 +1,9 @@
+processor      : 0
+BogoMIPS       : 100.00
+Features       : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp
+CPU implementer        : 0xfe
+CPU architecture: 8
+CPU variant    : 0x0
+CPU part       : 0xd08
+CPU revision   : 2
+
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_41 
b/gcc/testsuite/gcc.target/aarch64/cpunative/info_41
new file mode 100644
index 000000000000..f05956856578
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_41
@@ -0,0 +1,9 @@
+processor      : 0
+BogoMIPS       : 100.00
+Features       : fp asimd atomics crc32 asimdrdm paca pacg lrcpc fcma jscvt 
asimdfhm asimddp flagm ilrcpc sb ssbs frint flagm2 fphp asimdhp sve sve2
+CPU implementer        : 0xfe
+CPU architecture: 8
+CPU variant    : 0x0
+CPU part       : 0xd08
+CPU revision   : 2
+
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c
index 649e48e7e0b7..a24ca4ddbd9c 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c
@@ -7,6 +7,6 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-assembler {\.arch armv8-a\+dotprod\+crc\+crypto\+sve2\n} 
} } */
+/* { dg-final { scan-assembler {\.arch 
armv9-a\+crc\+crypto\+noflagm\+nolse\+nordma\+nofp16fml\+nojscvt\+norcpc\+nofrintts\+nosb\+nopredres\+nossbs\+nopauth\n}
 } } */
 
 /* Test a normal looking procinfo.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c
index 078d7bc899cc..c13715349e57 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c
@@ -7,6 +7,6 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-assembler {\.arch armv8-a\+dotprod\+crc\+crypto\+sve2\n} 
} } */
+/* { dg-final { scan-assembler {\.arch 
armv9-a\+crc\+crypto\+noflagm\+nolse\+nordma\+nofp16fml\+nojscvt\+norcpc\+nofrintts\+nosb\+nopredres\+nossbs\+nopauth\n}
 } } */
 
 /* Test a normal looking procinfo.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_34.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_34.c
index 168140002a0f..60564652245e 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_34.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_34.c
@@ -7,6 +7,6 @@ int main()
   return 0;
 }
 
-/* { dg-final { scan-assembler {\.arch armv8-a\+dotprod\+crc\+crypto\+sve2\n} 
} } */
+/* { dg-final { scan-assembler {\.arch 
armv9-a\+crc\+crypto\+noflagm\+nolse\+nordma\+nofp16fml\+nojscvt\+norcpc\+nofrintts\+nosb\+nopredres\+nossbs\+nopauth\n}
 } } */
 
 /* Test a normal looking procinfo.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_37.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_37.c
new file mode 100644
index 000000000000..72d8a1d92042
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_37.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/aarch64/cpunative/info_37" } */
+/* Force the architecture detection path with an unknown MIDR.  SVE2
+   suggests Armv9, but does not establish its other baseline features.  */
+/* { dg-additional-options "-march=native -mtune=cortex-a34" } */
+
+int main()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.arch 
armv9-a\+crc\+crypto\+sve2p1\+noflagm\+nolse\+nordma\+nofp16fml\+nojscvt\+norcpc\+nofrintts\+nosb\+nopredres\+nossbs\+nopauth\n}
 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_38.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_38.c
new file mode 100644
index 000000000000..15de18ce5120
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_38.c
@@ -0,0 +1,12 @@
+/* Check the inferred CPU as well as the ISA for an unknown SVE2 core.  */
+/* { dg-do compile { target { { aarch64*-*-linux* } && native } } } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/aarch64/cpunative/info_37" } */
+/* { dg-additional-options "-mcpu=native -###" } */
+
+int main ()
+{
+  return 0;
+}
+
+/* { dg-message "-mcpu=generic-armv9-a\\+crc\\+crypto\\+sve2p1.*\\+nopredres" 
"note" { target *-*-* } 0 } */
+/* { dg-excess-errors "" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_39.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_39.c
new file mode 100644
index 000000000000..a6042b4f5cb6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_39.c
@@ -0,0 +1,12 @@
+/* An unknown CPU without SVE2 uses the generic Armv8 CPU.  */
+/* { dg-do compile { target { { aarch64*-*-linux* } && native } } } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/aarch64/cpunative/info_38" } */
+/* { dg-additional-options "-mcpu=native -###" } */
+
+int main ()
+{
+  return 0;
+}
+
+/* { dg-message "-mcpu=generic-armv8-a\\+dotprod\\+crc\\+crypto" "note" { 
target *-*-* } 0 } */
+/* { dg-excess-errors "" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_40.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_40.c
new file mode 100644
index 000000000000..0b7590817693
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_40.c
@@ -0,0 +1,12 @@
+/* Unknown heterogeneous cores use the detected features for the fallback.  */
+/* { dg-do compile { target { { aarch64*-*-linux* } && native } } } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/aarch64/cpunative/info_35" } */
+/* { dg-additional-options "-mcpu=native -###" } */
+
+int main ()
+{
+  return 0;
+}
+
+/* { dg-message "-mcpu=generic-armv9-a\\+crc\\+crypto.*\\+nopredres" "note" { 
target *-*-* } 0 } */
+/* { dg-excess-errors "" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_41.c 
b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_41.c
new file mode 100644
index 000000000000..45df4f5ee201
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_41.c
@@ -0,0 +1,13 @@
+/* An unknown CPU reports SVE2 and all reportable Armv9-A baseline features.
+   None of those features should be disabled.  PREDRES has no cpuinfo token
+   and must still be disabled rather than inferred from SVE2.  */
+/* { dg-do compile { target { { aarch64*-*-linux* } && native } } } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/aarch64/cpunative/info_41" } */
+/* { dg-additional-options "-mcpu=native" } */
+
+int main ()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.arch armv9-a\+crc\+nopredres\n} } } */

Reply via email to