[clang] [compiler-rt] [llvm] [RISCV] Support new groupid/bitmask for cpu_model (PR #101632)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 2 01:20:14 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Piyou Chen (BeMg)
<details>
<summary>Changes</summary>
1. Add the new extension GroupID/Bitmask with latest hwprobe key.
2. Update the `initRISCVFeature `
3. Update `EmitRISCVCpuSupports` due to not only group0 now.
---
Full diff: https://github.com/llvm/llvm-project/pull/101632.diff
5 Files Affected:
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+2-1)
- (modified) clang/test/CodeGen/builtin-cpu-supports.c (+36-14)
- (modified) compiler-rt/lib/builtins/cpu_model/riscv.c (+49-1)
- (modified) llvm/include/llvm/TargetParser/RISCVISAInfo.h (+5-1)
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+43-26)
``````````diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 0c2ee446aa303..c903064b12cba 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -14391,9 +14391,10 @@ Value *CodeGenFunction::EmitRISCVCpuSupports(const CallExpr *E) {
};
int BitPos = RISCVISAInfo::getRISCVFeaturesBitPosition(FeatureStr);
+ int GroupID = RISCVISAInfo::getRISCVFeaturesGroupID(FeatureStr);
assert(BitPos != -1 && "validation should have rejected this feature");
Value *MaskV = Builder.getInt64(1ULL << BitPos);
- Value *Bitset = Builder.CreateAnd(LoadFeatureBit(0), MaskV);
+ Value *Bitset = Builder.CreateAnd(LoadFeatureBit(GroupID), MaskV);
return Builder.CreateICmpEQ(Bitset, MaskV);
}
diff --git a/clang/test/CodeGen/builtin-cpu-supports.c b/clang/test/CodeGen/builtin-cpu-supports.c
index 92c407653e660..461e49d0fc7fa 100644
--- a/clang/test/CodeGen/builtin-cpu-supports.c
+++ b/clang/test/CodeGen/builtin-cpu-supports.c
@@ -270,20 +270,30 @@ int test_ppc(int a) {
// CHECK-RV32-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
// CHECK-RV32-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
// CHECK-RV32-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
-// CHECK-RV32-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
+// CHECK-RV32-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
// CHECK-RV32: if.then3:
// CHECK-RV32-NEXT: store i32 11, ptr [[RETVAL]], align 4
// CHECK-RV32-NEXT: br label [[RETURN]]
+// CHECK-RV32: if.else4:
+// CHECK-RV32-NEXT: [[TMP9:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 1), align 8
+// CHECK-RV32-NEXT: [[TMP10:%.*]] = and i64 [[TMP9]], 8
+// CHECK-RV32-NEXT: [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
+// CHECK-RV32-NEXT: br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
+// CHECK-RV32: if.then5:
+// CHECK-RV32-NEXT: store i32 11, ptr [[RETVAL]], align 4
+// CHECK-RV32-NEXT: br label [[RETURN]]
// CHECK-RV32: if.end:
-// CHECK-RV32-NEXT: br label [[IF_END4:%.*]]
-// CHECK-RV32: if.end4:
-// CHECK-RV32-NEXT: br label [[IF_END5:%.*]]
-// CHECK-RV32: if.end5:
+// CHECK-RV32-NEXT: br label [[IF_END6:%.*]]
+// CHECK-RV32: if.end6:
+// CHECK-RV32-NEXT: br label [[IF_END7:%.*]]
+// CHECK-RV32: if.end7:
+// CHECK-RV32-NEXT: br label [[IF_END8:%.*]]
+// CHECK-RV32: if.end8:
// CHECK-RV32-NEXT: store i32 0, ptr [[RETVAL]], align 4
// CHECK-RV32-NEXT: br label [[RETURN]]
// CHECK-RV32: return:
-// CHECK-RV32-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
-// CHECK-RV32-NEXT: ret i32 [[TMP9]]
+// CHECK-RV32-NEXT: [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
+// CHECK-RV32-NEXT: ret i32 [[TMP12]]
//
// CHECK-RV64-LABEL: define dso_local signext i32 @test_riscv(
// CHECK-RV64-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -311,20 +321,30 @@ int test_ppc(int a) {
// CHECK-RV64-NEXT: [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
// CHECK-RV64-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
// CHECK-RV64-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
-// CHECK-RV64-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
+// CHECK-RV64-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
// CHECK-RV64: if.then3:
// CHECK-RV64-NEXT: store i32 11, ptr [[RETVAL]], align 4
// CHECK-RV64-NEXT: br label [[RETURN]]
+// CHECK-RV64: if.else4:
+// CHECK-RV64-NEXT: [[TMP9:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 1), align 8
+// CHECK-RV64-NEXT: [[TMP10:%.*]] = and i64 [[TMP9]], 8
+// CHECK-RV64-NEXT: [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
+// CHECK-RV64-NEXT: br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
+// CHECK-RV64: if.then5:
+// CHECK-RV64-NEXT: store i32 11, ptr [[RETVAL]], align 4
+// CHECK-RV64-NEXT: br label [[RETURN]]
// CHECK-RV64: if.end:
-// CHECK-RV64-NEXT: br label [[IF_END4:%.*]]
-// CHECK-RV64: if.end4:
-// CHECK-RV64-NEXT: br label [[IF_END5:%.*]]
-// CHECK-RV64: if.end5:
+// CHECK-RV64-NEXT: br label [[IF_END6:%.*]]
+// CHECK-RV64: if.end6:
+// CHECK-RV64-NEXT: br label [[IF_END7:%.*]]
+// CHECK-RV64: if.end7:
+// CHECK-RV64-NEXT: br label [[IF_END8:%.*]]
+// CHECK-RV64: if.end8:
// CHECK-RV64-NEXT: store i32 0, ptr [[RETVAL]], align 4
// CHECK-RV64-NEXT: br label [[RETURN]]
// CHECK-RV64: return:
-// CHECK-RV64-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
-// CHECK-RV64-NEXT: ret i32 [[TMP9]]
+// CHECK-RV64-NEXT: [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
+// CHECK-RV64-NEXT: ret i32 [[TMP12]]
//
int test_riscv(int a) {
__builtin_cpu_init();
@@ -334,6 +354,8 @@ int test_riscv(int a) {
return 7;
else if (__builtin_cpu_supports("v"))
return 11;
+ else if (__builtin_cpu_supports("zcb"))
+ return 11;
return 0;
}
#endif
diff --git a/compiler-rt/lib/builtins/cpu_model/riscv.c b/compiler-rt/lib/builtins/cpu_model/riscv.c
index 92931fae64fbf..0c443025b74c6 100644
--- a/compiler-rt/lib/builtins/cpu_model/riscv.c
+++ b/compiler-rt/lib/builtins/cpu_model/riscv.c
@@ -8,7 +8,7 @@
#include "cpu_model.h"
-#define RISCV_FEATURE_BITS_LENGTH 1
+#define RISCV_FEATURE_BITS_LENGTH 2
struct {
unsigned length;
unsigned long long features[RISCV_FEATURE_BITS_LENGTH];
@@ -105,6 +105,30 @@ struct {
#define ZVKSH_BITMASK (1ULL << 58)
#define ZVKT_GROUPID 0
#define ZVKT_BITMASK (1ULL << 59)
+#define ZVE32X_GROUPID 0
+#define ZVE32X_BITMASK (1ULL << 60)
+#define ZVE32F_GROUPID 0
+#define ZVE32F_BITMASK (1ULL << 61)
+#define ZVE64X_GROUPID 0
+#define ZVE64X_BITMASK (1ULL << 62)
+#define ZVE64F_GROUPID 0
+#define ZVE64F_BITMASK (1ULL << 63)
+#define ZVE64D_GROUPID 1
+#define ZVE64D_BITMASK (1ULL << 0)
+#define ZIMOP_GROUPID 1
+#define ZIMOP_BITMASK (1ULL << 1)
+#define ZCA_GROUPID 1
+#define ZCA_BITMASK (1ULL << 2)
+#define ZCB_GROUPID 1
+#define ZCB_BITMASK (1ULL << 3)
+#define ZCD_GROUPID 1
+#define ZCD_BITMASK (1ULL << 4)
+#define ZCF_GROUPID 1
+#define ZCF_BITMASK (1ULL << 5)
+#define ZCMOP_GROUPID 1
+#define ZCMOP_BITMASK (1ULL << 6)
+#define ZAWRS_GROUPID 1
+#define ZAWRS_BITMASK (1ULL << 7)
#if defined(__linux__)
@@ -169,6 +193,18 @@ static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
#define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
+#define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
+#define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
+#define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
+#define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
+#define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
+#define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
+#define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
+#define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
+#define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
+#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
+#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
+#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0)
@@ -271,6 +307,18 @@ static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) {
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZTSO);
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZACAS);
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICOND);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32X);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32F);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64X);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64F);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64D);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIMOP);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCA);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCB);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCD);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCF);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCMOP);
+ SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAWRS);
for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
__riscv_feature_bits.features[i] = features[i];
diff --git a/llvm/include/llvm/TargetParser/RISCVISAInfo.h b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
index d71ff174bf0d2..2f81307dcfabf 100644
--- a/llvm/include/llvm/TargetParser/RISCVISAInfo.h
+++ b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
@@ -80,10 +80,14 @@ class RISCVISAInfo {
std::set<StringRef> &EnabledFeatureNames,
StringMap<StringRef> &DescMap);
- /// Return the bit position (in group 0) of __riscv_feature_bits. Returns
+ /// Return the bit position of __riscv_feature_bits. Returns
/// -1 if not supported.
static int getRISCVFeaturesBitPosition(StringRef Ext);
+ /// Return the group id of __riscv_feature_bits. Returns
+ /// -1 if not supported.
+ static int getRISCVFeaturesGroupID(StringRef Ext);
+
private:
RISCVISAInfo(unsigned XLen) : XLen(XLen) {}
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 9f650b87f2b39..033bf096625aa 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -1023,40 +1023,57 @@ std::string RISCVISAInfo::getTargetFeatureForExtension(StringRef Ext) {
struct RISCVExtBit {
const StringLiteral ext;
+ uint8_t groupid;
uint8_t bitpos;
};
-/// Maps extensions with assigned bit positions within group 0 of
-/// __riscv_features_bits to their respective bit position. At the
-/// moment all extensions are within group 0.
-constexpr static RISCVExtBit RISCVGroup0BitPositions[] = {
- {"a", 0}, {"c", 2},
- {"d", 3}, {"f", 5},
- {"i", 8}, {"m", 12},
- {"v", 21}, {"zacas", 26},
- {"zba", 27}, {"zbb", 28},
- {"zbc", 29}, {"zbkb", 30},
- {"zbkc", 31}, {"zbkx", 32},
- {"zbs", 33}, {"zfa", 34},
- {"zfh", 35}, {"zfhmin", 36},
- {"zicboz", 37}, {"zicond", 38},
- {"zihintntl", 39}, {"zihintpause", 40},
- {"zknd", 41}, {"zkne", 42},
- {"zknh", 43}, {"zksed", 44},
- {"zksh", 45}, {"zkt", 46},
- {"ztso", 47}, {"zvbb", 48},
- {"zvbc", 49}, {"zvfh", 50},
- {"zvfhmin", 51}, {"zvkb", 52},
- {"zvkg", 53}, {"zvkned", 54},
- {"zvknha", 55}, {"zvknhb", 56},
- {"zvksed", 57}, {"zvksh", 58},
- {"zvkt", 59}};
+constexpr static RISCVExtBit RISCVBitPositions[] = {
+ {"a", 0, 0}, {"c", 0, 2},
+ {"d", 0, 3}, {"f", 0, 5},
+ {"i", 0, 8}, {"m", 0, 12},
+ {"v", 0, 21}, {"zacas", 0, 26},
+ {"zba", 0, 27}, {"zbb", 0, 28},
+ {"zbc", 0, 29}, {"zbkb", 0, 30},
+ {"zbkc", 0, 31}, {"zbkx", 0, 32},
+ {"zbs", 0, 33}, {"zfa", 0, 34},
+ {"zfh", 0, 35}, {"zfhmin", 0, 36},
+ {"zicboz", 0, 37}, {"zicond", 0, 38},
+ {"zihintntl", 0, 39}, {"zihintpause", 0, 40},
+ {"zknd", 0, 41}, {"zkne", 0, 42},
+ {"zknh", 0, 43}, {"zksed", 0, 44},
+ {"zksh", 0, 45}, {"zkt", 0, 46},
+ {"ztso", 0, 47}, {"zvbb", 0, 48},
+ {"zvbc", 0, 49}, {"zvfh", 0, 50},
+ {"zvfhmin", 0, 51}, {"zvkb", 0, 52},
+ {"zvkg", 0, 53}, {"zvkned", 0, 54},
+ {"zvknha", 0, 55}, {"zvknhb", 0, 56},
+ {"zvksed", 0, 57}, {"zvksh", 0, 58},
+ {"zvkt", 0, 59}, {"zve32x", 0, 60},
+ {"zve32f", 0, 61}, {"zve64x", 0, 62},
+ {"zve64x", 0, 63}, {"zve64d", 1, 0},
+ {"zimop", 1, 1}, {"zca", 1, 2},
+ {"zcb", 1, 3}, {"zcd", 1, 4},
+ {"zcf", 1, 5}, {"zcmop", 1, 6},
+ {"zawrs", 1, 7}};
+
int RISCVISAInfo::getRISCVFeaturesBitPosition(StringRef Ext) {
// Note that this code currently accepts mixed case extension names, but
// does not handle extension versions at all. That's probably fine because
// there's only one extension version in the __riscv_feature_bits vector.
- for (auto E : RISCVGroup0BitPositions)
+ for (auto E : RISCVBitPositions)
if (E.ext.equals_insensitive(Ext))
return E.bitpos;
return -1;
}
+
+// TODO: merge getRISCVFeaturesBitPosition and getRISCVFeaturesGroupID into
+// single function.
+int RISCVISAInfo::getRISCVFeaturesGroupID(StringRef Ext) {
+ // Note that this code currently accepts mixed case extension names, but
+ // does not handle extension versions at all. That's probably fine because
+ // there's only one extension version in the __riscv_feature_bits vector.
+ for (auto E : RISCVBitPositions)
+ if (E.ext.equals_insensitive(Ext))
+ return E.groupid;
+ return -1;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/101632
More information about the llvm-commits
mailing list