[clang] [llvm] [RISCV] Add support for getHostCPUFeatures using hwprobe (PR #94352)

Yingwei Zheng via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 14 21:59:23 PDT 2024


https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/94352

>From ff839bef048a65760f4cd0e9abafe11cfebd9362 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 4 Jun 2024 21:08:27 +0800
Subject: [PATCH 01/20] [RISCV] Add support for getHostCPUFeatures using
 hwprobe

Co-authored-by: Yangyu Chen <cyy at cyyself.name>
---
 llvm/lib/TargetParser/Host.cpp | 68 ++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 68155acd9e5bc..b4a13b38eb380 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1998,6 +1998,74 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
 
   return true;
 }
+#elif defined(__linux__) && defined(__riscv)
+#ifdef __has_include
+#if __has_include(<asm/hwprobe.h>)
+#include <asm/hwprobe.h>
+#endif
+#endif
+bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
+#ifdef RISCV_HWPROBE_KEY_MVENDORID
+  riscv_hwprobe Query[2]{
+      {RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
+      {RISCV_HWPROBE_KEY_CPUPERF_0, 0},
+  };
+  int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query,
+                    /*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0);
+  if (Ret != 0)
+    return false;
+
+  uint64_t ExtMask = Query[0].value;
+  Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD;
+  Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD;
+  Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C;
+  Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V;
+  Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA;
+  Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB;
+  Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS;
+  Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ;
+  Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC;
+  Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB;
+  Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC;
+  Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX;
+  Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND;
+  Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE;
+  Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH;
+  Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED;
+  Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH;
+  Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT;
+  Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB;
+  Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC;
+  Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB;
+  Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG;
+  Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED;
+  Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA;
+  Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB;
+  Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED;
+  Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH;
+  Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT;
+  Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH;
+  Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN;
+  Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL;
+  Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH;
+  Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN;
+  Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA;
+  Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO;
+  Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS;
+  Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND;
+  Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE;
+
+  uint64_t MisalignedMask = Query[1].value;
+  if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) {
+    Features["unaligned-scalar-mem"] = true;
+    Features["unaligned-vector-mem"] = true;
+  }
+
+  return true;
+#else
+  return false;
+#endif
+}
 #else
 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
 #endif

>From a2fa6e3d64d3a1e2a8e3a7af91068bdb1fda28b1 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 4 Jun 2024 22:10:55 +0800
Subject: [PATCH 02/20] [RISCV] Address review comments.

---
 llvm/lib/TargetParser/Host.cpp | 112 +++++++++++++++------------------
 1 file changed, 52 insertions(+), 60 deletions(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index b4a13b38eb380..ec275c0a7fded 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1999,72 +1999,64 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   return true;
 }
 #elif defined(__linux__) && defined(__riscv)
-#ifdef __has_include
-#if __has_include(<asm/hwprobe.h>)
-#include <asm/hwprobe.h>
-#endif
-#endif
+// struct riscv_hwprobe
+struct RISCVHwProbe {
+  int64_t Key;
+  uint64_t Value;
+};
 bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
-#ifdef RISCV_HWPROBE_KEY_MVENDORID
-  riscv_hwprobe Query[2]{
-      {RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
-      {RISCV_HWPROBE_KEY_CPUPERF_0, 0},
-  };
-  int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/&Query,
-                    /*pair_count=*/1, /*cpu_count=*/0, /*cpus=*/0, /*flags=*/0);
+  RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}};
+  int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
+                    /*pair_count=*/std::size(Query), /*cpu_count=*/0,
+                    /*cpus=*/0, /*flags=*/0);
   if (Ret != 0)
     return false;
 
