Skip to content

[RISCV] Support new groupid/bitmask for cpu_model #101632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,5 +483,5 @@ RISCVTargetInfo::checkCallingConvention(CallingConv CC) const {
bool RISCVTargetInfo::validateCpuSupports(StringRef Feature) const {
// Only allow extensions we have a known bit position for in the
// __riscv_feature_bits structure.
return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitPosition(Feature);
return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
}
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14390,10 +14390,10 @@ Value *CodeGenFunction::EmitRISCVCpuSupports(const CallExpr *E) {
return FeaturesBit;
};

int BitPos = RISCVISAInfo::getRISCVFeaturesBitPosition(FeatureStr);
auto [GroupID, BitPos] = RISCVISAInfo::getRISCVFeaturesBitsInfo(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);
}

Expand Down
50 changes: 36 additions & 14 deletions clang/test/CodeGen/builtin-cpu-supports.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 13, 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]+]] {
Expand Down Expand Up @@ -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 13, 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();
Expand All @@ -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 13;
return 0;
}
#endif
50 changes: 49 additions & 1 deletion compiler-rt/lib/builtins/cpu_model/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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__)

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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];
Expand Down
6 changes: 3 additions & 3 deletions llvm/include/llvm/TargetParser/RISCVISAInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ class RISCVISAInfo {
std::set<StringRef> &EnabledFeatureNames,
StringMap<StringRef> &DescMap);

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

private:
RISCVISAInfo(unsigned XLen) : XLen(XLen) {}
Expand Down
63 changes: 34 additions & 29 deletions llvm/lib/TargetParser/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,40 +1023,45 @@ 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}};
int RISCVISAInfo::getRISCVFeaturesBitPosition(StringRef Ext) {
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}};

std::pair<int, int> RISCVISAInfo::getRISCVFeaturesBitsInfo(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;
return std::make_pair(E.groupid, E.bitpos);
return std::make_pair(-1, -1);
}
Loading