Skip to content

Commit 82f52d9

Browse files
authored
[RISCV] Support new groupid/bitmask for cpu_model (#101632)
The spec can be found at riscv-non-isa/riscv-c-api-doc#74. 1. Add the new extension GroupID/Bitmask with latest hwprobe key. 2. Update the `initRISCVFeature ` 3. Update `EmitRISCVCpuSupports` due to not only group0 now.
1 parent 6673cf1 commit 82f52d9

File tree

6 files changed

+125
-50
lines changed

6 files changed

+125
-50
lines changed

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,5 +483,5 @@ RISCVTargetInfo::checkCallingConvention(CallingConv CC) const {
483483
bool RISCVTargetInfo::validateCpuSupports(StringRef Feature) const {
484484
// Only allow extensions we have a known bit position for in the
485485
// __riscv_feature_bits structure.
486-
return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitPosition(Feature);
486+
return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
487487
}

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14462,10 +14462,10 @@ Value *CodeGenFunction::EmitRISCVCpuSupports(const CallExpr *E) {
1446214462
return FeaturesBit;
1446314463
};
1446414464

14465-
int BitPos = RISCVISAInfo::getRISCVFeaturesBitPosition(FeatureStr);
14465+
auto [GroupID, BitPos] = RISCVISAInfo::getRISCVFeaturesBitsInfo(FeatureStr);
1446614466
assert(BitPos != -1 && "validation should have rejected this feature");
1446714467
Value *MaskV = Builder.getInt64(1ULL << BitPos);
14468-
Value *Bitset = Builder.CreateAnd(LoadFeatureBit(0), MaskV);
14468+
Value *Bitset = Builder.CreateAnd(LoadFeatureBit(GroupID), MaskV);
1446914469
return Builder.CreateICmpEQ(Bitset, MaskV);
1447014470
}
1447114471

clang/test/CodeGen/builtin-cpu-supports.c

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -270,20 +270,30 @@ int test_ppc(int a) {
270270
// 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
271271
// CHECK-RV32-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
272272
// CHECK-RV32-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
273-
// CHECK-RV32-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
273+
// CHECK-RV32-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
274274
// CHECK-RV32: if.then3:
275275
// CHECK-RV32-NEXT: store i32 11, ptr [[RETVAL]], align 4
276276
// CHECK-RV32-NEXT: br label [[RETURN]]
277+
// CHECK-RV32: if.else4:
278+
// 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
279+
// CHECK-RV32-NEXT: [[TMP10:%.*]] = and i64 [[TMP9]], 8
280+
// CHECK-RV32-NEXT: [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
281+
// CHECK-RV32-NEXT: br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
282+
// CHECK-RV32: if.then5:
283+
// CHECK-RV32-NEXT: store i32 13, ptr [[RETVAL]], align 4
284+
// CHECK-RV32-NEXT: br label [[RETURN]]
277285
// CHECK-RV32: if.end:
278-
// CHECK-RV32-NEXT: br label [[IF_END4:%.*]]
279-
// CHECK-RV32: if.end4:
280-
// CHECK-RV32-NEXT: br label [[IF_END5:%.*]]
281-
// CHECK-RV32: if.end5:
286+
// CHECK-RV32-NEXT: br label [[IF_END6:%.*]]
287+
// CHECK-RV32: if.end6:
288+
// CHECK-RV32-NEXT: br label [[IF_END7:%.*]]
289+
// CHECK-RV32: if.end7:
290+
// CHECK-RV32-NEXT: br label [[IF_END8:%.*]]
291+
// CHECK-RV32: if.end8:
282292
// CHECK-RV32-NEXT: store i32 0, ptr [[RETVAL]], align 4
283293
// CHECK-RV32-NEXT: br label [[RETURN]]
284294
// CHECK-RV32: return:
285-
// CHECK-RV32-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
286-
// CHECK-RV32-NEXT: ret i32 [[TMP9]]
295+
// CHECK-RV32-NEXT: [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
296+
// CHECK-RV32-NEXT: ret i32 [[TMP12]]
287297
//
288298
// CHECK-RV64-LABEL: define dso_local signext i32 @test_riscv(
289299
// CHECK-RV64-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -311,20 +321,30 @@ int test_ppc(int a) {
311321
// 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
312322
// CHECK-RV64-NEXT: [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
313323
// CHECK-RV64-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
314-
// CHECK-RV64-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
324+
// CHECK-RV64-NEXT: br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
315325
// CHECK-RV64: if.then3:
316326
// CHECK-RV64-NEXT: store i32 11, ptr [[RETVAL]], align 4
317327
// CHECK-RV64-NEXT: br label [[RETURN]]
328+
// CHECK-RV64: if.else4:
329+
// 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
330+
// CHECK-RV64-NEXT: [[TMP10:%.*]] = and i64 [[TMP9]], 8
331+
// CHECK-RV64-NEXT: [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
332+
// CHECK-RV64-NEXT: br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
333+
// CHECK-RV64: if.then5:
334+
// CHECK-RV64-NEXT: store i32 13, ptr [[RETVAL]], align 4
335+
// CHECK-RV64-NEXT: br label [[RETURN]]
318336
// CHECK-RV64: if.end:
319-
// CHECK-RV64-NEXT: br label [[IF_END4:%.*]]
320-
// CHECK-RV64: if.end4:
321-
// CHECK-RV64-NEXT: br label [[IF_END5:%.*]]
322-
// CHECK-RV64: if.end5:
337+
// CHECK-RV64-NEXT: br label [[IF_END6:%.*]]
338+
// CHECK-RV64: if.end6:
339+
// CHECK-RV64-NEXT: br label [[IF_END7:%.*]]
340+
// CHECK-RV64: if.end7:
341+
// CHECK-RV64-NEXT: br label [[IF_END8:%.*]]
342+
// CHECK-RV64: if.end8:
323343
// CHECK-RV64-NEXT: store i32 0, ptr [[RETVAL]], align 4
324344
// CHECK-RV64-NEXT: br label [[RETURN]]
325345
// CHECK-RV64: return:
326-
// CHECK-RV64-NEXT: [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
327-
// CHECK-RV64-NEXT: ret i32 [[TMP9]]
346+
// CHECK-RV64-NEXT: [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
347+
// CHECK-RV64-NEXT: ret i32 [[TMP12]]
328348
//
329349
int test_riscv(int a) {
330350
__builtin_cpu_init();
@@ -334,6 +354,8 @@ int test_riscv(int a) {
334354
return 7;
335355
else if (__builtin_cpu_supports("v"))
336356
return 11;
357+
else if (__builtin_cpu_supports("zcb"))
358+
return 13;
337359
return 0;
338360
}
339361
#endif

compiler-rt/lib/builtins/cpu_model/riscv.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#include "cpu_model.h"
1010

11-
#define RISCV_FEATURE_BITS_LENGTH 1
11+
#define RISCV_FEATURE_BITS_LENGTH 2
1212
struct {
1313
unsigned length;
1414
unsigned long long features[RISCV_FEATURE_BITS_LENGTH];
@@ -105,6 +105,30 @@ struct {
105105
#define ZVKSH_BITMASK (1ULL << 58)
106106
#define ZVKT_GROUPID 0
107107
#define ZVKT_BITMASK (1ULL << 59)
108+
#define ZVE32X_GROUPID 0
109+
#define ZVE32X_BITMASK (1ULL << 60)
110+
#define ZVE32F_GROUPID 0
111+
#define ZVE32F_BITMASK (1ULL << 61)
112+
#define ZVE64X_GROUPID 0
113+
#define ZVE64X_BITMASK (1ULL << 62)
114+
#define ZVE64F_GROUPID 0
115+
#define ZVE64F_BITMASK (1ULL << 63)
116+
#define ZVE64D_GROUPID 1
117+
#define ZVE64D_BITMASK (1ULL << 0)
118+
#define ZIMOP_GROUPID 1
119+
#define ZIMOP_BITMASK (1ULL << 1)
120+
#define ZCA_GROUPID 1
121+
#define ZCA_BITMASK (1ULL << 2)
122+
#define ZCB_GROUPID 1
123+
#define ZCB_BITMASK (1ULL << 3)
124+
#define ZCD_GROUPID 1
125+
#define ZCD_BITMASK (1ULL << 4)
126+
#define ZCF_GROUPID 1
127+
#define ZCF_BITMASK (1ULL << 5)
128+
#define ZCMOP_GROUPID 1
129+
#define ZCMOP_BITMASK (1ULL << 6)
130+
#define ZAWRS_GROUPID 1
131+
#define ZAWRS_BITMASK (1ULL << 7)
108132

109133
#if defined(__linux__)
110134

@@ -169,6 +193,18 @@ static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
169193
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
170194
#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
171195
#define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
196+
#define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
197+
#define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
198+
#define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
199+
#define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
200+
#define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
201+
#define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
202+
#define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
203+
#define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
204+
#define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
205+
#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
206+
#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
207+
#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
172208
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
173209
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
174210
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0)
@@ -271,6 +307,18 @@ static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) {
271307
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZTSO);
272308
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZACAS);
273309
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICOND);
310+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32X);
311+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32F);
312+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64X);
313+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64F);
314+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64D);
315+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIMOP);
316+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCA);
317+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCB);
318+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCD);
319+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCF);
320+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCMOP);
321+
SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAWRS);
274322