-  uint64_t ExtMask = Query[0].value;
-  Features["f"] = ExtMask & RISCV_HWPROBE_IMA_FD;
-  Features["d"] = ExtMask & RISCV_HWPROBE_IMA_FD;
-  Features["c"] = ExtMask & RISCV_HWPROBE_IMA_C;
-  Features["v"] = ExtMask & RISCV_HWPROBE_IMA_V;
-  Features["zba"] = ExtMask & RISCV_HWPROBE_IMA_ZBA;
-  Features["zbb"] = ExtMask & RISCV_HWPROBE_IMA_ZBB;
-  Features["zbs"] = ExtMask & RISCV_HWPROBE_IMA_ZBS;
-  Features["zicboz"] = ExtMask & RISCV_HWPROBE_IMA_ZICBOZ;
-  Features["zbc"] = ExtMask & RISCV_HWPROBE_IMA_ZBC;
-  Features["zbkb"] = ExtMask & RISCV_HWPROBE_IMA_ZBKB;
-  Features["zbkc"] = ExtMask & RISCV_HWPROBE_IMA_ZBKC;
-  Features["zbkx"] = ExtMask & RISCV_HWPROBE_IMA_ZBKX;
-  Features["zknd"] = ExtMask & RISCV_HWPROBE_IMA_ZKND;
-  Features["zkne"] = ExtMask & RISCV_HWPROBE_IMA_ZKNE;
-  Features["zknh"] = ExtMask & RISCV_HWPROBE_IMA_ZKNH;
-  Features["zksed"] = ExtMask & RISCV_HWPROBE_IMA_ZKSED;
-  Features["zksh"] = ExtMask & RISCV_HWPROBE_IMA_ZKSH;
-  Features["zkt"] = ExtMask & RISCV_HWPROBE_IMA_ZKT;
-  Features["zvbb"] = ExtMask & RISCV_HWPROBE_IMA_ZVBB;
-  Features["zvbc"] = ExtMask & RISCV_HWPROBE_IMA_ZVBC;
-  Features["zvkb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKB;
-  Features["zvkg"] = ExtMask & RISCV_HWPROBE_IMA_ZVKG;
-  Features["zvkned"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNED;
-  Features["zvknha"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHA;
-  Features["zvknhb"] = ExtMask & RISCV_HWPROBE_IMA_ZVKNHB;
-  Features["zvksed"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSED;
-  Features["zvksh"] = ExtMask & RISCV_HWPROBE_IMA_ZVKSH;
-  Features["zvkt"] = ExtMask & RISCV_HWPROBE_IMA_ZVKT;
-  Features["zfh"] = ExtMask & RISCV_HWPROBE_IMA_ZFH;
-  Features["zfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZFHMIN;
-  Features["zihintntl"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTNTL;
-  Features["zvfh"] = ExtMask & RISCV_HWPROBE_IMA_ZVFH;
-  Features["zvfhmin"] = ExtMask & RISCV_HWPROBE_IMA_ZVFHMIN;
-  Features["zfa"] = ExtMask & RISCV_HWPROBE_IMA_ZFA;
-  Features["ztso"] = ExtMask & RISCV_HWPROBE_IMA_ZTSO;
-  Features["zacas"] = ExtMask & RISCV_HWPROBE_IMA_ZACAS;
-  Features["zicond"] = ExtMask & RISCV_HWPROBE_IMA_ZICOND;
-  Features["zihintpause"] = ExtMask & RISCV_HWPROBE_IMA_ZIHINTPAUSE;
-
-  uint64_t MisalignedMask = Query[1].value;
-  if (MisalignedMask == RISCV_HWPROBE_MISALIGNED_FAST) {
-    Features["unaligned-scalar-mem"] = true;
-    Features["unaligned-vector-mem"] = true;
-  }
+  uint64_t ExtMask = Query[0].Value;
+  Features["f"] = ExtMask & (1 << 0);           // RISCV_HWPROBE_IMA_FD
+  Features["d"] = ExtMask & (1 << 0);           // RISCV_HWPROBE_IMA_FD
+  Features["c"] = ExtMask & (1 << 1);           // RISCV_HWPROBE_IMA_C
+  Features["v"] = ExtMask & (1 << 2);           // RISCV_HWPROBE_IMA_V
+  Features["zba"] = ExtMask & (1 << 3);         // RISCV_HWPROBE_EXT_ZBA
+  Features["zbb"] = ExtMask & (1 << 4);         // RISCV_HWPROBE_EXT_ZBB
+  Features["zbs"] = ExtMask & (1 << 5);         // RISCV_HWPROBE_EXT_ZBS
+  Features["zicboz"] = ExtMask & (1 << 6);      // RISCV_HWPROBE_EXT_ZICBOZ
+  Features["zbc"] = ExtMask & (1 << 7);         // RISCV_HWPROBE_EXT_ZBC
+  Features["zbkb"] = ExtMask & (1 << 8);        // RISCV_HWPROBE_EXT_ZBKB
+  Features["zbkc"] = ExtMask & (1 << 9);        // RISCV_HWPROBE_EXT_ZBKC
+  Features["zbkx"] = ExtMask & (1 << 10);       // RISCV_HWPROBE_EXT_ZBKX
+  Features["zknd"] = ExtMask & (1 << 11);       // RISCV_HWPROBE_EXT_ZKND
+  Features["zkne"] = ExtMask & (1 << 12);       // RISCV_HWPROBE_EXT_ZKNE
+  Features["zknh"] = ExtMask & (1 << 13);       // RISCV_HWPROBE_EXT_ZKNH
+  Features["zksed"] = ExtMask & (1 << 14);      // RISCV_HWPROBE_EXT_ZKSED
+  Features["zksh"] = ExtMask & (1 << 15);       // RISCV_HWPROBE_EXT_ZKSH
+  Features["zkt"] = ExtMask & (1 << 16);        // RISCV_HWPROBE_EXT_ZKT
+  Features["zvbb"] = ExtMask & (1 << 17);       // RISCV_HWPROBE_EXT_ZVBB
+  Features["zvbc"] = ExtMask & (1 << 18);       // RISCV_HWPROBE_EXT_ZVBC
+  Features["zvkb"] = ExtMask & (1 << 19);       // RISCV_HWPROBE_EXT_ZVKB
+  Features["zvkg"] = ExtMask & (1 << 20);       // RISCV_HWPROBE_EXT_ZVKG
+  Features["zvkned"] = ExtMask & (1 << 21);     // RISCV_HWPROBE_EXT_ZVKNED
+  Features["zvknha"] = ExtMask & (1 << 22);     // RISCV_HWPROBE_EXT_ZVKNHA
+  Features["zvknhb"] = ExtMask & (1 << 23);     // RISCV_HWPROBE_EXT_ZVKNHB
+  Features["zvksed"] = ExtMask & (1 << 24);     // RISCV_HWPROBE_EXT_ZVKSED
+  Features["zvksh"] = ExtMask & (1 << 25);      // RISCV_HWPROBE_EXT_ZVKSH
+  Features["zvkt"] = ExtMask & (1 << 26);       // RISCV_HWPROBE_EXT_ZVKT
+  Features["zfh"] = ExtMask & (1 << 27);        // RISCV_HWPROBE_EXT_ZFH
+  Features["zfhmin"] = ExtMask & (1 << 28);     // RISCV_HWPROBE_EXT_ZFHMIN
+  Features["zihintntl"] = ExtMask & (1 << 29);  // RISCV_HWPROBE_EXT_ZIHINTNTL
+  Features["zvfh"] = ExtMask & (1 << 30);       // RISCV_HWPROBE_EXT_ZVFH
+  Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
+  Features["zfa"] = ExtMask & (1ULL << 32);     // RISCV_HWPROBE_EXT_ZFA
+  Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
+  Features["zacas"] = ExtMask & (1ULL << 34);   // RISCV_HWPROBE_EXT_ZACAS
+  Features["zicond"] = ExtMask & (1ULL << 35);  // RISCV_HWPROBE_EXT_ZICOND
+  Features["zihintpause"] =
+      ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
+
+  // TODO: set unaligned-scalar-mem if RISCV_HWPROBE_KEY_MISALIGNED_PERF returns
+  // RISCV_HWPROBE_MISALIGNED_FAST.
 
   return true;
-#else
-  return false;
-#endif
 }
 #else
 bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }

>From f3f61d6a67087d31343a069138f8c07715852df4 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 11 Jun 2024 01:09:15 +0800
Subject: [PATCH 03/20] [RISCV] Check IMA

---
 llvm/lib/TargetParser/Host.cpp | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index ec275c0a7fded..b99e1443ef5e5 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2005,14 +2005,23 @@ struct RISCVHwProbe {
   uint64_t Value;
 };
 bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
-  RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}};
+  RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
+                       {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}};
   int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
                     /*pair_count=*/std::size(Query), /*cpu_count=*/0,
                     /*cpus=*/0, /*flags=*/0);
   if (Ret != 0)
     return false;
 
