Skip to content

Commit 16e46e6

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.6-beta.1
2 parents 6721bcf + a2d65ca commit 16e46e6

File tree

10 files changed

+166
-20
lines changed

10 files changed

+166
-20
lines changed

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,10 @@ bool RISCVTargetInfo::validateGlobalRegisterVariable(
508508
}
509509
return false;
510510
}
511+
512+
bool RISCVTargetInfo::validateCpuIs(StringRef CPUName) const {
513+
assert(getTriple().isOSLinux() &&
514+
"__builtin_cpu_is() is only supported for Linux.");
515+
516+
return llvm::RISCV::hasValidCPUModel(CPUName);
517+
}

clang/lib/Basic/Targets/RISCV.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,10 @@ class RISCVTargetInfo : public TargetInfo {
128128
}
129129

130130
bool supportsCpuSupports() const override { return getTriple().isOSLinux(); }
131+
bool supportsCpuIs() const override { return getTriple().isOSLinux(); }
131132
bool supportsCpuInit() const override { return getTriple().isOSLinux(); }
132133
bool validateCpuSupports(StringRef Feature) const override;
134+
bool validateCpuIs(StringRef CPUName) const override;
133135
bool isValidFeatureName(StringRef Name) const override;
134136

135137
bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "llvm/Support/ScopedPrinter.h"
6868
#include "llvm/TargetParser/AArch64TargetParser.h"
6969
#include "llvm/TargetParser/RISCVISAInfo.h"
70+
#include "llvm/TargetParser/RISCVTargetParser.h"
7071
#include "llvm/TargetParser/X86TargetParser.h"
7172
#include <optional>
7273
#include <sstream>
@@ -22505,6 +22506,47 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID,
2250522506
return nullptr;
2250622507
}
2250722508

