[compiler-rt] [llvm] [RISC-V] Add newer Linux hwprobe extensions detection (PR #192761)
Jiaqi He via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 17 19:07:46 PDT 2026
https://github.com/heturing created https://github.com/llvm/llvm-project/pull/192761
Related to #192317
Add support for newer Linux RISC-V hwprobe extensions in:
- `llvm/lib/TargetParser/Host.cpp`
- `compiler-rt/lib/builtins/cpu_model/riscv.c`
- `llvm/lib/Target/RISCV/RISCVFeatures.td` for the corresponding `RISCVExtensionBitmask`
In particular, this patch adds support for:
- `supm`
- `zicntr`
- `zihpm`
- `zfbfmin`
- `zvfbfmin`
- `zvfbfwma`
- `zicbom`
- `zaamo`
- `zalrsc`
- `zabha`
- `zalasr`
- `zicbop`
- `zilsd`
- `zclsd`
Notes:
- I intentionally left out `zicfilp` for now, since it is currently treated as experimental in LLVM.
- I have also proposed [PR](https://github.com/riscv-non-isa/riscv-c-api-doc/pull/185) for the corresponding extension bitmask assignments in the RISC-V C API repo.
- Testing is still in progress in RISC-V Linux under QEMU.
>From adcbaac7da3f2fe256789e44d8cb424818675214 Mon Sep 17 00:00:00 2001
From: Jiaqi He <heturing at gmail.com>
Date: Fri, 17 Apr 2026 19:26:22 -0600
Subject: [PATCH] [RISC-V] Update linux feature detection
---
compiler-rt/lib/builtins/cpu_model/riscv.c | 52 ++++++++++++++++++++++
llvm/lib/Target/RISCV/RISCVFeatures.td | 36 ++++++++++-----
llvm/lib/TargetParser/Host.cpp | 38 +++++++++++-----
3 files changed, 102 insertions(+), 24 deletions(-)
diff --git a/compiler-rt/lib/builtins/cpu_model/riscv.c b/compiler-rt/lib/builtins/cpu_model/riscv.c
index 1c729c8bd7e05..5abe11ecc0bfb 100644
--- a/compiler-rt/lib/builtins/cpu_model/riscv.c
+++ b/compiler-rt/lib/builtins/cpu_model/riscv.c
@@ -146,6 +146,30 @@ struct {
#define ZIFENCEI_BITMASK (1ULL << 11)
#define ZMMUL_GROUPID 1
#define ZMMUL_BITMASK (1ULL << 12)
+#define SUPM_GROUPID 1
+#define SUPM_BITMASK (1ULL << 14)
+#define ZICNTR_GROUPID 1
+#define ZICNTR_BITMASK (1ULL << 15)
+#define ZIHPM_GROUPID 1
+#define ZIHPM_BITMASK (1ULL << 16)
+#define ZFBFMIN_GROUPID 1
+#define ZFBFMIN_BITMASK (1ULL << 17)
+#define ZVFBFMIN_GROUPID 1
+#define ZVFBFMIN_BITMASK (1ULL << 18)
+#define ZVFBFWMA_GROUPID 1
+#define ZVFBFWMA_BITMASK (1ULL << 19)
+#define ZICBOM_GROUPID 1
+#define ZICBOM_BITMASK (1ULL << 20)
+#define ZAAMO_GROUPID 1
+#define ZAAMO_BITMASK (1ULL << 21)
+#define ZALRSC_GROUPID 1
+#define ZALRSC_BITMASK (1ULL << 22)
+#define ZABHA_GROUPID 1
+#define ZABHA_BITMASK (1ULL << 23)
+#define ZALASR_GROUPID 1
+#define ZALASR_BITMASK (1ULL << 24)
+#define ZICBOP_GROUPID 1
+#define ZICBOP_BITMASK (1ULL << 25)
#if defined(__linux__)
@@ -222,6 +246,20 @@ static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
+#define RISCV_HWPROBE_EXT_SUPM (1ULL << 49)
+#define RISCV_HWPROBE_EXT_ZICNTR (1ULL << 50)
+#define RISCV_HWPROBE_EXT_ZIHPM (1ULL << 51)
+#define RISCV_HWPROBE_EXT_ZFBFMIN (1ULL << 52)
+#define RISCV_HWPROBE_EXT_ZVFBFMIN (1ULL << 53)
+#define RISCV_HWPROBE_EXT_ZVFBFWMA (1ULL << 54)
+#define RISCV_HWPROBE_EXT_ZICBOM (1ULL << 55)
+#define RISCV_HWPROBE_EXT_ZAAMO (1ULL << 56)
+#define RISCV_HWPROBE_EXT_ZALRSC (1ULL << 57)
+#define RISCV_HWPROBE_EXT_ZABHA (1ULL << 58)
+#define RISCV_HWPROBE_EXT_ZALASR (1ULL << 59)
+#define RISCV_HWPROBE_EXT_ZICBOP (1ULL << 60)
+#define RISCV_HWPROBE_EXT_ZILSD (1ULL << 61)
+#define RISCV_HWPROBE_EXT_ZCLSD (1ULL << 62)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0)
@@ -338,6 +376,20 @@ static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) {
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCF);
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCMOP);
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAWRS);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(SUPM);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICNTR);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIHPM);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZFBFMIN);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFBFMIN);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVFBFWMA);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICBOM);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAAMO);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZALRSC);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZABHA);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZALASR);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICBOP);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZILSD);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCLSD);
for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
__riscv_feature_bits.features[i] = features[i];
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 825c78509519d..86b70156078f0 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -88,13 +88,15 @@ def FeatureStdExtZic64b
: RISCVExtension<1, 0, "Cache Block Size Is 64 Bytes">;
def FeatureStdExtZicbom
- : RISCVExtension<1, 0, "Cache-Block Management Instructions">;
+ : RISCVExtension<1, 0, "Cache-Block Management Instructions">,
+ RISCVExtensionBitmask<1, 20>;
def HasStdExtZicbom : Predicate<"Subtarget->hasStdExtZicbom()">,
AssemblerPredicate<(all_of FeatureStdExtZicbom),
"'Zicbom' (Cache-Block Management Instructions)">;
def FeatureStdExtZicbop
- : RISCVExtension<1, 0, "Cache-Block Prefetch Instructions">;
+ : RISCVExtension<1, 0, "Cache-Block Prefetch Instructions">,
+ RISCVExtensionBitmask<1, 25>;
def HasStdExtZicbop : Predicate<"Subtarget->hasStdExtZicbop()">,
AssemblerPredicate<(all_of FeatureStdExtZicbop),
"'Zicbop' (Cache-Block Prefetch Instructions)">;
@@ -131,7 +133,8 @@ def HasStdExtZicsr : Predicate<"Subtarget->hasStdExtZicsr()">,
def FeatureStdExtZicntr
: RISCVExtension<2, 0, "Base Counters and Timers",
- [FeatureStdExtZicsr]>;
+ [FeatureStdExtZicsr]>,
+ RISCVExtensionBitmask<1, 15>;
def FeatureStdExtZicond
: RISCVExtension<1, 0, "Integer Conditional Operations">,
@@ -163,7 +166,8 @@ def HasStdExtZihintntl : Predicate<"Subtarget->hasStdExtZihintntl()">,
def FeatureStdExtZihpm
: RISCVExtension<2, 0, "Hardware Performance Counters",
- [FeatureStdExtZicsr]>;
+ [FeatureStdExtZicsr]>,
+ RISCVExtensionBitmask<1, 16>;
def FeatureStdExtZimop : RISCVExtension<1, 0, "May-Be-Operations">,
RISCVExtensionBitmask<1, 1>;
@@ -219,7 +223,8 @@ def HasStdExtM : Predicate<"Subtarget->hasStdExtM()">,
// Atomic Extensions
def FeatureStdExtZaamo
- : RISCVExtension<1, 0, "Atomic Memory Operations">;
+ : RISCVExtension<1, 0, "Atomic Memory Operations">,
+ RISCVExtensionBitmask<1, 21>;
def HasStdExtZaamo
: Predicate<"Subtarget->hasStdExtZaamo()">,
AssemblerPredicate<(any_of FeatureStdExtZaamo),
@@ -227,7 +232,8 @@ def HasStdExtZaamo
def NoStdExtZaamo : Predicate<"!Subtarget->hasStdExtZaamo()">;
def FeatureStdExtZalrsc
- : RISCVExtension<1, 0, "Load-Reserved/Store-Conditional">;
+ : RISCVExtension<1, 0, "Load-Reserved/Store-Conditional">,
+ RISCVExtensionBitmask<1, 22>;
def HasStdExtZalrsc
: Predicate<"Subtarget->hasStdExtZalrsc()">,
AssemblerPredicate<(any_of FeatureStdExtZalrsc),
@@ -257,7 +263,8 @@ def FeatureStdExtZa128rs
def FeatureStdExtZabha
: RISCVExtension<1, 0, "Byte and Halfword Atomic Memory Operations",
- [FeatureStdExtZaamo]>;
+ [FeatureStdExtZaamo]>,
+ RISCVExtensionBitmask<1, 23>;
def HasStdExtZabha : Predicate<"Subtarget->hasStdExtZabha()">,
AssemblerPredicate<(all_of FeatureStdExtZabha),
"'Zabha' (Byte and Halfword Atomic Memory Operations)">;
@@ -272,7 +279,8 @@ def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">,
def NoStdExtZacas : Predicate<"!Subtarget->hasStdExtZacas()">;
def FeatureStdExtZalasr
- : RISCVExtension<1, 0, "Load-Acquire and Store-Release Instructions">;
+ : RISCVExtension<1, 0, "Load-Acquire and Store-Release Instructions">,
+ RISCVExtensionBitmask<1, 24>;
def HasStdExtZalasr : Predicate<"Subtarget->hasStdExtZalasr()">,
AssemblerPredicate<(all_of FeatureStdExtZalasr),
"'Zalasr' (Load-Acquire and Store-Release Instructions)">;
@@ -330,7 +338,8 @@ def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">,
def NoStdExtZfh : Predicate<"!Subtarget->hasStdExtZfh()">;
def FeatureStdExtZfbfmin
- : RISCVExtension<1, 0, "Scalar BF16 Converts", [FeatureStdExtF]>;
+ : RISCVExtension<1, 0, "Scalar BF16 Converts", [FeatureStdExtF]>,
+ RISCVExtensionBitmask<1, 17>;
def HasStdExtZfbfmin : Predicate<"Subtarget->hasStdExtZfbfmin()">,
AssemblerPredicate<(all_of FeatureStdExtZfbfmin),
"'Zfbfmin' (Scalar BF16 Converts)">;
@@ -695,14 +704,16 @@ def FeatureStdExtZvfbfa
[FeatureStdExtZve32f, FeatureStdExtZfbfmin]>;
def FeatureStdExtZvfbfmin
- : RISCVExtension<1, 0, "Vector BF16 Converts", [FeatureStdExtZve32f]>;
+ : RISCVExtension<1, 0, "Vector BF16 Converts", [FeatureStdExtZve32f]>,
+ RISCVExtensionBitmask<1, 18>;
def HasStdExtZvfbfmin : Predicate<"Subtarget->hasStdExtZvfbfmin()">,
AssemblerPredicate<(all_of FeatureStdExtZvfbfmin),
"'Zvfbfmin' (Vector BF16 Converts)">;
def FeatureStdExtZvfbfwma
: RISCVExtension<1, 0, "Vector BF16 widening mul-add",
- [FeatureStdExtZvfbfmin, FeatureStdExtZfbfmin]>;
+ [FeatureStdExtZvfbfmin, FeatureStdExtZfbfmin]>,
+ RISCVExtensionBitmask<1, 19>;
def HasStdExtZvfbfwma : Predicate<"Subtarget->hasStdExtZvfbfwma()">,
AssemblerPredicate<(all_of FeatureStdExtZvfbfwma),
"'Zvfbfwma' (Vector BF16 widening mul-add)">;
@@ -1096,7 +1107,8 @@ def FeatureStdExtSspm
// environment to control pointer masking.
def FeatureStdExtSupm
: RISCVExtension<1, 0,
- "Indicates User-mode Pointer Masking">;
+ "Indicates User-mode Pointer Masking">,
+ RISCVExtensionBitmask<1, 14>;
def FeatureStdExtSmctr
: RISCVExtension<1, 0,
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index dfe97f178bd46..4b40cc56d5878 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2515,18 +2515,32 @@ StringMap<bool> sys::getHostCPUFeatures() {
Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND
Features["zihintpause"] =
ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE
- Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X
- Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F
- Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X
- Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F
- Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D
- Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP
- Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA
- Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB
- Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD
- Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF
- Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP
- Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS
+ Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X
+ Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F
+ Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X
+ Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F
+ Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D
+ Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP
+ Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA
+ Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB
+ Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD
+ Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF
+ Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP
+ Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS
+ Features["supm"] = ExtMask & (1ULL << 49); // RISCV_HWPROBE_EXT_SUPM
+ Features["zicntr"] = ExtMask & (1ULL << 50); // RISCV_HWPROBE_EXT_ZICNTR
+ Features["zihpm"] = ExtMask & (1ULL << 51); // RISCV_HWPROBE_EXT_ZIHPM
+ Features["zfbfmin"] = ExtMask & (1ULL << 52); // RISCV_HWPROBE_EXT_ZFBFMIN
+ Features["zvfbfmin"] = ExtMask & (1ULL << 53); // RISCV_HWPROBE_EXT_ZVFBFMIN
+ Features["zvfbfwma"] = ExtMask & (1ULL << 54); // RISCV_HWPROBE_EXT_ZVFBFWMA
+ Features["zicbom"] = ExtMask & (1ULL << 55); // RISCV_HWPROBE_EXT_ZICBOM
+ Features["zaamo"] = ExtMask & (1ULL << 56); // RISCV_HWPROBE_EXT_ZAAMO
+ Features["zalrsc"] = ExtMask & (1ULL << 57); // RISCV_HWPROBE_EXT_ZALRSC
+ Features["zabha"] = ExtMask & (1ULL << 58); // RISCV_HWPROBE_EXT_ZABHA
+ Features["zalasr"] = ExtMask & (1ULL << 59); // RISCV_HWPROBE_EXT_ZALASR
+ Features["zicbop"] = ExtMask & (1ULL << 60); // RISCV_HWPROBE_EXT_ZICBOP
+ Features["zilsd"] = ExtMask & (1ULL << 61); // RISCV_HWPROBE_EXT_ZILSD
+ Features["zclsd"] = ExtMask & (1ULL << 62); // RISCV_HWPROBE_EXT_ZCLSD
// Check whether the processor supports fast misaligned scalar memory access.
// NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on
More information about the llvm-commits
mailing list