-  uint64_t ExtMask = Query[0].Value;
+  uint64_t BaseMask = Query[0].Value;
+  // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set.
+  if (BaseMask & 1) {
+    Features["i"] = true;
+    Features["m"] = true;
+    Features["a"] = true;
+  }
+
+  uint64_t ExtMask = Query[1].Value;
   Features["f"] = ExtMask & (1 << 0);           // RISCV_HWPROBE_IMA_FD
   Features["d"] = ExtMask & (1 << 0);           // RISCV_HWPROBE_IMA_FD
   Features["c"] = ExtMask & (1 << 1);           // RISCV_HWPROBE_IMA_C

>From 212ddab917a2f555db42a51b46959c035282c0e8 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 11 Jun 2024 01:10:47 +0800
Subject: [PATCH 04/20] [Clang][RISCV] Add clang -mcpu=native support

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 2e2bce8494672..bf34b6e3f2ea4 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -86,8 +86,14 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   // and other features (ex. mirco architecture feature) from mcpu
   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
     StringRef CPU = A->getValue();
-    if (CPU == "native")
+    if (CPU == "native") {
       CPU = llvm::sys::getHostCPUName();
+      llvm::StringMap<bool> HostFeatures;
+      if (llvm::sys::getHostCPUFeatures(HostFeatures))
+        for (auto &F : HostFeatures)
+          Features.push_back(
+              Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+    }
 
     getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);
   }

