[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