275323
for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
276324
__riscv_feature_bits.features[i] = features[i];

llvm/include/llvm/TargetParser/RISCVISAInfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ class RISCVISAInfo {
8080
std::set<StringRef> &EnabledFeatureNames,
8181
StringMap<StringRef> &DescMap);
8282

83-
/// Return the bit position (in group 0) of __riscv_feature_bits. Returns
84-
/// -1 if not supported.
85-
static int getRISCVFeaturesBitPosition(StringRef Ext);
83+
/// Return the group id and bit position of __riscv_feature_bits. Returns
84+
/// <-1, -1> if not supported.
85+
static std::pair<int, int> getRISCVFeaturesBitsInfo(StringRef Ext);
8686

8787
private:
8888
RISCVISAInfo(unsigned XLen) : XLen(XLen) {}

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,40 +1023,45 @@ std::string RISCVISAInfo::getTargetFeatureForExtension(StringRef Ext) {
10231023

10241024
struct RISCVExtBit {
10251025
const StringLiteral ext;
1026+
uint8_t groupid;
10261027
uint8_t bitpos;
10271028
};
10281029

1029-
/// Maps extensions with assigned bit positions within group 0 of
1030-
/// __riscv_features_bits to their respective bit position. At the
1031-
/// moment all extensions are within group 0.
1032-
constexpr static RISCVExtBit RISCVGroup0BitPositions[] = {
1033-
{"a", 0}, {"c", 2},
1034-
{"d", 3}, {"f", 5},
1035-
{"i", 8}, {"m", 12},
1036-
{"v", 21}, {"zacas", 26},
1037-
{"zba", 27}, {"zbb", 28},
1038-
{"zbc", 29}, {"zbkb", 30},
1039-
{"zbkc", 31}, {"zbkx", 32},
1040-
{"zbs", 33}, {"zfa", 34},
1041-
{"zfh", 35}, {"zfhmin", 36},
1042-
{"zicboz", 37}, {"zicond", 38},
1043-
{"zihintntl", 39}, {"zihintpause", 40},
1044-
{"zknd", 41}, {"zkne", 42},
1045-
{"zknh", 43}, {"zksed", 44},
1046-
{"zksh", 45}, {"zkt", 46},
1047-
{"ztso", 47}, {"zvbb", 48},
1048-
{"zvbc", 49}, {"zvfh", 50},
1049-
{"zvfhmin", 51}, {"zvkb", 52},
1050-
{"zvkg", 53}, {"zvkned", 54},
1051-
{"zvknha", 55}, {"zvknhb", 56},
1052-
{"zvksed", 57}, {"zvksh", 58},
1053-
{"zvkt", 59}};
1054-
int RISCVISAInfo::getRISCVFeaturesBitPosition(StringRef Ext) {
1030+
constexpr static RISCVExtBit RISCVBitPositions[] = {
1031+
{"a", 0, 0}, {"c", 0, 2},
1032+
{"d", 0, 3}, {"f", 0, 5},
1033+
{"i", 0, 8}, {"m", 0, 12},
1034+
{"v", 0, 21}, {"zacas", 0, 26},
1035+
{"zba", 0, 27}, {"zbb", 0, 28},
1036+
{"zbc", 0, 29}, {"zbkb", 0, 30},
1037+
{"zbkc", 0, 31}, {"zbkx", 0, 32},
1038+
{"zbs", 0, 33}, {"zfa", 0, 34},
1039+
{"zfh", 0, 35}, {"zfhmin", 0, 36},
1040+
{"zicboz", 0, 37}, {"zicond", 0, 38},
1041+
{"zihintntl", 0, 39}, {"zihintpause", 0, 40},
1042+
{"zknd", 0, 41}, {"zkne", 0, 42},
1043+
{"zknh", 0, 43}, {"zksed", 0, 44},
1044+
{"zksh", 0, 45}, {"zkt", 0, 46},
1045+
{"ztso", 0, 47}, {"zvbb", 0, 48},
1046+
{"zvbc", 0, 49}, {"zvfh", 0, 50},
1047+
{"zvfhmin", 0, 51}, {"zvkb", 0, 52},
1048+
{"zvkg", 0, 53}, {"zvkned", 0, 54},
1049+
{"zvknha", 0, 55}, {"zvknhb", 0, 56},
1050+
{"zvksed", 0, 57}, {"zvksh", 0, 58},
1051+
{"zvkt", 0, 59}, {"zve32x", 0, 60},
1052+
{"zve32f", 0, 61}, {"zve64x", 0, 62},
1053+
{"zve64x", 0, 63}, {"zve64d", 1, 0},
1054+
{"zimop", 1, 1}, {"zca", 1, 2},
1055+
{"zcb", 1, 3}, {"zcd", 1, 4},
1056+
{"zcf", 1, 5}, {"zcmop", 1, 6},
1057+
{"zawrs", 1, 7}};
1058+
1059+
std::pair<int, int> RISCVISAInfo::getRISCVFeaturesBitsInfo(StringRef Ext) {
10551060
// Note that this code currently accepts mixed case extension names, but
10561061
// does not handle extension versions at all. That's probably fine because
10571062
// there's only one extension version in the __riscv_feature_bits vector.
1058-
for (auto E : RISCVGroup0BitPositions)
1063+
for (auto E : RISCVBitPositions)
10591064
if (E.ext.equals_insensitive(Ext))
1060-
return E.bitpos;
1061-
return -1;
1065+
return std::make_pair(E.groupid, E.bitpos);
1066+
return std::make_pair(-1, -1);
10621067
}

0 commit comments

Comments
 (0)