Skip to content

Commit 11477a5

Browse files
committed
[Backport to 15] Add SPV_INTEL_subgroup_buffer_prefetch extension support (#3690)
1 parent c315768 commit 11477a5

11 files changed

Lines changed: 264 additions & 0 deletions

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ EXT(SPV_INTEL_tensor_float32_rounding)
7171
EXT(SPV_EXT_relaxed_printf_string_address_space)
7272
EXT(SPV_INTEL_fp_max_error)
7373
EXT(SPV_INTEL_cache_controls)
74+
EXT(SPV_INTEL_subgroup_buffer_prefetch)
7475
EXT(SPV_INTEL_maximum_registers)
7576
EXT(SPV_INTEL_bindless_images)
7677
EXT(SPV_INTEL_2d_block_io)

lib/SPIRV/SPIRVUtil.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,6 +2506,12 @@ class SPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo {
25062506
setArgAttr(0, SPIR::ATTR_CONST);
25072507
addUnsignedArg(0);
25082508
break;
2509+
case OpSubgroupBlockPrefetchINTEL:
2510+
setArgAttr(0, SPIR::ATTR_CONST);
2511+
addUnsignedArg(0);
2512+
addUnsignedArg(1);
2513+
addUnsignedArg(2); // optional Memory Operands bitmask
2514+
break;
25092515
case OpAtomicUMax:
25102516
case OpAtomicUMin:
25112517
addUnsignedArg(0);

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4037,6 +4037,44 @@ _SPIRV_OP(ConvertHandleToSamplerINTEL)
40374037
_SPIRV_OP(ConvertHandleToSampledImageINTEL)
40384038
#undef _SPIRV_OP
40394039

4040+
class SPIRVSubgroupBlockPrefetchINTELInst : public SPIRVInstTemplateBase {
4041+
public:
4042+
llvm::Optional<ExtensionID> getRequiredExtension() const override {
4043+
return ExtensionID::SPV_INTEL_subgroup_buffer_prefetch;
4044+
}
4045+
SPIRVCapVec getRequiredCapability() const override {
4046+
return getVec(CapabilitySubgroupBufferPrefetchINTEL);
4047+
}
4048+
// Operand 2, if present, is the Memory Operands bitmask.
4049+
bool isOperandLiteral(unsigned I) const override { return I == 2; }
4050+
4051+
protected:
4052+
void validate() const override {
4053+
SPIRVInstruction::validate();
4054+
if (getValue(Ops[0])->isForward())
4055+
return;
4056+
SPIRVErrorLog &SPVErrLog = getModule()->getErrorLog();
4057+
SPIRVType *PtrType = getValueType(Ops[0]);
4058+
const std::string InstName = "OpSubgroupBlockPrefetchINTEL";
4059+
SPVErrLog.checkError(PtrType->isTypePointer(), SPIRVEC_InvalidInstruction,
4060+
InstName + "\nPtr must be a pointer\n");
4061+
SPVErrLog.checkError(
4062+
PtrType->getPointerStorageClass() == StorageClassCrossWorkgroup,
4063+
SPIRVEC_InvalidInstruction,
4064+
InstName + "\nPtr must be in CrossWorkgroup storage class\n");
4065+
SPVErrLog.checkError(PtrType->getPointerElementType()->isTypeInt(),
4066+
SPIRVEC_InvalidInstruction,
4067+
InstName +
4068+
"\nPtr must point to a scalar integer type\n");
4069+
SPVErrLog.checkError(
4070+
getValueType(Ops[1])->isTypeInt(32), SPIRVEC_InvalidInstruction,
4071+
InstName + "\nNumBytes must be a 32-bit integer scalar\n");
4072+
}
4073+
};
4074+
typedef SPIRVInstTemplate<SPIRVSubgroupBlockPrefetchINTELInst,
4075+
OpSubgroupBlockPrefetchINTEL, false, 3, true>
4076+
SPIRVSubgroupBlockPrefetchINTEL;
4077+
40404078
class SPIRVSubgroup2DBlockIOINTELInst : public SPIRVInstTemplateBase {
40414079
public:
40424080
llvm::Optional<ExtensionID> getRequiredExtension() const override {

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
543543
add(CapabilityBindlessTextureNV, "BindlessTextureNV");
544544
add(CapabilitySubgroupShuffleINTEL, "SubgroupShuffleINTEL");
545545
add(CapabilitySubgroupBufferBlockIOINTEL, "SubgroupBufferBlockIOINTEL");
546+
add(CapabilitySubgroupBufferPrefetchINTEL, "SubgroupBufferPrefetchINTEL");
546547
add(CapabilitySubgroupImageBlockIOINTEL, "SubgroupImageBlockIOINTEL");
547548
add(CapabilitySubgroupImageMediaBlockIOINTEL,
548549
"SubgroupImageMediaBlockIOINTEL");

lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ _SPIRV_OP(SpecConstantCompositeContinuedINTEL, 6092)
565565
_SPIRV_OP(ControlBarrierArriveINTEL, 6142)
566566
_SPIRV_OP(ControlBarrierWaitINTEL, 6143)
567567
_SPIRV_OP(ArithmeticFenceEXT, 6145)
568+
_SPIRV_OP(SubgroupBlockPrefetchINTEL, 6221)
568569
_SPIRV_OP(Subgroup2DBlockLoadINTEL, 6231)
569570
_SPIRV_OP(Subgroup2DBlockLoadTransformINTEL, 6232)
570571
_SPIRV_OP(Subgroup2DBlockLoadTransposeINTEL, 6233)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: not llvm-spirv %s -to-binary -o %t.spv 2>&1 | FileCheck %s
2+
3+
; CHECK: InvalidInstruction: Can't translate llvm instruction:
4+
; CHECK-NEXT: OpSubgroupBlockPrefetchINTEL
5+
; CHECK-NEXT: Ptr must point to a scalar integer type
6+
7+
119734787 65536 393230 11 0
8+
2 Capability Addresses
9+
2 Capability Kernel
10+
2 Capability SubgroupBufferPrefetchINTEL
11+
10 Extension "SPV_INTEL_subgroup_buffer_prefetch"
12+
5 ExtInstImport 1 "OpenCL.std"
13+
3 MemoryModel 2 2
14+
5 EntryPoint 6 7 "test"
15+
3 Source 4 100000
16+
3 TypeFloat 3 32
17+
4 TypeInt 5 32 0
18+
2 TypeVoid 2
19+
4 TypePointer 4 5 3
20+
5 TypeFunction 6 2 4 5
21+
22+
5 Function 2 7 0 6
23+
3 FunctionParameter 4 8
24+
3 FunctionParameter 5 9
25+
26+
2 Label 10
27+
3 SubgroupBlockPrefetchINTEL 8 9
28+
1 Return
29+
30+
1 FunctionEnd
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: not llvm-spirv %s -to-binary -o %t.spv 2>&1 | FileCheck %s
2+
3+
; CHECK: InvalidInstruction: Can't translate llvm instruction:
4+
; CHECK-NEXT: OpSubgroupBlockPrefetchINTEL
5+
; CHECK-NEXT: NumBytes must be a 32-bit integer scalar
6+
7+
119734787 65536 393230 11 0
8+
2 Capability Addresses
9+
2 Capability Kernel
10+
2 Capability Int8
11+
2 Capability Int64
12+
2 Capability SubgroupBufferPrefetchINTEL
13+
10 Extension "SPV_INTEL_subgroup_buffer_prefetch"
14+
5 ExtInstImport 1 "OpenCL.std"
15+
3 MemoryModel 2 2
16+
5 EntryPoint 6 7 "test"
17+
3 Source 4 100000
18+
4 TypeInt 3 8 0
19+
4 TypeInt 5 64 0
20+
2 TypeVoid 2
21+
4 TypePointer 4 5 3
22+
5 TypeFunction 6 2 4 5
23+
24+
5 Function 2 7 0 6
25+
3 FunctionParameter 4 8
26+
3 FunctionParameter 5 9
27+
28+
2 Label 10
29+
3 SubgroupBlockPrefetchINTEL 8 9
30+
1 Return
31+
32+
1 FunctionEnd
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; RUN: not llvm-spirv %s -to-binary -o %t.spv 2>&1 | FileCheck %s
2+
3+
; CHECK: InvalidInstruction: Can't translate llvm instruction:
4+
; CHECK-NEXT: OpSubgroupBlockPrefetchINTEL
5+
; CHECK-NEXT: Ptr must be in CrossWorkgroup storage class
6+
7+
119734787 65536 393230 11 0
8+
2 Capability Addresses
9+
2 Capability Kernel
10+
2 Capability Int8
11+
2 Capability SubgroupBufferPrefetchINTEL
12+
10 Extension "SPV_INTEL_subgroup_buffer_prefetch"
13+
5 ExtInstImport 1 "OpenCL.std"
14+
3 MemoryModel 2 2
15+
5 EntryPoint 6 7 "test"
16+
3 Source 4 100000
17+
4 TypeInt 3 8 0
18+
4 TypeInt 5 32 0
19+
2 TypeVoid 2
20+
4 TypePointer 4 7 3
21+
5 TypeFunction 6 2 4 5
22+
23+
5 Function 2 7 0 6
24+
3 FunctionParameter 4 8
25+
3 FunctionParameter 5 9
26+
27+
2 Label 10
28+
3 SubgroupBlockPrefetchINTEL 8 9
29+
1 Return
30+
31+
1 FunctionEnd
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_subgroup_buffer_prefetch
3+
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv %t.spv --to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
5+
; RUN: llvm-spirv %t.spv -r --spirv-target-env=SPV-IR -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM
6+
7+
; RUN: not llvm-spirv %t.bc -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
8+
9+
; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
10+
; CHECK-ERROR-NEXT: SPV_INTEL_subgroup_buffer_prefetch
11+
12+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
13+
target triple = "spir64-unknown-unknown"
14+
15+
; CHECK-SPIRV-DAG: Capability SubgroupBufferPrefetchINTEL
16+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_subgroup_buffer_prefetch"
17+
; CHECK-SPIRV-DAG: TypeInt [[#Int8Ty:]] 8 0
18+
; CHECK-SPIRV-DAG: TypeInt [[#Int32Ty:]] 32 0
19+
; CHECK-SPIRV-DAG: TypePointer [[#GlbPtrTy:]] 5 [[#Int8Ty]]
20+
21+
; CHECK-SPIRV: FunctionParameter [[#GlbPtrTy]] [[#Ptr:]]
22+
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#NumBytes:]]
23+
; CHECK-SPIRV: SubgroupBlockPrefetchINTEL [[#Ptr]] [[#NumBytes]]
24+
25+
; CHECK-LLVM: call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khj(i8 addrspace(1)* %{{.*}}, i32 %{{.*}})
26+
27+
define spir_kernel void @test(i8 addrspace(1)* %ptr, i32 %num_bytes) {
28+
entry:
29+
call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khj(i8 addrspace(1)* %ptr, i32 %num_bytes)
30+
ret void
31+
}
32+
33+
declare spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khj(i8 addrspace(1)*, i32)
34+
35+
!opencl.spir.version = !{!0}
36+
!spirv.Source = !{!1}
37+
!0 = !{i32 1, i32 0}
38+
!1 = !{i32 4, i32 100000}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_subgroup_buffer_prefetch
3+
; RUN: spirv-val %t.spv
4+
; RUN: llvm-spirv %t.spv --to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
5+
; RUN: llvm-spirv %t.spv -r --spirv-target-env=SPV-IR -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM
6+
7+
; OpSubgroupBlockPrefetchINTEL accepts an optional Memory Operands bitmask
8+
; as a third operand after the required Ptr and NumBytes.
9+
; Test Prefetch with Nontemporal memory operand (0x4).
10+
11+
; CHECK-SPIRV-DAG: Capability SubgroupBufferPrefetchINTEL
12+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_subgroup_buffer_prefetch"
13+
; CHECK-SPIRV-DAG: TypeInt [[#Int8Ty:]] 8 0
14+
; CHECK-SPIRV-DAG: TypeInt [[#Int32Ty:]] 32 0
15+
; CHECK-SPIRV-DAG: TypePointer [[#GlbPtrTy:]] 5 [[#Int8Ty]]
16+
17+
; CHECK-SPIRV: FunctionParameter [[#GlbPtrTy]] [[#Ptr:]]
18+
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#NumBytes:]]
19+
; CHECK-SPIRV: SubgroupBlockPrefetchINTEL [[#Ptr]] [[#NumBytes]] 4
20+
21+
; CHECK-LLVM: call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khjj(i8 addrspace(1)* %{{.*}}, i32 %{{.*}}, i32 4)
22+
23+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
24+
target triple = "spir64-unknown-unknown"
25+
26+
define spir_kernel void @test_nontemporal(i8 addrspace(1)* %ptr, i32 %num_bytes) {
27+
entry:
28+
call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khjj(i8 addrspace(1)* %ptr, i32 %num_bytes, i32 4)
29+
ret void
30+
}
31+
32+
declare spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khjj(i8 addrspace(1)*, i32, i32)
33+
34+
!opencl.spir.version = !{!0}
35+
!spirv.Source = !{!1}
36+
!0 = !{i32 1, i32 0}
37+
!1 = !{i32 4, i32 100000}

0 commit comments

Comments
 (0)