[llvm] [RISCV] Get host CPU name via hwprobe (PR #142745)
Pengcheng Wang via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 4 20:57:41 PDT 2025
https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/142745
>From 4914cddaae16bb1a64c417acb0bb3abb3b697909 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Wed, 4 Jun 2025 16:58:39 +0800
Subject: [PATCH 1/3] [RISCV] Get host CPU name via hwprobe
We can get the `mvendorid/marchid/mimpid` via hwprobe and then we
can compare these IDs with those defined in processors to find the
CPU name.
With this change, `-mcpu/-mtune=native` can set the proper name.
---
.../llvm/TargetParser/RISCVTargetParser.h | 8 ++++++
llvm/lib/TargetParser/Host.cpp | 26 +++++++++++++++----
llvm/lib/TargetParser/RISCVTargetParser.cpp | 15 ++++++++---
3 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
index a529479b546d9..f94e05ee7d30b 100644
--- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h
+++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h
@@ -28,6 +28,13 @@ struct CPUModel {
uint32_t MVendorID;
uint64_t MArchID;
uint64_t MImpID;
+
+ bool isValid() const { return MVendorID != 0 && MArchID != 0 && MImpID != 0; }
+
+ bool operator==(const CPUModel &Other) const {
+ return MVendorID == Other.MVendorID && MArchID == Other.MArchID &&
+ MImpID == Other.MImpID;
+ }
};
struct CPUInfo {
@@ -55,6 +62,7 @@ bool hasFastScalarUnalignedAccess(StringRef CPU);
bool hasFastVectorUnalignedAccess(StringRef CPU);
bool hasValidCPUModel(StringRef CPU);
CPUModel getCPUModel(StringRef CPU);
+StringRef getCPUNameFromCPUModel(const CPUModel &Model);
} // namespace RISCV
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 14acef116708a..13f029e792c01 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1672,8 +1672,29 @@ StringRef sys::getHostCPUName() {
return "generic";
}
#elif defined(__riscv)
+// struct riscv_hwprobe
+struct RISCVHwProbe {
+ int64_t Key;
+ uint64_t Value;
+};
+
StringRef sys::getHostCPUName() {
#if defined(__linux__)
+ // Try hwprobe way first.
+ RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_MVENDORID=*/0, 0},
+ {/*RISCV_HWPROBE_KEY_MARCHID=*/1, 0},
+ {/*RISCV_HWPROBE_KEY_MIMPID=*/2, 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) {
+ RISCV::CPUModel Model{pairs[0].value, pairs[1].value, pairs[2].value};
+ StringRef Name = RISCV::getCPUNameFromCPUModel(Model);
+ if (!Name.empty())
+ return Name;
+ }
+
+ // Then try the cpuinfo way.
std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
StringRef Content = P ? P->getBuffer() : "";
StringRef Name = detail::getHostCPUNameForRISCV(Content);
@@ -2148,11 +2169,6 @@ const StringMap<bool> sys::getHostCPUFeatures() {
return Features;
}
#elif defined(__linux__) && defined(__riscv)
-// struct riscv_hwprobe
-struct RISCVHwProbe {
- int64_t Key;
- uint64_t Value;
-};
const StringMap<bool> sys::getHostCPUFeatures() {
RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0},
{/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0},
diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp
index 2e5e8f4e50c9c..9957ec0c28d88 100644
--- a/llvm/lib/TargetParser/RISCVTargetParser.cpp
+++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp
@@ -57,10 +57,7 @@ bool hasFastVectorUnalignedAccess(StringRef CPU) {
return Info && Info->FastVectorUnalignedAccess;
}
-bool hasValidCPUModel(StringRef CPU) {
- const CPUModel Model = getCPUModel(CPU);
- return Model.MVendorID != 0 && Model.MArchID != 0 && Model.MImpID != 0;
-}
+bool hasValidCPUModel(StringRef CPU) { return getCPUModel(CPU).isValid(); }
CPUModel getCPUModel(StringRef CPU) {
const CPUInfo *Info = getCPUInfoByName(CPU);
@@ -69,6 +66,16 @@ CPUModel getCPUModel(StringRef CPU) {
return Info->Model;
}
+StringRef getCPUNameFromCPUModel(const CPUModel &Model) {
+ if (!Model.isValid())
+ return "";
+
+ for (auto &C : RISCVCPUInfo)
+ if (C.Model == Model)
+ return C.Name;
+ return "";
+}
+
bool parseCPU(StringRef CPU, bool IsRV64) {
const CPUInfo *Info = getCPUInfoByName(CPU);
>From 632db80936014fdf078691b7db63af8c1f9852a8 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Thu, 5 Jun 2025 11:55:36 +0800
Subject: [PATCH 2/3] Guard struct RISCVHwProbe by __linux__ macro
---
llvm/lib/TargetParser/Host.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index 13f029e792c01..8cb33add5f06f 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1672,11 +1672,13 @@ StringRef sys::getHostCPUName() {
return "generic";
}
#elif defined(__riscv)
+#if defined(__linux__)
// struct riscv_hwprobe
struct RISCVHwProbe {
int64_t Key;
uint64_t Value;
};
+#endif
StringRef sys::getHostCPUName() {
#if defined(__linux__)
>From 09d135e6abdc318b1a6b47da883ef33f0339bd35 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Thu, 5 Jun 2025 11:57:29 +0800
Subject: [PATCH 3/3] fix comment
---
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 8cb33add5f06f..b0d21591aeb05 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -1682,7 +1682,7 @@ struct RISCVHwProbe {
StringRef sys::getHostCPUName() {
#if defined(__linux__)
- // Try hwprobe way first.
+ // Try the hwprobe way first.
RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_MVENDORID=*/0, 0},
{/*RISCV_HWPROBE_KEY_MARCHID=*/1, 0},
{/*RISCV_HWPROBE_KEY_MIMPID=*/2, 0}};
More information about the llvm-commits
mailing list