Skip to content

Commit 9b50b27

Browse files
vmaksimojsji
authored andcommitted
SPV_KHR_untyped_pointers - implement OpUntypedPrefetchKHR (#2752)
When the extension is enabled, we should replace prefetch OpenCL ExtInst with the OpUntypedPrefetchKHR instruction. Spec: https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_untyped_pointers.html Original commit: KhronosGroup/SPIRV-LLVM-Translator@c795db9a90b86f0
1 parent 38c9811 commit 9b50b27

File tree

8 files changed

+159
-5
lines changed

8 files changed

+159
-5
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,6 +2477,36 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
24772477
BV, Builder.CreateIntrinsic(Intrinsic::expect, RetTy, {Val, ExpVal}));
24782478
}
24792479

2480+
case OpUntypedPrefetchKHR: {
2481+
// Do the same as transOCLBuiltinFromExtInst() but for OpUntypedPrefetchKHR.
2482+
auto *BC = static_cast<SPIRVUntypedPrefetchKHR *>(BV);
2483+
2484+
std::vector<Type *> ArgTypes =
2485+
transTypeVector(BC->getValueTypes(BC->getArguments()), true);
2486+
Type *RetTy = Type::getVoidTy(*Context);
2487+
2488+
std::string MangledName =
2489+
getSPIRVFriendlyIRFunctionName(OpenCLLIB::Prefetch, ArgTypes, RetTy);
2490+
opaquifyTypedPointers(ArgTypes);
2491+
2492+
FunctionType *FT = FunctionType::get(RetTy, ArgTypes, false);
2493+
Function *F = M->getFunction(MangledName);
2494+
if (!F) {
2495+
F = Function::Create(FT, GlobalValue::ExternalLinkage, MangledName, M);
2496+
F->setCallingConv(CallingConv::SPIR_FUNC);
2497+
if (isFuncNoUnwind())
2498+
F->addFnAttr(Attribute::NoUnwind);
2499+
if (isFuncReadNone(OCLExtOpMap::map(OpenCLLIB::Prefetch)))
2500+
F->setDoesNotAccessMemory();
2501+
}
2502+
2503+
auto Args = transValue(BC->getValues(BC->getArguments()), F, BB);
2504+
CallInst *CI = CallInst::Create(F, Args, BC->getName(), BB);
2505+
setCallingConv(CI);
2506+
addFnAttr(CI, Attribute::NoUnwind);
2507+
2508+
return mapValue(BV, CI);
2509+
}
24802510
case OpExtInst: {
24812511
auto *ExtInst = static_cast<SPIRVExtInst *>(BV);
24822512
switch (ExtInst->getExtSetKind()) {

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5336,6 +5336,12 @@ SPIRVValue *LLVMToSPIRVBase::transDirectCallInst(CallInst *CI,
53365336
BM->addExtension(
53375337
ExtensionID::SPV_EXT_relaxed_printf_string_address_space);
53385338
}
5339+
} else if (DemangledName.find("__spirv_ocl_prefetch") != StringRef::npos) {
5340+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_KHR_untyped_pointers)) {
5341+
return BM->addUntypedPrefetchKHRInst(
5342+
transScavengedType(CI),
5343+
BM->getIds(transValue(getArguments(CI), BB)), BB);
5344+
}
53395345
}
53405346

