https://gcc.gnu.org/g:bbc5005bf48212c94501bd3918c44b38be6aa94e

commit r17-3883-gbbc5005bf48212c94501bd3918c44b38be6aa94e
Author: Kito Cheng <[email protected]>
Date:   Mon Aug 24 20:29:58 2026 +0800

    RISC-V: Support -mtune=native and -mcpu=native
    
    Identify the core by matching mvendorid, marchid and mimpid, with the
    values taken from hwprobe or /proc/cpuinfo.
    
    Like any other -mcpu=, -mcpu=native overrides neither -march= nor
    -mtune=.  That needs the configured defaults to keep out of the way:
    OPTION_DEFAULT_SPECS runs before the driver self specs, and --with-arch
    would otherwise reach riscv_expand_arch_from_cpu, which knows of no core
    called native and quietly falls back on the configured string.
    
    We pick the CPU this process is running on when the cores have different
    mvendorid, marchid or mimpid for now; we may add support for that once we
    have -mcpu=A+B/-mtune=A+B.
    
    NOTE: SpacemiT K3 might be the candidate for that, but A100 and X100 have
          different VLEN and the system default only allows a program to use
          X100, so I did not handle the case for now.
    
    gcc/ChangeLog:
    
            * config/riscv/driver-riscv.cc (struct riscv_cpuid): New.
            (riscv_cpuid::valid_p, riscv_cpuid::match): New member functions.
            (struct riscv_core_id): New.
            (riscv_core_ids): New.
            (riscv_core_from_cpuid): New function.
            (riscv_hwprobe_cpus, riscv_hwprobe_affinity, 
riscv_hwprobe_this_core):
            New functions.
            (struct riscv_cpuinfo): Add the identification registers.
            (riscv_read_cpuinfo): Read them.
            (riscv_cpuid_from_pairs, riscv_cpuid_from_hwprobe)
            (riscv_cpuid_from_cpuinfo): New functions.
            (riscv_native_tune): New function.
            (host_detect_local_cpu): Handle "tune".
            * config/riscv/riscv.h (RISCV_NATIVE_SPECS): Handle -mtune=native
            and -mcpu=native.
            (OPTION_DEFAULT_SPECS): Leave -mcpu=native to RISCV_NATIVE_SPECS.
            * config/riscv/x-riscv: Update the dependencies.
            * doc/invoke.texi (RISC-V Options): Document -mtune=native and
            -mcpu=native.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/march-native-2.c: New test.
            * gcc.target/riscv/march-native-3.c: New test.
            * gcc.target/riscv/march-native-4.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_7.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_8.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_9.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_10.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_11.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_12.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_13.c: New test.
            * gcc.target/riscv/cpunative/native_cpu_0.c: Check the tuning too.
            * gcc.target/riscv/cpunative/native_cpu_1.c: Likewise.
            * gcc.target/riscv/cpunative/native_cpu_2.c: Likewise.
            * gcc.target/riscv/cpunative/native_cpu_4.c: Likewise.
            * gcc.target/riscv/cpunative/native_cpu_5.c: Likewise.
            * gcc.target/riscv/cpunative/native_cpu_6.c: Likewise.
            * gcc.target/riscv/cpunative/native_cpu_3.c: Check that an
            unrecognised core leaves the tuning alone.

Diff:
---
 gcc/config/riscv/driver-riscv.cc                   | 226 ++++++++++++++++++++-
 gcc/config/riscv/riscv.h                           |  17 +-
 gcc/config/riscv/x-riscv                           |   1 +
 gcc/doc/invoke.texi                                |   7 +
 .../gcc.target/riscv/cpunative/native_cpu_0.c      |   3 +-
 .../gcc.target/riscv/cpunative/native_cpu_1.c      |   3 +-
 .../gcc.target/riscv/cpunative/native_cpu_10.c     |  17 ++
 .../gcc.target/riscv/cpunative/native_cpu_11.c     |  16 ++
 .../gcc.target/riscv/cpunative/native_cpu_12.c     |  15 ++
 .../gcc.target/riscv/cpunative/native_cpu_13.c     |  19 ++
 .../gcc.target/riscv/cpunative/native_cpu_2.c      |   3 +-
 .../gcc.target/riscv/cpunative/native_cpu_3.c      |   7 +-
 .../gcc.target/riscv/cpunative/native_cpu_4.c      |   3 +-
 .../gcc.target/riscv/cpunative/native_cpu_5.c      |   3 +-
 .../gcc.target/riscv/cpunative/native_cpu_6.c      |   3 +-
 .../gcc.target/riscv/cpunative/native_cpu_7.c      |  15 ++
 .../gcc.target/riscv/cpunative/native_cpu_8.c      |  16 ++
 .../gcc.target/riscv/cpunative/native_cpu_9.c      |  15 ++
 gcc/testsuite/gcc.target/riscv/march-native-2.c    |  12 ++
 gcc/testsuite/gcc.target/riscv/march-native-3.c    |  13 ++
 gcc/testsuite/gcc.target/riscv/march-native-4.c    |  14 ++
 21 files changed, 414 insertions(+), 14 deletions(-)

