Skip to content

Commit 8ad4c2e

Browse files
authored
[Backport to 22] Add SPV_INTEL_subgroup_buffer_prefetch extension support (#3690) (#3694)
cherry picked from c8862dd
1 parent 114f5ee commit 8ad4c2e

11 files changed

Lines changed: 271 additions & 0 deletions

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ EXT(SPV_INTEL_fpga_argument_interfaces)
7272
EXT(SPV_INTEL_fpga_latency_control)
7373
EXT(SPV_INTEL_fp_max_error)
7474
EXT(SPV_INTEL_cache_controls)
75+
EXT(SPV_INTEL_subgroup_buffer_prefetch)
7576
EXT(SPV_INTEL_subgroup_requirements)
7677
EXT(SPV_INTEL_task_sequence)
7778
EXT(SPV_INTEL_maximum_registers)

lib/SPIRV/SPIRVUtil.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,6 +2493,12 @@ class SPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo {
24932493
setArgAttr(0, SPIR::ATTR_CONST);
24942494
addUnsignedArg(0);
24952495
break;
2496+
case OpSubgroupBlockPrefetchINTEL:
2497+
setArgAttr(0, SPIR::ATTR_CONST);
2498+
addUnsignedArg(0);
2499+
addUnsignedArg(1);
2500+
addUnsignedArg(2); // optional Memory Operands bitmask
2501+
break;
24962502
case OpAtomicUMax:
24972503
case OpAtomicUMin:
24982504
addUnsignedArg(0);

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4392,6 +4392,46 @@ class SPIRVUntypedPrefetchKHR : public SPIRVInstruction {
43924392
std::vector<SPIRVId> CacheTy;
43934393
};
43944394

4395+
class SPIRVSubgroupBlockPrefetchINTELInst : public SPIRVInstTemplateBase {
4396+
public:
4397+
std::optional<ExtensionID> getRequiredExtension() const override {
4398+
return ExtensionID::SPV_INTEL_subgroup_buffer_prefetch;
4399+
}
4400+
SPIRVCapVec getRequiredCapability() const override {
4401+
return getVec(CapabilitySubgroupBufferPrefetchINTEL);
4402+
}
4403+
// Operand 2, if present, is the Memory Operands bitmask.
4404+
bool isOperandLiteral(unsigned I) const override { return I == 2; }
4405+
4406+
protected:
4407+
void validate() const override {
4408+
SPIRVInstruction::validate();
4409+
if (getValue(Ops[0])->isForward())
4410+
return;
4411+
SPIRVErrorLog &SPVErrLog = getModule()->getErrorLog();
4412+
SPIRVType *PtrType = getValueType(Ops[0]);
4413+
std::string InstName = "OpSubgroupBlockPrefetchINTEL";
4414+
SPVErrLog.checkError(
4415+
PtrType->isTypePointer() || PtrType->isTypeUntypedPointerKHR(),
4416+
SPIRVEC_InvalidInstruction, InstName + "\nPtr must be a pointer\n");
4417+
SPVErrLog.checkError(
4418+
PtrType->getPointerStorageClass() == StorageClassCrossWorkgroup,
4419+
SPIRVEC_InvalidInstruction,
4420+
InstName + "\nPtr must be in CrossWorkgroup storage class\n");
4421+
if (!PtrType->isTypeUntypedPointerKHR())
4422+
SPVErrLog.checkError(PtrType->getPointerElementType()->isTypeInt(),
4423+
SPIRVEC_InvalidInstruction,
4424+
InstName +
4425+
"\nPtr must point to a scalar integer type\n");
4426+
SPVErrLog.checkError(
4427+
getValueType(Ops[1])->isTypeInt(32), SPIRVEC_InvalidInstruction,
4428+
InstName + "\nNumBytes must be a 32-bit integer scalar\n");
4429+
}
4430+
};
4431+
typedef SPIRVInstTemplate<SPIRVSubgroupBlockPrefetchINTELInst,
4432+
OpSubgroupBlockPrefetchINTEL, false, 3, true>
4433+
SPIRVSubgroupBlockPrefetchINTEL;
4434+
43954435
class SPIRVSubgroup2DBlockIOINTELInst : public SPIRVInstTemplateBase {
43964436
public:
43974437
std::optional<ExtensionID> getRequiredExtension() const override {

lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
563563
add(CapabilityBindlessTextureNV, "BindlessTextureNV");
564564
add(CapabilitySubgroupShuffleINTEL, "SubgroupShuffleINTEL");
565565
add(CapabilitySubgroupBufferBlockIOINTEL, "SubgroupBufferBlockIOINTEL");
566+
add(CapabilitySubgroupBufferPrefetchINTEL, "SubgroupBufferPrefetchINTEL");
566567
add(CapabilitySubgroupImageBlockIOINTEL, "SubgroupImageBlockIOINTEL");
567568
add(CapabilitySubgroupImageMediaBlockIOINTEL,
568569
"SubgroupImageMediaBlockIOINTEL");

lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ _SPIRV_OP(ConvertBF16ToFINTEL, 6117)
574574
_SPIRV_OP(ControlBarrierArriveINTEL, 6142)
575575
_SPIRV_OP(ControlBarrierWaitINTEL, 6143)
576576
_SPIRV_OP(ArithmeticFenceEXT, 6145)
577+
_SPIRV_OP(SubgroupBlockPrefetchINTEL, 6221)
577578
_SPIRV_OP(Subgroup2DBlockLoadINTEL, 6231)
578579
_SPIRV_OP(Subgroup2DBlockLoadTransformINTEL, 6232)
579580
_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: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; RUN: llvm-spirv %s -o %t.spv --spirv-ext=+SPV_INTEL_subgroup_buffer_prefetch
2+
; RUN: spirv-val %t.spv
3+
; RUN: llvm-spirv %t.spv --to-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-TYPED-PTRS
4+
; RUN: llvm-spirv %t.spv -r --spirv-target-env=SPV-IR -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM
5+
6+
; RUN: llvm-spirv %s -o %t.spv --spirv-ext=+SPV_INTEL_subgroup_buffer_prefetch,+SPV_KHR_untyped_pointers
7+
; RUN: spirv-val %t.spv
8+
; RUN: llvm-spirv %t.spv --to-text -o -| FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-UNTYPED-PTRS
9+
; RUN: llvm-spirv %t.spv -r --spirv-target-env=SPV-IR -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM
10+
11+
; RUN: not llvm-spirv %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
12+
13+
; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
14+
; CHECK-ERROR-NEXT: SPV_INTEL_subgroup_buffer_prefetch
15+
16+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
17+
target triple = "spir64-unknown-unknown"
18+
19+
; CHECK-SPIRV-DAG: Capability SubgroupBufferPrefetchINTEL
20+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_subgroup_buffer_prefetch"
21+
; CHECK-SPIRV-UNTYPED-PTRS-DAG: Capability UntypedPointersKHR
22+
; CHECK-SPIRV-UNTYPED-PTRS-DAG: Extension "SPV_KHR_untyped_pointers"
23+
; CHECK-SPIRV-DAG: TypeInt [[#Int8Ty:]] 8 0
24+
; CHECK-SPIRV-DAG: TypeInt [[#Int32Ty:]] 32 0
25+
; CHECK-SPIRV-TYPED-PTRS-DAG: TypePointer [[#GlbPtrTy:]] 5 [[#Int8Ty]]
26+
; CHECK-SPIRV-UNTYPED-PTRS-DAG: TypeUntypedPointerKHR [[#GlbPtrTy:]] 5
27+
28+
; CHECK-SPIRV: FunctionParameter [[#GlbPtrTy]] [[#Ptr:]]
29+
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#NumBytes:]]
30+
; CHECK-SPIRV: SubgroupBlockPrefetchINTEL [[#Ptr]] [[#NumBytes]]
31+
32+
; CHECK-LLVM: call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khj(ptr addrspace(1) %{{.*}}, i32 %{{.*}})
33+
34+
define spir_kernel void @test(ptr addrspace(1) %ptr, i32 %num_bytes) {
35+
entry:
36+
call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khj(ptr addrspace(1) %ptr, i32 %num_bytes)
37+
ret void
38+
}
39+
40+
declare spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khj(ptr addrspace(1), i32)
41+
42+
!opencl.spir.version = !{!0}
43+
!spirv.Source = !{!1}
44+
!0 = !{i32 1, i32 0}
45+
!1 = !{i32 4, i32 100000}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llvm-spirv %s -o %t.spv --spirv-ext=+SPV_INTEL_subgroup_buffer_prefetch
2+
; RUN: spirv-val %t.spv
3+
; RUN: llvm-spirv %t.spv --to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
4+
; RUN: llvm-spirv %t.spv -r --spirv-target-env=SPV-IR -o - | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM
5+
6+
; OpSubgroupBlockPrefetchINTEL accepts an optional Memory Operands bitmask
7+
; as a third operand after the required Ptr and NumBytes.
8+
; Test Prefetch with Nontemporal memory operand (0x4).
9+
10+
; CHECK-SPIRV-DAG: Capability SubgroupBufferPrefetchINTEL
11+
; CHECK-SPIRV-DAG: Extension "SPV_INTEL_subgroup_buffer_prefetch"
12+
; CHECK-SPIRV-DAG: TypeInt [[#Int8Ty:]] 8 0
13+
; CHECK-SPIRV-DAG: TypeInt [[#Int32Ty:]] 32 0
14+
; CHECK-SPIRV-DAG: TypePointer [[#GlbPtrTy:]] 5 [[#Int8Ty]]
15+
16+
; CHECK-SPIRV: FunctionParameter [[#GlbPtrTy]] [[#Ptr:]]
17+
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#NumBytes:]]
18+
; CHECK-SPIRV: SubgroupBlockPrefetchINTEL [[#Ptr]] [[#NumBytes]] 4
19+
20+
; CHECK-LLVM: call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khjj(ptr addrspace(1) %{{.*}}, i32 %{{.*}}, i32 4)
21+
22+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
23+
target triple = "spir64-unknown-unknown"
24+
25+
define spir_kernel void @test_nontemporal(ptr addrspace(1) %ptr, i32 %num_bytes) {
26+
entry:
27+
call spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khjj(ptr addrspace(1) %ptr, i32 %num_bytes, i32 4)
28+
ret void
29+
}
30+
31+
declare spir_func void @_Z34__spirv_SubgroupBlockPrefetchINTELPU3AS1Khjj(ptr addrspace(1), i32, i32)
32+
33+
!opencl.spir.version = !{!0}
34+
!spirv.Source = !{!1}
35+
!0 = !{i32 1, i32 0}
36+
!1 = !{i32 4, i32 100000}

0 commit comments

Comments
 (0)