53415347
return addDecorations(

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4200,5 +4200,101 @@ _SPIRV_OP(ConvertHandleToSamplerINTEL)
42004200
_SPIRV_OP(ConvertHandleToSampledImageINTEL)
42014201
#undef _SPIRV_OP
42024202

4203+
class SPIRVUntypedPrefetchKHR : public SPIRVInstruction {
4204+
public:
4205+
static const Op OC = OpUntypedPrefetchKHR;
4206+
static const SPIRVWord FixedWordCount = 3;
4207+
4208+
SPIRVUntypedPrefetchKHR(SPIRVType *Ty, std::vector<SPIRVWord> &TheArgs,
4209+
SPIRVBasicBlock *BB)
4210+
: SPIRVInstruction(FixedWordCount, OC, BB) {
4211+
setHasNoId();
4212+
setHasNoType();
4213+
PtrTy = TheArgs[0];
4214+
NumBytes = TheArgs[1];
4215+
if (TheArgs.size() > 2)
4216+
RW.push_back(TheArgs[2]);
4217+
if (TheArgs.size() > 3)
4218+
Locality.push_back(TheArgs[3]);
4219+
if (TheArgs.size() > 4)
4220+
CacheTy.push_back(TheArgs[4]);
4221+
assert(BB && "Invalid BB");
4222+
validate();
4223+
}
4224+
4225+
SPIRVUntypedPrefetchKHR() : SPIRVInstruction(OC) {
4226+
setHasNoId();
4227+
setHasNoType();
4228+
}
4229+
4230+
void validate() const override {
4231+
SPIRVInstruction::validate();
4232+
SPIRVErrorLog &SPVErrLog = this->getModule()->getErrorLog();
4233+
std::string InstName = "OpUntypedPrefetchKHR";
4234+
SPVErrLog.checkError(getValueType(PtrTy)->isTypePointer(),
4235+
SPIRVEC_InvalidInstruction,
4236+
InstName + "\nFirst argument must be a pointer\n");
4237+
SPVErrLog.checkError(
4238+
getValueType(PtrTy)->getPointerStorageClass() ==
4239+
StorageClassCrossWorkgroup,
4240+
SPIRVEC_InvalidInstruction,
4241+
InstName + "\nFirst argument must be a pointer in CrossWorkgroup "
4242+
"storage class\n");
4243+
SPVErrLog.checkError(
4244+
getValueType(NumBytes)->isTypeInt(), SPIRVEC_InvalidInstruction,
4245+
InstName + "\nSecond argument (Num Bytes) must be an integer\n");
4246+
SPVErrLog.checkError(
4247+
RW.empty() || (RW.size() == 1 && getValueType(RW[0])->isTypeInt()),
4248+
SPIRVEC_InvalidInstruction,
4249+
InstName + "\nThird argument (RW) must be an integer\n");
4250+
SPVErrLog.checkError(
4251+
Locality.empty() ||
4252+
(Locality.size() == 1 && getValueType(Locality[0])->isTypeInt()),
4253+
SPIRVEC_InvalidInstruction,
4254+
InstName + "\nFourth argument (Locality) must be an integer\n");
4255+
SPVErrLog.checkError(
4256+
CacheTy.empty() ||
4257+
(CacheTy.size() == 1 && getValueType(CacheTy[0])->isTypeInt()),
4258+
SPIRVEC_InvalidInstruction,
4259+
InstName + "\nFifth argument (Cache Type) must be an integer\n");
4260+
}
4261+
4262+
void setWordCount(SPIRVWord TheWordCount) override {
4263+
SPIRVEntry::setWordCount(TheWordCount);
4264+
if (TheWordCount > 3)
4265+
RW.resize(1);
4266+
if (TheWordCount > 4)
4267+
Locality.resize(1);
4268+
if (TheWordCount > 5)
4269+
CacheTy.resize(1);
4270+
}
4271+
const std::vector<SPIRVWord> getArguments() const {
4272+
std::vector<SPIRVWord> Args;
4273+
Args.push_back(PtrTy);
4274+
Args.push_back(NumBytes);
4275+
if (!RW.empty())
4276+
Args.push_back(RW[0]);
4277+
if (!Locality.empty())
4278+
Args.push_back(Locality[0]);
4279+
if (!CacheTy.empty())
4280+
Args.push_back(CacheTy[0]);
4281+
return Args;
4282+
}
4283+
4284+
SPIRVCapVec getRequiredCapability() const override {
4285+
return getVec(CapabilityUntypedPointersKHR);
4286+
}
4287+
std::optional<ExtensionID> getRequiredExtension() const override {
4288+
return ExtensionID::SPV_KHR_untyped_pointers;
4289+
}
4290+
_SPIRV_DEF_ENCDEC5(PtrTy, NumBytes, RW, Locality, CacheTy)
4291+
protected:
4292+
SPIRVId PtrTy;
4293+
SPIRVId NumBytes;
4294+
std::vector<SPIRVId> RW;
4295+
std::vector<SPIRVId> Locality;
4296+
std::vector<SPIRVId> CacheTy;
4297+
};
4298+
42034299
} // namespace SPIRV
42044300
#endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ class SPIRVModuleImpl : public SPIRVModule {
493493
SPIRVInstruction *addExpectKHRInst(SPIRVType *ResultTy, SPIRVValue *Value,
494494
SPIRVValue *ExpectedValue,
495495
SPIRVBasicBlock *BB) override;
496+
SPIRVInstruction *addUntypedPrefetchKHRInst(SPIRVType *Ty,
497+
std::vector<SPIRVWord> Args,
498+
SPIRVBasicBlock *BB) override;
496499

497500
virtual SPIRVId getExtInstSetId(SPIRVExtInstSetKind Kind) const override;
498501

@@ -1832,6 +1835,11 @@ SPIRVInstruction *SPIRVModuleImpl::addExpectKHRInst(SPIRVType *ResultTy,
18321835
BB);
18331836
}
18341837