22509+
Value *CodeGenFunction::EmitRISCVCpuIs(const CallExpr *E) {
22510+
const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
22511+
StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
22512+
return EmitRISCVCpuIs(CPUStr);
22513+
}
22514+
22515+
Value *CodeGenFunction::EmitRISCVCpuIs(StringRef CPUStr) {
22516+
llvm::Type *Int32Ty = Builder.getInt32Ty();
22517+
llvm::Type *Int64Ty = Builder.getInt64Ty();
22518+
llvm::StructType *StructTy = llvm::StructType::get(Int32Ty, Int64Ty, Int64Ty);
22519+
llvm::Constant *RISCVCPUModel =
22520+
CGM.CreateRuntimeVariable(StructTy, "__riscv_cpu_model");
22521+
cast<llvm::GlobalValue>(RISCVCPUModel)->setDSOLocal(true);
22522+
22523+
auto loadRISCVCPUID = [&](unsigned Index) {
22524+
Value *Ptr = Builder.CreateStructGEP(StructTy, RISCVCPUModel, Index);
22525+
Value *CPUID = Builder.CreateAlignedLoad(StructTy->getTypeAtIndex(Index),
22526+
Ptr, llvm::MaybeAlign());
22527+
return CPUID;
22528+
};
22529+
22530+
const llvm::RISCV::CPUModel CPUModel = llvm::RISCV::getCPUModel(CPUStr);
22531+
22532+
// Compare mvendorid.
22533+
Value *VendorID = loadRISCVCPUID(0);
22534+
Value *Result =
22535+
Builder.CreateICmpEQ(VendorID, Builder.getInt32(CPUModel.MVendorID));
22536+
22537+
// Compare marchid.
22538+
Value *ArchID = loadRISCVCPUID(1);
22539+
Result = Builder.CreateAnd(
22540+
Result, Builder.CreateICmpEQ(ArchID, Builder.getInt64(CPUModel.MArchID)));
22541+
22542+
// Compare mimpid.
22543+
Value *ImpID = loadRISCVCPUID(2);
22544+
Result = Builder.CreateAnd(
22545+
Result, Builder.CreateICmpEQ(ImpID, Builder.getInt64(CPUModel.MImpID)));
22546+
22547+
return Result;
22548+
}
22549+
2250822550
Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
2250922551
const CallExpr *E,
2251022552
ReturnValueSlot ReturnValue) {
@@ -22513,6 +22555,8 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
2251322555
return EmitRISCVCpuSupports(E);
2251422556
if (BuiltinID == Builtin::BI__builtin_cpu_init)
2251522557
return EmitRISCVCpuInit();
22558+
if (BuiltinID == Builtin::BI__builtin_cpu_is)
22559+
return EmitRISCVCpuIs(E);
2251622560

2251722561
SmallVector<Value *, 4> Ops;
2251822562
llvm::Type *ResultType = ConvertType(E->getType());

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4730,6 +4730,8 @@ class CodeGenFunction : public CodeGenTypeCache {
47304730
llvm::Value *EmitRISCVCpuSupports(const CallExpr *E);
47314731
llvm::Value *EmitRISCVCpuSupports(ArrayRef<StringRef> FeaturesStrs);
47324732
llvm::Value *EmitRISCVCpuInit();
4733+
llvm::Value *EmitRISCVCpuIs(const CallExpr *E);
4734+
llvm::Value *EmitRISCVCpuIs(StringRef CPUStr);
47334735

47344736
void AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst,
47354737
const CallExpr *E);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
// RUN: %clang_cc1 -triple riscv64-unknown-linux-gnu -disable-O0-optnone -emit-llvm %s -o - \
3+
// RUN: | opt -S -passes=mem2reg | FileCheck %s --check-prefix=CHECK-RV64
4+
5+
// CHECK-RV64-LABEL: define dso_local signext i32 @test_cpu_is_veyron_v1(
6+
// CHECK-RV64-SAME: ) #[[ATTR0:[0-9]+]] {
7+
// CHECK-RV64-NEXT: [[ENTRY:.*:]]
8+
// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i32, ptr @__riscv_cpu_model, align 4
9+
// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 1567
10+
// CHECK-RV64-NEXT: [[TMP2:%.*]] = load i64, ptr getelementptr inbounds nuw ({ i32, i64, i64 }, ptr @__riscv_cpu_model, i32 0, i32 1), align 8
11+
// CHECK-RV64-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], -9223372036854710272
12+
// CHECK-RV64-NEXT: [[TMP4:%.*]] = and i1 [[TMP1]], [[TMP3]]
13+
// CHECK-RV64-NEXT: [[TMP5:%.*]] = load i64, ptr getelementptr inbounds nuw ({ i32, i64, i64 }, ptr @__riscv_cpu_model, i32 0, i32 2), align 8
14+
// CHECK-RV64-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 273
15+
// CHECK-RV64-NEXT: [[TMP7:%.*]] = and i1 [[TMP4]], [[TMP6]]
16+
// CHECK-RV64-NEXT: [[CONV:%.*]] = zext i1 [[TMP7]] to i32
17+
// CHECK-RV64-NEXT: ret i32 [[CONV]]
18+
//
19+
int test_cpu_is_veyron_v1() {
20+
return __builtin_cpu_is("veyron-v1");
21+
}
22+
23+
// CHECK-RV64-LABEL: define dso_local signext i32 @test_cpu_is_spacemit_x60(
24+
// CHECK-RV64-SAME: ) #[[ATTR0]] {
25+
// CHECK-RV64-NEXT: [[ENTRY:.*:]]
26+
// CHECK-RV64-NEXT: [[TMP0:%.*]] = load i32, ptr @__riscv_cpu_model, align 4
27+
// CHECK-RV64-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 1808
28+
// CHECK-RV64-NEXT: [[TMP2:%.*]] = load i64, ptr getelementptr inbounds nuw ({ i32, i64, i64 }, ptr @__riscv_cpu_model, i32 0, i32 1), align 8
29+
// CHECK-RV64-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], -9223372035378380799
30+
// CHECK-RV64-NEXT: [[TMP4:%.*]] = and i1 [[TMP1]], [[TMP3]]
31+
// CHECK-RV64-NEXT: [[TMP5:%.*]] = load i64, ptr getelementptr inbounds nuw ({ i32, i64, i64 }, ptr @__riscv_cpu_model, i32 0, i32 2), align 8
32+
// CHECK-RV64-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 1152921505839391232
33+
// CHECK-RV64-NEXT: [[TMP7:%.*]] = and i1 [[TMP4]], [[TMP6]]
34+
// CHECK-RV64-NEXT: [[CONV:%.*]] = zext i1 [[TMP7]] to i32
35+
// CHECK-RV64-NEXT: ret i32 [[CONV]]
36+
//
37+
int test_cpu_is_spacemit_x60() {
38+
return __builtin_cpu_is("spacemit-x60");
39+
}

llvm/include/llvm/TargetParser/RISCVTargetParser.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ struct RISCVExtensionBitmask {
3232
};
3333
} // namespace RISCVExtensionBitmaskTable
3434