>From 8a40b9e9f50feb0fd58623f6cb87996dec490376 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 22 Jun 2024 16:29:07 +0800
Subject: [PATCH 05/20] [RISCV] Fix generic targets

---
 llvm/lib/TargetParser/Host.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index b99e1443ef5e5..c7f3ee387795a 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -448,7 +448,7 @@ StringRef sys::detail::getHostCPUNameForRISCV(StringRef ProcCpuinfoContent) {
   return StringSwitch<const char *>(UArch)
       .Case("sifive,u74-mc", "sifive-u74")
       .Case("sifive,bullet0", "sifive-u74")
-      .Default("generic");
+      .Default("");
 }
 
 StringRef sys::detail::getHostCPUNameForBPF() {
@@ -1571,7 +1571,9 @@ StringRef sys::getHostCPUName() {
 #if defined(__linux__)
   std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
   StringRef Content = P ? P->getBuffer() : "";
-  return detail::getHostCPUNameForRISCV(Content);
+  auto CPUName = detail::getHostCPUNameForRISCV(Content);
+  if (!Name.empty())
+    return Name;
 #else
 #if __riscv_xlen == 64
   return "generic-rv64";

>From 01769601490b184a6cf25afb2b3f891fd275b3e1 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 22 Jun 2024 16:35:14 +0800
Subject: [PATCH 06/20] [RISCV] Fix typo. NFC.

---
 llvm/lib/TargetParser/Host.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index c7f3ee387795a..d5472ad4dadec 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1571,7 +1571,7 @@ StringRef sys::getHostCPUName() {
 #if defined(__linux__)
   std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
   StringRef Content = P ? P->getBuffer() : "";
-  auto CPUName = detail::getHostCPUNameForRISCV(Content);
+  StringRef Name = detail::getHostCPUNameForRISCV(Content);
   if (!Name.empty())
     return Name;
 #else

>From 8c01bddeb45d53069f731118b191e56323373357 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 24 Jun 2024 12:35:03 +0800
Subject: [PATCH 07/20] [RISCV] Fix missing return statement

---
 llvm/lib/TargetParser/Host.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index d5472ad4dadec..93485bf5b077c 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1574,7 +1574,7 @@ StringRef sys::getHostCPUName() {
   StringRef Name = detail::getHostCPUNameForRISCV(Content);
   if (!Name.empty())
     return Name;
-#else
+#endif
 #if __riscv_xlen == 64
   return "generic-rv64";
 #elif __riscv_xlen == 32
@@ -1582,7 +1582,6 @@ StringRef sys::getHostCPUName() {
 #else
 #error "Unhandled value of __riscv_xlen"
 #endif
-#endif
 }
 #elif defined(__sparc__)
 #if defined(__linux__)

>From 753d1af2dbeb201aed97c20976434a6895851a20 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 24 Jun 2024 15:49:23 +0800
Subject: [PATCH 08/20] [RISCV] Mark ztso as experimental

---
 llvm/lib/TargetParser/Host.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 93485bf5b077c..eaa263bef7a00 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2057,7 +2057,8 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   Features["zvfh"] = ExtMask & (1 << 30);       // RISCV_HWPROBE_EXT_ZVFH
   Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
   Features["zfa"] = ExtMask & (1ULL << 32);     // RISCV_HWPROBE_EXT_ZFA
-  Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
+  Features["experimental-ztso"] =
+      ExtMask & (1ULL << 33);                   // RISCV_HWPROBE_EXT_ZTSO
   Features["zacas"] = ExtMask & (1ULL << 34);   // RISCV_HWPROBE_EXT_ZACAS
   Features["zicond"] = ExtMask & (1ULL << 35);  // RISCV_HWPROBE_EXT_ZICOND
   Features["zihintpause"] =

>From 835bd2647b4ae87755b59542b9592f1970834c60 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 24 Jun 2024 15:52:44 +0800
Subject: [PATCH 09/20] Revert "[RISCV] Mark ztso as experimental"

---
 llvm/lib/TargetParser/Host.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index eaa263bef7a00..93485bf5b077c 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2057,8 +2057,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   Features["zvfh"] = ExtMask & (1 << 30);       // RISCV_HWPROBE_EXT_ZVFH
   Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
   Features["zfa"] = ExtMask & (1ULL << 32);     // RISCV_HWPROBE_EXT_ZFA
-  Features["experimental-ztso"] =
-      ExtMask & (1ULL << 33);                   // RISCV_HWPROBE_EXT_ZTSO
+  Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
   Features["zacas"] = ExtMask & (1ULL << 34);   // RISCV_HWPROBE_EXT_ZACAS
   Features["zicond"] = ExtMask & (1ULL << 35);  // RISCV_HWPROBE_EXT_ZICOND
   Features["zihintpause"] =

>From 6c633891a8b21fe71f4c26c35b6d985db1a50ff1 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 24 Jun 2024 20:17:28 +0800
Subject: [PATCH 10/20] [RISCV] Update release notes. NFC.

---
 llvm/docs/ReleaseNotes.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 2abb0fd956b64..95ef6def65c42 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -185,6 +185,7 @@ Changes to the RISC-V Backend
 * Added smcdeleg, ssccfg, smcsrind, and sscsrind extensions to -march.
 * ``-mcpu=syntacore-scr3-rv32`` and ``-mcpu=syntacore-scr3-rv64`` were added.
 * Ztso is no longer experimental.
+* ``-mcpu=native`` now detects available features with hwprobe (RISC-V Hardware Probing Interface) on Linux 6.4 or later.
 
 Changes to the WebAssembly Backend
 ----------------------------------

>From fc8998ff8a01bb9f48d91944fa51955c978ea285 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 24 Jun 2024 23:55:08 +0800
Subject: [PATCH 11/20] [RISCV] Remove ztso support.

---
 llvm/lib/TargetParser/Host.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index d4db0daa94032..a6c848d180b07 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2061,7 +2061,8 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   Features["zvfh"] = ExtMask & (1 << 30);       // RISCV_HWPROBE_EXT_ZVFH
   Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
   Features["zfa"] = ExtMask & (1ULL << 32);     // RISCV_HWPROBE_EXT_ZFA
-  Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
+  // TODO: set ztso when it is no longer experimental.
+  // Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
   Features["zacas"] = ExtMask & (1ULL << 34);   // RISCV_HWPROBE_EXT_ZACAS
   Features["zicond"] = ExtMask & (1ULL << 35);  // RISCV_HWPROBE_EXT_ZICOND
   Features["zihintpause"] =

>From 7563384b8598c6b125a9262877699bd3834549e7 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 27 Jun 2024 19:49:31 +0800
Subject: [PATCH 12/20] [RISCV] Detect target features in `riscv::getRISCVArch`

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 26 +++++++++++++++-------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index ad59238214fc9..c2b44f836b5dc 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -83,14 +83,8 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   // and other features (ex. mirco architecture feature) from mcpu
   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
     StringRef CPU = A->getValue();
-    if (CPU == "native") {
+    if (CPU == "native")
       CPU = llvm::sys::getHostCPUName();
-      llvm::StringMap<bool> HostFeatures;
-      if (llvm::sys::getHostCPUFeatures(HostFeatures))
-        for (auto &F : HostFeatures)
-          Features.push_back(
-              Args.MakeArgString((F.second ? "+" : "-") + F.first()));
-    }
 
     getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);
 
@@ -296,8 +290,24 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
   // 2. Get march (isa string) based on `-mcpu=`
   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
     StringRef CPU = A->getValue();
-    if (CPU == "native")
+    if (CPU == "native") {
       CPU = llvm::sys::getHostCPUName();
+      // If the target cpu is unrecognized, use target features.
+      if (CPU.empty() || CPU.starts_with("generic")) {
+        llvm::StringMap<bool> HostFeatures;
+        if (llvm::sys::getHostCPUFeatures(HostFeatures)) {
+          std::vector<std::string> Features;
+          for (auto &F : HostFeatures)
+            Features.push_back(
+                Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+
+          auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
+              Triple.isRISCV32() ? 32 : 64, Features);
+          if (ParseResult)
+            return (*ParseResult)->toString();
+        }
+      }
+    }
     StringRef MArch = llvm::RISCV::getMArchFromMcpu(CPU);
     // Bypass if target cpu's default march is empty.
     if (MArch != "")

>From 622bd655db4d41998e8d57562598acc5ca4af24e Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 27 Jun 2024 20:48:15 +0800
Subject: [PATCH 13/20] Revert "[RISCV] Detect target features in
 `riscv::getRISCVArch`"

This reverts commit 7563384b8598c6b125a9262877699bd3834549e7.
---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 26 +++++++---------------
 1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index c2b44f836b5dc..ad59238214fc9 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -83,8 +83,14 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   // and other features (ex. mirco architecture feature) from mcpu
   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
     StringRef CPU = A->getValue();
-    if (CPU == "native")
+    if (CPU == "native") {
       CPU = llvm::sys::getHostCPUName();
+      llvm::StringMap<bool> HostFeatures;
+      if (llvm::sys::getHostCPUFeatures(HostFeatures))
+        for (auto &F : HostFeatures)
+          Features.push_back(
+              Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+    }
 
     getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);
 
@@ -290,24 +296,8 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
   // 2. Get march (isa string) based on `-mcpu=`
   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
     StringRef CPU = A->getValue();
-    if (CPU == "native") {
+    if (CPU == "native")
       CPU = llvm::sys::getHostCPUName();
-      // If the target cpu is unrecognized, use target features.
-      if (CPU.empty() || CPU.starts_with("generic")) {
-        llvm::StringMap<bool> HostFeatures;
-        if (llvm::sys::getHostCPUFeatures(HostFeatures)) {
-          std::vector<std::string> Features;
-          for (auto &F : HostFeatures)
-            Features.push_back(
-                Args.MakeArgString((F.second ? "+" : "-") + F.first()));
-
-          auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
-              Triple.isRISCV32() ? 32 : 64, Features);
-          if (ParseResult)
-            return (*ParseResult)->toString();
-        }
-      }
-    }
     StringRef MArch = llvm::RISCV::getMArchFromMcpu(CPU);
     // Bypass if target cpu's default march is empty.
     if (MArch != "")

>From 6be7eea2a193ca3d92141f62286f779124647acd Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 8 Jul 2024 01:16:44 +0800
Subject: [PATCH 14/20] [RISCV][Driver] Remove `Args.MakeArgString`

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index ad59238214fc9..91855a30ac756 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -88,8 +88,7 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
       llvm::StringMap<bool> HostFeatures;
       if (llvm::sys::getHostCPUFeatures(HostFeatures))
         for (auto &F : HostFeatures)
-          Features.push_back(
-              Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+          Features.push_back(((F.second ? "+" : "-") + F.first()).str());
     }
 
     getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);

>From a515f3bbab5104679ce309ece264e71ff7e289aa Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 10 Jul 2024 15:52:39 +0800
Subject: [PATCH 15/20] [RISCV] Format code. NFC.

---
 llvm/lib/TargetParser/Host.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index e2f5b494ffcb3..2d0771bf85bbd 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2061,8 +2061,8 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   Features["zfa"] = ExtMask & (1ULL << 32);     // RISCV_HWPROBE_EXT_ZFA
   // TODO: set ztso when it is no longer experimental.
   // Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
-  Features["zacas"] = ExtMask & (1ULL << 34);   // RISCV_HWPROBE_EXT_ZACAS
-  Features["zicond"] = ExtMask & (1ULL << 35);  // RISCV_HWPROBE_EXT_ZICOND
+  Features["zacas"] = ExtMask & (1ULL << 34);  // RISCV_HWPROBE_EXT_ZACAS
+  Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
   Features["zihintpause"] =
       ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
 

>From ad887bc5a55908a5b7db54aaee1bfc9ecc783b0a Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 10 Jul 2024 16:49:20 +0800
Subject: [PATCH 16/20] Reland `[RISCV] Add support for getHostCPUFeatures
 using hwprobe`

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 24 +++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index da949b8546fa1..139d69752fee5 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -83,13 +83,8 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   // and other features (ex. mirco architecture feature) from mcpu
   if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
     StringRef CPU = A->getValue();
-    if (CPU == "native") {
+    if (CPU == "native")
       CPU = llvm::sys::getHostCPUName();
-      llvm::StringMap<bool> HostFeatures;
-      if (llvm::sys::getHostCPUFeatures(HostFeatures))
-        for (auto &F : HostFeatures)
-          Features.push_back(((F.second ? "+" : "-") + F.first()).str());
-    }
 
     getRISCFeaturesFromMcpu(D, A, Triple, CPU, Features);
 
@@ -295,8 +290,23 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
   // 2. Get march (isa string) based on `-mcpu=`
   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
     StringRef CPU = A->getValue();
-    if (CPU == "native")
+    if (CPU == "native") {
       CPU = llvm::sys::getHostCPUName();
+      // If the target cpu is unrecognized, use target features.
+      if (CPU.empty() || CPU.starts_with("generic")) {
+        llvm::StringMap<bool> HostFeatures;
+        if (llvm::sys::getHostCPUFeatures(HostFeatures)) {
+          std::vector<std::string> Features;
+          for (auto &F : HostFeatures)
+            Features.push_back(((F.second ? "+" : "-") + F.first()).str());
+          auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
+              Triple.isRISCV32() ? 32 : 64, Features);
+          if (ParseResult)
+            return (*ParseResult)->toString();
+        }
+      }
+    }
+
     StringRef MArch = llvm::RISCV::getMArchFromMcpu(CPU);
     // Bypass if target cpu's default march is empty.
     if (MArch != "")