1838+
SPIRVInstruction *SPIRVModuleImpl::addUntypedPrefetchKHRInst(
1839+
SPIRVType *Ty, std::vector<SPIRVWord> Args, SPIRVBasicBlock *BB) {
1840+
return addInstruction(new SPIRVUntypedPrefetchKHR(Ty, Args, BB), BB);
1841+
}
1842+
18351843
// Create AliasDomainDeclINTEL/AliasScopeDeclINTEL/AliasScopeListDeclINTEL
18361844
// instructions
18371845
template <typename AliasingInstType>

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ class SPIRVModule {
500500
SPIRVValue *Value,
501501
SPIRVValue *ExpectedValue,
502502
SPIRVBasicBlock *BB) = 0;
503+
virtual SPIRVInstruction *
504+
addUntypedPrefetchKHRInst(SPIRVType *Ty, std::vector<SPIRVWord> Args,
505+
SPIRVBasicBlock *BB) = 0;
503506

504507
virtual SPIRVId getExtInstSetId(SPIRVExtInstSetKind Kind) const = 0;
505508

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ _SPIRV_OP(UntypedAccessChainKHR, 4419)
339339
_SPIRV_OP(UntypedInBoundsAccessChainKHR, 4420)
340340
_SPIRV_OP(UntypedPtrAccessChainKHR, 4423)
341341
_SPIRV_OP(UntypedInBoundsPtrAccessChainKHR, 4424)
342+
_SPIRV_OP(UntypedPrefetchKHR, 4426)
342343
_SPIRV_OP(GroupNonUniformRotateKHR, 4431)
343344
_SPIRV_OP(SDotKHR, 4450)
344345
_SPIRV_OP(UDotKHR, 4451)

llvm-spirv/spirv-headers-tag.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
db5a00f8cebe81146cafabf89019674a3c4bf03d
1+
efb6b4099ddb8fa60f62956dee592c4b94ec6a49

llvm-spirv/test/extensions/INTEL/SPV_INTEL_cache_controls/decorate-prefetch-w-cache-controls.ll

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
; RUN: llvm-as %s -o %t.bc
2-
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls -spirv-text %t.bc -o - | FileCheck %s --check-prefix=CHECK-SPIRV
2+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls -spirv-text %t.bc -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-TYPED-PTRS
33

44
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls %t.bc -o %t.spv
5+
; RUN: spirv-val %t.spv
6+
; RUN: llvm-spirv -r %t.spv --spirv-target-env=SPV-IR -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM
7+
8+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls,+SPV_KHR_untyped_pointers -spirv-text %t.bc -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-UNTYPED-PTRS
9+
10+
; RUN: llvm-spirv --spirv-ext=+SPV_INTEL_cache_controls,+SPV_KHR_untyped_pointers %t.bc -o %t.spv
11+
; RUN: spirv-val %t.spv
512
; RUN: llvm-spirv -r %t.spv --spirv-target-env=SPV-IR -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM
613

714
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
@@ -24,9 +31,12 @@ $_ZTSZ4mainEUlvE_ = comdat any
2431
; CHECK-SPIRV: Decorate [[PTR_ID2:.*]] CacheControlLoadINTEL 1 1
2532
; CHECK-SPIRV: Decorate [[PTR_ID3:.*]] CacheControlLoadINTEL 2 3
2633

27-
; CHECK-SPIRV: ExtInst [[#]] [[#]] [[#]] prefetch [[PTR_ID1]] [[#]]
28-
; CHECK-SPIRV: ExtInst [[#]] [[#]] [[#]] prefetch [[PTR_ID2]] [[#]]
29-
; CHECK-SPIRV: ExtInst [[#]] [[#]] [[#]] prefetch [[PTR_ID3]] [[#]]
34+
; CHECK-SPIRV-TYPED-PTRS: ExtInst [[#]] [[#]] [[#]] prefetch [[PTR_ID1]] [[#]]
35+
; CHECK-SPIRV-TYPED-PTRS: ExtInst [[#]] [[#]] [[#]] prefetch [[PTR_ID2]] [[#]]
36+
; CHECK-SPIRV-TYPED-PTRS: ExtInst [[#]] [[#]] [[#]] prefetch [[PTR_ID3]] [[#]]
37+
; CHECK-SPIRV-UNTYPED-PTRS: UntypedPrefetchKHR [[PTR_ID1]] [[#]]
38+
; CHECK-SPIRV-UNTYPED-PTRS: UntypedPrefetchKHR [[PTR_ID2]] [[#]]
39+
; CHECK-SPIRV-UNTYPED-PTRS: UntypedPrefetchKHR [[PTR_ID3]] [[#]]
3040

3141
; Check that the appropriate !spirv.Decorations are preserved after reverse
3242
; translation

0 commit comments

Comments
 (0)