35+
struct CPUModel {
36+
uint32_t MVendorID;
37+
uint64_t MArchID;
38+
uint64_t MImpID;
39+
};
40+
41+
struct CPUInfo {
42+
StringLiteral Name;
43+
StringLiteral DefaultMarch;
44+
bool FastScalarUnalignedAccess;
45+
bool FastVectorUnalignedAccess;
46+
CPUModel CPUModel;
47+
bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
48+
};
49+
3550
// We use 64 bits as the known part in the scalable vector types.
3651
static constexpr unsigned RVVBitsPerBlock = 64;
3752

@@ -45,6 +60,8 @@ void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
4560
void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
4661
bool hasFastScalarUnalignedAccess(StringRef CPU);
4762
bool hasFastVectorUnalignedAccess(StringRef CPU);
63+
bool hasValidCPUModel(StringRef CPU);
64+
CPUModel getCPUModel(StringRef CPU);
4865

4966
} // namespace RISCV
5067

llvm/lib/Target/RISCV/RISCVProcessors.td

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class RISCVProcessorModel<string n,
4949
string default_march = "">
5050
: ProcessorModel<n, m, f, tunef> {
5151
string DefaultMarch = default_march;
52+
int MVendorID = 0;
53+
int MArchID = 0;
54+
int MImpID = 0;
5255
}
5356

5457
class RISCVTuneProcessorModel<string n,
@@ -435,7 +438,11 @@ def VENTANA_VEYRON_V1 : RISCVProcessorModel<"veyron-v1",
435438
TuneZExtHFusion,
436439
TuneZExtWFusion,
437440
TuneShiftedZExtWFusion,
438-
TuneLDADDFusion]>;
441+
TuneLDADDFusion]> {
442+
let MVendorID = 0x61f;
443+
let MArchID = 0x8000000000010000;
444+
let MImpID = 0x111;
445+
}
439446

440447
def XIANGSHAN_NANHU : RISCVProcessorModel<"xiangshan-nanhu",
441448
XiangShanNanHuModel,
@@ -481,7 +488,11 @@ def SPACEMIT_X60 : RISCVProcessorModel<"spacemit-x60",
481488
[TuneDLenFactor2,
482489
TuneOptimizedNF2SegmentLoadStore,
483490
TuneOptimizedNF3SegmentLoadStore,
484-
TuneOptimizedNF4SegmentLoadStore]>;
491+
TuneOptimizedNF4SegmentLoadStore]> {
492+
let MVendorID = 0x710;
493+
let MArchID = 0x8000000058000001;
494+
let MImpID = 0x1000000049772200;
495+
}
485496

486497
def RP2350_HAZARD3 : RISCVProcessorModel<"rp2350-hazard3",
487498
NoSchedModel,

llvm/lib/TargetParser/RISCVTargetParser.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,22 @@ namespace RISCV {
2222

2323
enum CPUKind : unsigned {
2424
#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, \
25-
FAST_VECTOR_UNALIGN) \
25+
FAST_VECTOR_UNALIGN, MVENDORID, MARCHID, MIMPID) \
2626
CK_##ENUM,
2727
#define TUNE_PROC(ENUM, NAME) CK_##ENUM,
2828
#include "llvm/TargetParser/RISCVTargetParserDef.inc"
2929
};
3030

31-
struct CPUInfo {
32-
StringLiteral Name;
33-
StringLiteral DefaultMarch;
34-
bool FastScalarUnalignedAccess;
35-
bool FastVectorUnalignedAccess;
36-
bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
37-
};
38-
3931
constexpr CPUInfo RISCVCPUInfo[] = {
4032
#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, \
41-
FAST_VECTOR_UNALIGN) \
42-
{NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, FAST_VECTOR_UNALIGN},
33+
FAST_VECTOR_UNALIGN, MVENDORID, MARCHID, MIMPID) \
34+
{ \
35+
NAME, \
36+
DEFAULT_MARCH, \
37+
FAST_SCALAR_UNALIGN, \
38+
FAST_VECTOR_UNALIGN, \
39+
{MVENDORID, MARCHID, MIMPID}, \
40+
},
4341
#include "llvm/TargetParser/RISCVTargetParserDef.inc"
4442
};
4543

@@ -60,6 +58,19 @@ bool hasFastVectorUnalignedAccess(StringRef CPU) {
6058
return Info && Info->FastVectorUnalignedAccess;
6159
}
6260