>From 208a172cd50041978917e05a9d223007689966be Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Wed, 10 Jul 2024 16:51:26 +0800
Subject: [PATCH 17/20] [RISCV] Set ztso

---
 llvm/docs/ReleaseNotes.rst     | 2 +-
 llvm/lib/TargetParser/Host.cpp | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 98bf5b72b7cda..c2543dcf4f143 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -189,13 +189,13 @@ Changes to the RISC-V Backend
 * B (the collection of the Zba, Zbb, Zbs extensions) is supported.
 * Added smcdeleg, ssccfg, smcsrind, and sscsrind extensions to -march.
 * ``-mcpu=syntacore-scr3-rv32`` and ``-mcpu=syntacore-scr3-rv64`` were added.
-* ``-mcpu=native`` now detects available features with hwprobe (RISC-V Hardware Probing Interface) on Linux 6.4 or later.
 * The default atomics mapping was changed to emit an additional trailing fence
   for sequentially consistent stores, offering compatibility with a future
   mapping using load-acquire and store-release instructions while remaining
   fully compatible with objects produced prior to this change. The mapping
   (ABI) used is recorded as an ELF attribute.
 * Ztso is no longer experimental.
+* ``-mcpu=native`` now detects available features with hwprobe (RISC-V Hardware Probing Interface) on Linux 6.4 or later.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 2d0771bf85bbd..6e168fb269549 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2059,10 +2059,9 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   Features["zvfh"] = ExtMask & (1 << 30);       // RISCV_HWPROBE_EXT_ZVFH
   Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN
   Features["zfa"] = ExtMask & (1ULL << 32);     // RISCV_HWPROBE_EXT_ZFA
