Skip to content

Commit c795db9

Browse files
authored
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
1 parent e8fce05 commit c795db9

File tree

8 files changed

+159
-5
lines changed

8 files changed

+159
-5
lines changed

lib/SPIRV/SPIRVReader.cpp

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

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

lib/SPIRV/SPIRVWriter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5329,6 +5329,12 @@ SPIRVValue *LLVMToSPIRVBase::transDirectCallInst(CallInst *CI,
53295329
BM->addExtension(
53305330
ExtensionID::SPV_EXT_relaxed_printf_string_address_space);
53315331
}
5332+
} else if (DemangledName.find("__spirv_ocl_prefetch") != StringRef::npos) {
5333+
if (BM->isAllowedToUseExtension(ExtensionID::SPV_KHR_untyped_pointers)) {
5334+
return BM->addUntypedPrefetchKHRInst(
5335+
transScavengedType(CI),
5336+
BM->getIds(transValue(getArguments(CI), BB)), BB);
5337+
}
53325338
}
53335339

53345340
return addDecorations(

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4225,5 +4225,101 @@ _SPIRV_OP(ConvertHandleToSamplerINTEL)
42254225
_SPIRV_OP(ConvertHandleToSampledImageINTEL)
42264226
#undef _SPIRV_OP
42274227

4228+
class SPIRVUntypedPrefetchKHR : public SPIRVInstruction {
4229+
public:
4230+
static const Op OC = OpUntypedPrefetchKHR;
4231+
static const SPIRVWord FixedWordCount = 3;
4232+
4233+
SPIRVUntypedPrefetchKHR(SPIRVType *Ty, std::vector<SPIRVWord> &TheArgs,
4234+
SPIRVBasicBlock *BB)
4235+
: SPIRVInstruction(FixedWordCount, OC, BB) {
4236+
setHasNoId();
4237+
setHasNoType();
4238+
PtrTy = TheArgs[0];
4239+
NumBytes = TheArgs[1];
4240+
if (TheArgs.size() > 2)
4241+
RW.push_back(TheArgs[2]);
4242+
if (TheArgs.size() > 3)
4243+
Locality.push_back(TheArgs[3]);
4244+
if (TheArgs.size() > 4)
4245+
CacheTy.push_back(TheArgs[4]);
4246+
assert(BB && "Invalid BB");
4247+
validate();
4248+
}
4249+
4250+
SPIRVUntypedPrefetchKHR() : SPIRVInstruction(OC) {
4251+
setHasNoId();
4252+
setHasNoType();
4253+
}
4254+
4255+
void validate() const override {
4256+
SPIRVInstruction::validate();
4257+
SPIRVErrorLog &SPVErrLog = this->getModule()->getErrorLog();
4258+
std::string InstName = "OpUntypedPrefetchKHR";
4259+
SPVErrLog.checkError(getValueType(PtrTy)->isTypePointer(),
4260+
SPIRVEC_InvalidInstruction,
4261+
InstName + "\nFirst argument must be a pointer\n");
4262+
SPVErrLog.checkError(
4263+
getValueType(PtrTy)->getPointerStorageClass() ==
4264+
StorageClassCrossWorkgroup,
4265+
SPIRVEC_InvalidInstruction,
4266+
InstName + "\nFirst argument must be a pointer in CrossWorkgroup "
4267+
"storage class\n");
4268+
SPVErrLog.checkError(
4269+
getValueType(NumBytes)->isTypeInt(), SPIRVEC_InvalidInstruction,
4270+
InstName + "\nSecond argument (Num Bytes) must be an integer\n");
4271+
SPVErrLog.checkError(
4272+
RW.empty() || (RW.size() == 1 && getValueType(RW[0])->isTypeInt()),
4273+
SPIRVEC_InvalidInstruction,
4274+
InstName + "\nThird argument (RW) must be an integer\n");
4275+
SPVErrLog.checkError(
4276+
Locality.empty() ||
4277+
(Locality.size() == 1 && getValueType(Locality[0])->isTypeInt()),
4278+
SPIRVEC_InvalidInstruction,
4279+
InstName + "\nFourth argument (Locality) must be an integer\n");
4280+
SPVErrLog.checkError(
4281+
CacheTy.empty() ||
4282+
(CacheTy.size() == 1 && getValueType(CacheTy[0])->isTypeInt()),
4283+
SPIRVEC_InvalidInstruction,
4284+
InstName + "\nFifth argument (Cache Type) must be an integer\n");
4285+
}
4286+
4287+
void setWordCount(SPIRVWord TheWordCount) override {
4288+
SPIRVEntry::setWordCount(TheWordCount);
4289+
if (TheWordCount > 3)
4290+
RW.resize(1);
4291+
if (TheWordCount > 4)
4292+
Locality.resize(1);
4293+
if (TheWordCount > 5)
4294+
CacheTy.resize(1);
4295+
}
4296+
const std::vector<SPIRVWord> getArguments() const {
4297+
std::vector<SPIRVWord> Args;
4298+
Args.push_back(PtrTy);
4299+
Args.push_back(NumBytes);
4300+
if (!RW.empty())
4301+
Args.push_back(RW[0]);
4302+
if (!Locality.empty())
4303+
Args.push_back(Locality[0]);
4304+
if (!CacheTy.empty())
4305+
Args.push_back(CacheTy[0]);
4306+
return Args;
4307+
}
4308+
4309+
SPIRVCapVec getRequiredCapability() const override {
4310+
return getVec(CapabilityUntypedPointersKHR);
4311+
}
4312+
std::optional<ExtensionID> getRequiredExtension() const override {
4313+
return ExtensionID::SPV_KHR_untyped_pointers;
4314+
}
4315+
_SPIRV_DEF_ENCDEC5(PtrTy, NumBytes, RW, Locality, CacheTy)
4316+
protected:
4317+
SPIRVId PtrTy;
4318+
SPIRVId NumBytes;
4319+
std::vector<SPIRVId> RW;
4320+
std::vector<SPIRVId> Locality;
4321+
std::vector<SPIRVId> CacheTy;
4322+
};
4323+
42284324
} // namespace SPIRV
42294325
#endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H

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>

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

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)

spirv-headers-tag.conf

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

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)