diff --git a/gcc/config/riscv/driver-riscv.cc b/gcc/config/riscv/driver-riscv.cc
index 03a52a3b9760..467a959afb5a 100644
--- a/gcc/config/riscv/driver-riscv.cc
+++ b/gcc/config/riscv/driver-riscv.cc
@@ -27,8 +27,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "riscv-subset.h"
 
 #ifdef __linux__
+#include <sched.h>
 #include "common/config/riscv/riscv-hwprobe.h"
 
+/* Read for UNKNOWN_ID alone; the core table itself is built further down.  */
+#include "riscv-cores.def"
+
 #ifndef __NR_getcpu
 #define __NR_getcpu 168
 #endif
@@ -49,6 +53,83 @@ static const struct riscv_hwprobe_ext riscv_hwprobe_exts[] = 
{
 #include "common/config/riscv/riscv-hwprobe.def"
 };
 
+/* What the mvendorid, marchid and mimpid CSRs read on one core.  */
+
+struct riscv_cpuid
+{
+  constexpr riscv_cpuid ()
+    : mvendorid (UNKNOWN_ID), marchid (UNKNOWN_ID), mimpid (UNKNOWN_ID)
+  {
+  }
+
+  constexpr riscv_cpuid (riscv_core_id_t vendor, riscv_core_id_t arch,
+                        riscv_core_id_t impl)
+    : mvendorid (vendor), marchid (arch), mimpid (impl)
+  {
+  }
+
+  bool valid_p () const;
+  bool match (const struct riscv_cpuid &other) const;
+
+  riscv_core_id_t mvendorid;
+  riscv_core_id_t marchid;
+  riscv_core_id_t mimpid;
+};
+
+/* True if all three registers have a value.  */
+
+bool
+riscv_cpuid::valid_p () const
+{
+  return (mvendorid != UNKNOWN_ID
+         && marchid != UNKNOWN_ID
+         && mimpid != UNKNOWN_ID);
+}
+
+/* True if OTHER is the same core.  All three registers have to agree, and
+   both sides have to have all three: most of riscv-cores.def records none
+   of them, and a detection that came back empty must not match those.  */
+
+bool
+riscv_cpuid::match (const struct riscv_cpuid &other) const
+{
+  return (valid_p ()
+         && other.valid_p ()
+         && mvendorid == other.mvendorid
+         && marchid == other.marchid
+         && mimpid == other.mimpid);
+}
+
+/* One entry per core, holding what it reports in its identification
+   registers.  */
+
+struct riscv_core_id
+{
+  const char *name;
+  struct riscv_cpuid id;
+};
+
+static const struct riscv_core_id riscv_core_ids[] = {
+#define RISCV_CORE(CORE_NAME, ARCH, MICRO_ARCH, MVENDORID, MARCHID, MIMPID) \
+  { CORE_NAME, { (riscv_core_id_t) (MVENDORID),                                
\
+                (riscv_core_id_t) (MARCHID),                           \
+                (riscv_core_id_t) (MIMPID) } },
+#include "riscv-cores.def"
+};
+
+/* Return the name of the core whose identification registers read ID, or
+   NULL if riscv-cores.def describes no such core.  */
+
+static const char *
+riscv_core_from_cpuid (const struct riscv_cpuid &id)
+{
+  for (size_t i = 0; i < ARRAY_SIZE (riscv_core_ids); i++)
+    if (riscv_core_ids[i].id.match (id))
+      return riscv_core_ids[i].name;
+
+  return NULL;
+}
+
 /* Return the number of the CPU this process is currently running on, or -1
    if it cannot be determined.  */
 