61+
bool hasValidCPUModel(StringRef CPU) {
62+
const CPUModel CPUModel = getCPUModel(CPU);
63+
return CPUModel.MVendorID != 0 && CPUModel.MArchID != 0 &&
64+
CPUModel.MImpID != 0;
65+
}
66+
67+
CPUModel getCPUModel(StringRef CPU) {
68+
const CPUInfo *Info = getCPUInfoByName(CPU);
69+
if (!Info)
70+
return {0, 0, 0};
71+
return Info->CPUModel;
72+
}
73+
6374
bool parseCPU(StringRef CPU, bool IsRV64) {
6475
const CPUInfo *Info = getCPUInfoByName(CPU);
6576

llvm/test/TableGen/riscv-target-def.td

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class RISCVProcessorModel<string n,
8181
string default_march = "">
8282
: ProcessorModel<n, m, f, tunef> {
8383
string DefaultMarch = default_march;
84+
int MVendorID = 0;
85+
int MArchID = 0;
86+
int MImpID = 0;
8487
}
8588

8689
class RISCVTuneProcessorModel<string n,
@@ -160,13 +163,13 @@ def ROCKET : RISCVTuneProcessorModel<"rocket",
160163
// CHECK: #endif // GET_SUPPORTED_PROFILES
161164

162165
// CHECK: #ifndef PROC
163-
// CHECK-NEXT: #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, FAST_VECTOR_UNALIGN)
166+
// CHECK-NEXT: #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN, FAST_VECTOR_UNALIGN, MVENDORID, MARCHID, MIMPID)
164167
// CHECK-NEXT: #endif
165168

166-
// CHECK: PROC(GENERIC_RV32, {"generic-rv32"}, {"rv32i2p1"}, 0, 0)
167-
// CHECK-NEXT: PROC(GENERIC_RV64, {"generic-rv64"}, {"rv64i2p1"}, 0, 0)
168-
// CHECK-NEXT: PROC(ROCKET_RV32, {"rocket-rv32"}, {"rv32i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0, 0)
169-
// CHECK-NEXT: PROC(ROCKET_RV64, {"rocket-rv64"}, {"rv64i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0, 0)
169+
// CHECK: PROC(GENERIC_RV32, {"generic-rv32"}, {"rv32i2p1"}, 0, 0, 0x00000000, 0x0000000000000000, 0x0000000000000000)
170+
// CHECK-NEXT: PROC(GENERIC_RV64, {"generic-rv64"}, {"rv64i2p1"}, 0, 0, 0x00000000, 0x0000000000000000, 0x0000000000000000)
171+
// CHECK-NEXT: PROC(ROCKET_RV32, {"rocket-rv32"}, {"rv32i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0, 0, 0x00000000, 0x0000000000000000, 0x0000000000000000)
172+
// CHECK-NEXT: PROC(ROCKET_RV64, {"rocket-rv64"}, {"rv64i2p1_zicsr2p0_zidummy0p1_zifencei2p0"}, 0, 0, 0x00000000, 0x0000000000000000, 0x0000000000000000)
170173

171174
// CHECK: #undef PROC
172175

llvm/utils/TableGen/RISCVTargetDefEmitter.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "llvm/ADT/DenseSet.h"
15+
#include "llvm/Support/Format.h"
1516
#include "llvm/Support/RISCVISAUtils.h"
1617
#include "llvm/TableGen/Record.h"
1718
#include "llvm/TableGen/TableGenBackend.h"
@@ -166,7 +167,7 @@ static void emitRISCVProfiles(const RecordKeeper &Records, raw_ostream &OS) {
166167
static void emitRISCVProcs(const RecordKeeper &RK, raw_ostream &OS) {
167168
OS << "#ifndef PROC\n"
168169
<< "#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_SCALAR_UNALIGN"
169-
<< ", FAST_VECTOR_UNALIGN)\n"
170+
<< ", FAST_VECTOR_UNALIGN, MVENDORID, MARCHID, MIMPID)\n"
170171
<< "#endif\n\n";
171172

172173
// Iterate on all definition records.
@@ -192,8 +193,17 @@ static void emitRISCVProcs(const RecordKeeper &RK, raw_ostream &OS) {
192193
printMArch(OS, Features);
193194
else
194195
OS << MArch;
196+
197+
uint32_t MVendorID = Rec->getValueAsInt("MVendorID");
198+
uint64_t MArchID = Rec->getValueAsInt("MArchID");
199+
uint64_t MImpID = Rec->getValueAsInt("MImpID");
200+
195201
OS << "\"}, " << FastScalarUnalignedAccess << ", "
196-
<< FastVectorUnalignedAccess << ")\n";
202+
<< FastVectorUnalignedAccess;
203+
OS << ", " << format_hex(MVendorID, 10);
204+
OS << ", " << format_hex(MArchID, 18);
205+
OS << ", " << format_hex(MImpID, 18);
206+
OS << ")\n";
197207
}
198208
OS << "\n#undef PROC\n";
199209
OS << "\n";

0 commit comments

Comments
 (0)