-  // TODO: set ztso when it is no longer experimental.
-  // Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
-  Features["zacas"] = ExtMask & (1ULL << 34);  // RISCV_HWPROBE_EXT_ZACAS
-  Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
+  Features["ztso"] = ExtMask & (1ULL << 33);    // RISCV_HWPROBE_EXT_ZTSO
+  Features["zacas"] = ExtMask & (1ULL << 34);   // RISCV_HWPROBE_EXT_ZACAS
+  Features["zicond"] = ExtMask & (1ULL << 35);  // RISCV_HWPROBE_EXT_ZICOND
   Features["zihintpause"] =
       ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
 

>From adbb036d9a7108e99307c8de1f7e87a8388f2785 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 13 Jul 2024 16:48:57 +0800
Subject: [PATCH 18/20] [RISCV] Fix compilation error

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 17 +++++++----------
 llvm/lib/TargetParser/Host.cpp             |  7 ++++---
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 139d69752fee5..bee312ea5d7de 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -294,16 +294,13 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
       CPU = llvm::sys::getHostCPUName();
       // If the target cpu is unrecognized, use target features.
       if (CPU.empty() || CPU.starts_with("generic")) {
-        llvm::StringMap<bool> HostFeatures;
-        if (llvm::sys::getHostCPUFeatures(HostFeatures)) {
-          std::vector<std::string> Features;
-          for (auto &F : HostFeatures)
-            Features.push_back(((F.second ? "+" : "-") + F.first()).str());
-          auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
-              Triple.isRISCV32() ? 32 : 64, Features);
-          if (ParseResult)
-            return (*ParseResult)->toString();
-        }
+        std::vector<std::string> Features;
+        for (auto &F : llvm::sys::getHostCPUFeatures())
+          Features.push_back(((F.second ? "+" : "-") + F.first()).str());
+        auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
+            Triple.isRISCV32() ? 32 : 64, Features);
+        if (ParseResult)
+          return (*ParseResult)->toString();
       }
     }
 
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 69bb6ed6692a1..82c1731f58f0a 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2013,15 +2013,16 @@ struct RISCVHwProbe {
   int64_t Key;
   uint64_t Value;
 };
-bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
+const StringMap<bool> sys::getHostCPUFeatures() {
   RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
                        {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}};
   int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query,
                     /*pair_count=*/std::size(Query), /*cpu_count=*/0,
                     /*cpus=*/0, /*flags=*/0);
   if (Ret != 0)
-    return false;
+    return {};
 
+  StringMap<bool> Features;
   uint64_t BaseMask = Query[0].Value;
   // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set.
   if (BaseMask & 1) {
@@ -2074,7 +2075,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
   // TODO: set unaligned-scalar-mem if RISCV_HWPROBE_KEY_MISALIGNED_PERF returns
   // RISCV_HWPROBE_MISALIGNED_FAST.
 
-  return true;
+  return Features;
 }
 #else
 const StringMap<bool> sys::getHostCPUFeatures() { return {}; }

>From 6b6fd88a71ba3d52c9ece87bac09f467d3b9c970 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 13 Jul 2024 17:04:45 +0800
Subject: [PATCH 19/20] [RISCV] Fallback when hwprobe is unavailable

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index bee312ea5d7de..829d8f8729e23 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -294,13 +294,17 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
       CPU = llvm::sys::getHostCPUName();
       // If the target cpu is unrecognized, use target features.
       if (CPU.empty() || CPU.starts_with("generic")) {
-        std::vector<std::string> Features;
-        for (auto &F : llvm::sys::getHostCPUFeatures())
-          Features.push_back(((F.second ? "+" : "-") + F.first()).str());
-        auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
-            Triple.isRISCV32() ? 32 : 64, Features);
-        if (ParseResult)
-          return (*ParseResult)->toString();
+        auto FeatureMap = llvm::sys::getHostCPUFeatures();
+        // hwprobe may be unavailable on older Linux versions.
+        if (!FeatureMap.empty()) {
+          std::vector<std::string> Features;
+          for (auto &F : FeatureMap)
+            Features.push_back(((F.second ? "+" : "-") + F.first()).str());
+          auto ParseResult = llvm::RISCVISAInfo::parseFeatures(
+              Triple.isRISCV32() ? 32 : 64, Features);
+          if (ParseResult)
+            return (*ParseResult)->toString();
+        }
       }
     }
 

>From 558bc0ccfe0e7013a793664733ee7cd60dbc7a58 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 15 Jul 2024 12:58:48 +0800
Subject: [PATCH 20/20] [RISCV][Clang] Address review comments.

---
 clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
index 829d8f8729e23..584fe94b0ce95 100644
--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -293,7 +293,7 @@ std::string riscv::getRISCVArch(const llvm::opt::ArgList &Args,
     if (CPU == "native") {
       CPU = llvm::sys::getHostCPUName();
       // If the target cpu is unrecognized, use target features.
-      if (CPU.empty() || CPU.starts_with("generic")) {
+      if (CPU.starts_with("generic")) {
         auto FeatureMap = llvm::sys::getHostCPUFeatures();
         // hwprobe may be unavailable on older Linux versions.
         if (!FeatureMap.empty()) {



More information about the cfe-commits mailing list