@@ -63,6 +144,53 @@ riscv_current_cpu (void)
   return (int) cpu;
 }
 
+/* Ask hwprobe about the CPUs in CPUS.  */
+
+static bool
+riscv_hwprobe_cpus (struct riscv_hwprobe *pairs, size_t npairs,
+                   const cpu_set_t *cpus)
+{
+  return syscall_5_args (__NR_riscv_hwprobe, (long) pairs, (long) npairs,
+                        (long) sizeof (*cpus), (long) cpus, 0) == 0;
+}
+
+/* Ask hwprobe about the CPUs this process may run on rather than about the
+   whole machine: on a machine whose cores are not all alike, a query that
+   spans cores which disagree is answered with UNKNOWN_ID.
+
+   TODO: Cores that differ but share an ISA could still be described, once
+   we have -mcpu=A+B/-mtune=A+B.  */
+
+static bool
+riscv_hwprobe_affinity (struct riscv_hwprobe *pairs, size_t npairs)
+{
+  cpu_set_t cpus;
+
+  if (sched_getaffinity (0, sizeof (cpus), &cpus) != 0)
+    return false;
+
+  return riscv_hwprobe_cpus (pairs, npairs, &cpus);
+}
+
+/* Ask hwprobe about the one CPU this process is running on, for when the
+   CPUs it may run on do not agree and the wider query therefore answers
+   UNKNOWN_ID.  That is the core /proc/cpuinfo describes as well.  */
+
+static bool
+riscv_hwprobe_this_core (struct riscv_hwprobe *pairs, size_t npairs)
+{
+  cpu_set_t cpus;
+  int cpu = riscv_current_cpu ();
+
+  if (cpu < 0 || cpu >= CPU_SETSIZE)
+    return false;
+
+  CPU_ZERO (&cpus);
+  CPU_SET (cpu, &cpus);
+
+  return riscv_hwprobe_cpus (pairs, npairs, &cpus);
+}
+
 /* Append the Zvl extension for this machine's vector register width,
    which only the vlenb CSR reports.  */
 
@@ -136,6 +264,7 @@ riscv_arch_from_hwprobe (std::string &isa, bool *vector_p)
 struct riscv_cpuinfo
 {
   std::string isa;
+  struct riscv_cpuid id;
 };
 
 /* GCC_CPUINFO names a file to read instead of /proc/cpuinfo, and
@@ -211,6 +340,7 @@ riscv_read_cpuinfo (int want, struct riscv_cpuinfo *out)
     return false;
 
   out->isa.clear ();
+  out->id = riscv_cpuid ();
 
   while (fgets (line, sizeof (line), f) != NULL)
     {
@@ -241,6 +371,12 @@ riscv_read_cpuinfo (int want, struct riscv_cpuinfo *out)
        }
       else if (name == "isa" && !hart_isa_p)
        out->isa = value;
+      else if (name == "mvendorid")
+       out->id.mvendorid = strtoull (value, NULL, 0);
+      else if (name == "marchid")
+       out->id.marchid = strtoull (value, NULL, 0);
+      else if (name == "mimpid")
+       out->id.mimpid = strtoull (value, NULL, 0);
     }
 
   fclose (f);
@@ -349,6 +485,78 @@ riscv_native_arch (void)
   return xstrdup (isa.c_str ());
 }
 
+/* Get mvendorid, marchid, mimpid out of what a hwprobe query wrote into
+   PAIRS.  Return false unless every register came back with a value.  */
+
+static bool
+riscv_cpuid_from_pairs (const struct riscv_hwprobe *pairs, size_t npairs,
+                       struct riscv_cpuid &id)
+{
+  id = riscv_cpuid (riscv_hwprobe_value (pairs, npairs,
+                                        RISCV_HWPROBE_KEY_MVENDORID),
+                   riscv_hwprobe_value (pairs, npairs,
+                                        RISCV_HWPROBE_KEY_MARCHID),
+                   riscv_hwprobe_value (pairs, npairs,
+                                        RISCV_HWPROBE_KEY_MIMPID));
+
+  return id.valid_p ();
+}
+
+/* Get mvendorid, marchid, mimpid by hwprobe.  Return false if the
+   kernel cannot describe the core.  */
+
+static bool
+riscv_cpuid_from_hwprobe (struct riscv_cpuid &id)
+{
+  struct riscv_hwprobe pairs[] = {
+    { RISCV_HWPROBE_KEY_MVENDORID, 0 },
+    { RISCV_HWPROBE_KEY_MARCHID, 0 },
+    { RISCV_HWPROBE_KEY_MIMPID, 0 }
+  };
+  size_t npairs = ARRAY_SIZE (pairs);
+
+  if (riscv_hwprobe_affinity (pairs, npairs)
+      && riscv_cpuid_from_pairs (pairs, npairs, id))
+    return true;
+
+  return (riscv_hwprobe_this_core (pairs, npairs)
+         && riscv_cpuid_from_pairs (pairs, npairs, id));
+}
+
+/* Get mvendorid, marchid, mimpid by /proc/cpuinfo.  Return false if
+   it does not name all three.  */
+
+static bool
+riscv_cpuid_from_cpuinfo (struct riscv_cpuid &id)
+{
+  struct riscv_cpuinfo info;
+
+  if (!riscv_cpuinfo (&info))
+    return false;
+
+  id = info.id;
+
+  return id.valid_p ();
+}
+
+/* Return the name of the core this machine runs, or NULL if it is not one
+   riscv-cores.def has identification registers for.  */
+
+static const char *
+riscv_native_tune (void)
+{
+  struct riscv_cpuid id;
+  const char *core;
+
+  if ((riscv_cpuinfo_forced () || !riscv_cpuid_from_hwprobe (id))
+      && !riscv_cpuid_from_cpuinfo (id))
+    return NULL;
+
+  core = riscv_core_from_cpuid (id);
+
+  return core != NULL ? xstrdup (core) : NULL;
+}
+
 #else /* !__linux__ */
 
 static const char *
@@ -357,10 +565,16 @@ riscv_native_arch (void)
   return NULL;
 }
 
+static const char *
+riscv_native_tune (void)
+{
+  return NULL;
+}
+
 #endif /* __linux__ */
 
 /* Implement the local_cpu_detect spec function.  ARGV[0] selects what to
-   report: "arch" for an -march= option.  */
+   report: "arch" for an -march= option, "tune" for an -mtune= one.  */
 
 const char *
 host_detect_local_cpu (int argc, const char **argv)
@@ -378,5 +592,15 @@ host_detect_local_cpu (int argc, const char **argv)
       return concat ("-march=", isa, NULL);
     }
 
+  if (strcmp (argv[0], "tune") == 0)
+    {
+      const char *core = riscv_native_tune ();
+
+      if (core == NULL)
+       return NULL;
+
+      return concat ("-mtune=", core, NULL);
+    }
+
   return NULL;
 }
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 80356eacadbb..7ba2a726ac40 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -59,7 +59,11 @@ extern const char *host_detect_local_cpu (int argc, const 
char **argv);
   { "local_cpu_detect", host_detect_local_cpu },
 
 # define RISCV_NATIVE_SPECS                                            \
-  "%{march=native:%<march=native %:local_cpu_detect(arch)} "
+  "%{march=native:%<march=native %:local_cpu_detect(arch)} "           \
+  "%{mtune=native:%<mtune=native %:local_cpu_detect(tune)} "           \
+  "%{mcpu=native:%<mcpu=native "                                       \
+    "%{!march=*|march=unset:%<march=* %:local_cpu_detect(arch)} "      \
+    "%{!mtune=*:%:local_cpu_detect(tune)}} "
 #else
 # define RISCV_NATIVE_SPEC_FUNCTIONS
 # define RISCV_NATIVE_SPECS ""
@@ -82,15 +86,18 @@ extern const char *host_detect_local_cpu (int argc, const 
char **argv);
    --with-tls is ignored if -mtls-dialect is specified.
    --with-cmodel is ignored if -mcmodel is specified.
 
+   -mcpu=native is defer to RISCV_NATIVE_SPECS to prevent disturb the option
+   order.
+
    Uses default values if -mcpu doesn't have a valid option.  */
 #define OPTION_DEFAULT_SPECS \
   {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" },                               \
-  {"tune", "%{!mtune=*:"                                               \
+  {"tune", "%{!mtune=*:%{!mcpu=native:"                                        
\
           "  %{!mcpu=*:-mtune=%(VALUE)}"                               \
-          "  %{mcpu=*:-mtune=%:riscv_default_mtune(%* %(VALUE))}}" },  \
-  {"arch", "%{!march=*|march=unset:"                                   \
+          "  %{mcpu=*:-mtune=%:riscv_default_mtune(%* %(VALUE))}}}" }, \
+  {"arch", "%{!march=*|march=unset:%{!mcpu=native:"                    \
           "  %{!mcpu=*:-march=%(VALUE)}"                               \
-          "  %{mcpu=*:%:riscv_expand_arch_from_cpu(%* %(VALUE))}}" },  \
+          "  %{mcpu=*:%:riscv_expand_arch_from_cpu(%* %(VALUE))}}}" }, \
   {"abi", "%{!mabi=*:-mabi=%(VALUE)}" },                               \
   {"isa_spec", "%{!misa-spec=*:-misa-spec=%(VALUE)}" },                        
\
   {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"},                \
diff --git a/gcc/config/riscv/x-riscv b/gcc/config/riscv/x-riscv
index d1c59ba50e0c..1a9eadac91a1 100644
--- a/gcc/config/riscv/x-riscv
+++ b/gcc/config/riscv/x-riscv
@@ -1,6 +1,7 @@
 driver-riscv.o: $(srcdir)/config/riscv/driver-riscv.cc \
   $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(CORETYPES_H) \
   $(srcdir)/config/riscv/riscv-subset.h \
+  $(srcdir)/config/riscv/riscv-cores.def \
   $(srcdir)/common/config/riscv/riscv-hwprobe.h \
   $(srcdir)/common/config/riscv/riscv-hwprobe.def
        $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 86a00df78cf6..a74e99081d35 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -31431,6 +31431,13 @@ Note that @option{-mcpu} does not override 
@option{-march} or @option{-mtune}.
 When @option{-mtune=} is not specified, GCC uses the setting from
 @option{-mcpu}.  The default is @samp{generic} if neither is specified.
 
+@option{-mtune=native} and @option{-mcpu=native} identify the core the
+compiler is running on, subject to the same restrictions and the same
+caveat about unlike cores as @option{-march=native} above.
+@option{-mcpu=native} additionally selects the detected architecture.  A
+core the compiler has no hardware identification for leaves the tuning at
+its default rather than causing an error.
+
 The @samp{size} choice is not intended for use by end-users.  This is used
 when @option{-Os} is specified.  It overrides the instruction cost info
 provided by @option{-mtune=}, but does not override the pipeline info.  This
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_0.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_0.c
index bdac433d3814..7c94332396f1 100644
--- a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_0.c
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_0.c
@@ -6,7 +6,7 @@
 /* { dg-require-effective-target rv64 } */
 /* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_0" } */
 /* { dg-set-compiler-env-var GCC_CPUINFO_CPU "0" } */
-/* { dg-additional-options "-march=native -mabi=lp64d -fverbose-asm" } */
+/* { dg-additional-options "-march=native -mtune=native -mabi=lp64d 
-fverbose-asm" } */
 
 int
 main (void)
@@ -15,3 +15,4 @@ main (void)
 }
 
 /* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_h1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-x100} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_1.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_1.c
index a958e8c541ad..97880d32be32 100644
--- a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_1.c
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_1.c
@@ -5,7 +5,7 @@
 /* { dg-require-effective-target rv64 } */
 /* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_0" } */
 /* { dg-set-compiler-env-var GCC_CPUINFO_CPU "8" } */
-/* { dg-additional-options "-march=native -mabi=lp64d -fverbose-asm" } */
+/* { dg-additional-options "-march=native -mtune=native -mabi=lp64d 
-fverbose-asm" } */
 
 int
 main (void)
@@ -15,3 +15,4 @@ main (void)
 
 /* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_v1p0_} } } */
 /* { dg-final { scan-assembler-not {\.attribute arch, "[^"]*_h1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-a100} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_10.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_10.c
new file mode 100644
index 000000000000..7ab5af2667d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_10.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_1" } */
+/* { dg-set-compiler-env-var GCC_CPUINFO_CPU "0" } */
+/* { dg-additional-options "-march=unset -mcpu=native -mabi=lp64d 
-fverbose-asm" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.attribute arch, 
"rv64i2p1[^"]*_zba1p0_zbb1p0} } } */
+/* { dg-final { scan-assembler-not {znosuchext} } } */
+/* { dg-final { scan-assembler-not {xmadeup} } } */
+/* { dg-final { scan-assembler-not {options passed:[^\n]* -mtune=} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_11.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_11.c
new file mode 100644
index 000000000000..f2f4422453a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_11.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_2" } */
+/* { dg-set-compiler-env-var GCC_CPUINFO_CPU "2" } */
+/* { dg-additional-options "-march=unset -mcpu=native -mabi=lp64d 
-fverbose-asm" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.attribute arch, 
"rv64i2p1[^"]*_zba1p0_zbb1p0"} } } */
+/* { dg-final { scan-assembler-not {\.attribute arch, "[^"]*_v1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=sifive-u74} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_12.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_12.c
new file mode 100644
index 000000000000..5614a2c62c44
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_12.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_3" } */
+/* { dg-set-compiler-env-var GCC_CPUINFO_CPU "0" } */
+/* { dg-additional-options "-march=unset -mcpu=native -mabi=lp64d 
-fverbose-asm" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.attribute arch, 
"rv64i2p1[^"]*_v1p0_[^"]*_zvfh1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-x60} } } 
*/
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_13.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_13.c
new file mode 100644
index 000000000000..fd09000ca85e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_13.c
@@ -0,0 +1,19 @@
+/* As native_cpu_6.c, but asking for both through -mcpu=native.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_4" } */
+/* { dg-set-compiler-env-var GCC_CPUINFO_CPU "31" } */
+/* { dg-additional-options "-march=unset -mcpu=native -mabi=lp64d 
-fverbose-asm" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_zfbfmin1p0_} 
} } */
+/* { dg-final { scan-assembler {\.attribute arch, "[^"]*_zvfbfwma1p0_} } } */
+/* { dg-final { scan-assembler {\.attribute arch, "[^"]*_svade1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=sifive-p870-d} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_2.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_2.c
index adccb7ea7cd0..c3f45f81901a 100644
--- a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_2.c
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_2.c
@@ -3,7 +3,7 @@
 /* { dg-require-effective-target rv64 } */
 /* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_0" } */
 /* { dg-set-compiler-env-var GCC_CPUINFO_CPU "99" } */
-/* { dg-additional-options "-march=native -mabi=lp64d -fverbose-asm" } */
+/* { dg-additional-options "-march=native -mtune=native -mabi=lp64d 
-fverbose-asm" } */
 
 int
 main (void)
@@ -12,3 +12,4 @@ main (void)
 }
 
 /* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_h1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-x100} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_3.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_3.c
index 8fbcb75b1871..04f5e17e41b3 100644
--- a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_3.c
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_3.c
@@ -1,11 +1,13 @@
-/* Testcase with unknown ext in /proc/cpuinfo.  */
+/* Testcase with unknown ext in /proc/cpuinfo.  Its identification
+   registers name no core we know either, which leaves the tuning alone
+   rather than causing an error.  */
 
 /* { dg-do compile } */
 /* { dg-require-effective-target riscv_native_cpu_detect } */
 /* { dg-require-effective-target rv64 } */
 /* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_1" } */
 /* { dg-set-compiler-env-var GCC_CPUINFO_CPU "0" } */
-/* { dg-additional-options "-march=native -mabi=lp64d -fverbose-asm" } */
+/* { dg-additional-options "-march=native -mtune=native -mabi=lp64d 
-fverbose-asm" } */
 
 int
 main (void)
@@ -16,3 +18,4 @@ main (void)
 /* { dg-final { scan-assembler {\.attribute arch, 
"rv64i2p1[^"]*_zba1p0_zbb1p0} } } */
 /* { dg-final { scan-assembler-not {znosuchext} } } */
 /* { dg-final { scan-assembler-not {xmadeup} } } */
+/* { dg-final { scan-assembler-not {options passed:[^\n]* -mtune=} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_4.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_4.c
index 58bb4aeef9fd..0b8dfa90b746 100644
--- a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_4.c
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_4.c
@@ -5,7 +5,7 @@
 /* { dg-require-effective-target rv64 } */
 /* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_2" } */
 /* { dg-set-compiler-env-var GCC_CPUINFO_CPU "2" } */
-/* { dg-additional-options "-march=native -mabi=lp64d -fverbose-asm" } */
+/* { dg-additional-options "-march=native -mtune=native -mabi=lp64d 
-fverbose-asm" } */
 
 int
 main (void)
@@ -15,3 +15,4 @@ main (void)
 
 /* { dg-final { scan-assembler {\.attribute arch, 
"rv64i2p1[^"]*_zba1p0_zbb1p0"} } } */
 /* { dg-final { scan-assembler-not {\.attribute arch, "[^"]*_v1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=sifive-u74} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_5.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_5.c
index 656b44f011e7..0d5b9196f952 100644
--- a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_5.c
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_5.c
@@ -5,7 +5,7 @@
 /* { dg-require-effective-target rv64 } */
 /* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_3" } */
 /* { dg-set-compiler-env-var GCC_CPUINFO_CPU "0" } */
-/* { dg-additional-options "-march=native -mabi=lp64d -fverbose-asm" } */
+/* { dg-additional-options "-march=native -mtune=native -mabi=lp64d 
-fverbose-asm" } */
 
 int
 main (void)
@@ -14,3 +14,4 @@ main (void)
 }
 
 /* { dg-final { scan-assembler {\.attribute arch, 
"rv64i2p1[^"]*_v1p0_[^"]*_zvfh1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-x60} } } 
*/
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_6.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_6.c
index 823fcd79b545..7d840ba5631f 100644
--- a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_6.c
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_6.c
@@ -9,7 +9,7 @@
 /* { dg-require-effective-target rv64 } */
 /* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_4" } */
 /* { dg-set-compiler-env-var GCC_CPUINFO_CPU "31" } */
-/* { dg-additional-options "-march=native -mabi=lp64d -fverbose-asm" } */
+/* { dg-additional-options "-march=native -mtune=native -mabi=lp64d 
-fverbose-asm" } */
 
 int
 main (void)
@@ -20,3 +20,4 @@ main (void)
 /* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_zfbfmin1p0_} 
} } */
 /* { dg-final { scan-assembler {\.attribute arch, "[^"]*_zvfbfwma1p0_} } } */
 /* { dg-final { scan-assembler {\.attribute arch, "[^"]*_svade1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=sifive-p870-d} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_7.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_7.c
new file mode 100644
index 000000000000..080ac2a0f46a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_7.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_0" } */
+/* { dg-set-compiler-env-var GCC_CPUINFO_CPU "0" } */
+/* { dg-additional-options "-march=unset -mcpu=native -mabi=lp64d 
-fverbose-asm" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_h1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-x100} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_8.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_8.c
new file mode 100644
index 000000000000..68259573a5d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_8.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_0" } */
+/* { dg-set-compiler-env-var GCC_CPUINFO_CPU "8" } */
+/* { dg-additional-options "-march=unset -mcpu=native -mabi=lp64d 
-fverbose-asm" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_v1p0_} } } */
+/* { dg-final { scan-assembler-not {\.attribute arch, "[^"]*_h1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-a100} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_9.c 
b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_9.c
new file mode 100644
index 000000000000..abc4c7bdec7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cpunative/native_cpu_9.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-set-compiler-env-var GCC_CPUINFO 
"$srcdir/gcc.target/riscv/cpunative/info_0" } */
+/* { dg-set-compiler-env-var GCC_CPUINFO_CPU "99" } */
+/* { dg-additional-options "-march=unset -mcpu=native -mabi=lp64d 
-fverbose-asm" } */
+
+int
+main (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.attribute arch, "rv64i2p1[^"]*_h1p0_} } } */
+/* { dg-final { scan-assembler {options passed:[^\n]* -mtune=spacemit-x100} } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/march-native-2.c 
b/gcc/testsuite/gcc.target/riscv/march-native-2.c
new file mode 100644
index 000000000000..10367cec55d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/march-native-2.c
@@ -0,0 +1,12 @@
+/* -mtune=native must not be rejected, whether or not the running core is
+   one the compiler knows how to name.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-options "-mtune=native" } */
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/march-native-3.c 
b/gcc/testsuite/gcc.target/riscv/march-native-3.c
new file mode 100644
index 000000000000..dd7eb1669028
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/march-native-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-options "-march=unset -mcpu=native" } */
+
+#ifndef __riscv_arch_test
+#error "-mcpu=native did not produce a usable ISA string"
+#endif
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/march-native-4.c 
b/gcc/testsuite/gcc.target/riscv/march-native-4.c
new file mode 100644
index 000000000000..db91ce561f00
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/march-native-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target riscv_native_cpu_detect } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-options "-mcpu=native -march=rv64gc -mabi=lp64d" } */
+
+#ifdef __riscv_v
+#error "-mcpu=native overrode an explicit -march"
+#endif
+
+int
+main (void)
+{
+  return 0;
+}

Reply via email to