Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport to 14] Implement SPV_INTEL_2d_block_io #2982

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/LLVMSPIRVExtensions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@ EXT(SPV_INTEL_fp_max_error)
EXT(SPV_INTEL_cache_controls)
EXT(SPV_INTEL_maximum_registers)
EXT(SPV_INTEL_bindless_images)
EXT(SPV_INTEL_2d_block_io)
45 changes: 45 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3965,5 +3965,50 @@ _SPIRV_OP(ConvertHandleToSamplerINTEL)
_SPIRV_OP(ConvertHandleToSampledImageINTEL)
#undef _SPIRV_OP

class SPIRVSubgroup2DBlockIOINTELInst : public SPIRVInstTemplateBase {
public:
llvm::Optional<ExtensionID> getRequiredExtension() const override {
return ExtensionID::SPV_INTEL_2d_block_io;
}
SPIRVCapVec getRequiredCapability() const override {
return getVec(CapabilitySubgroup2DBlockIOINTEL);
}
};

class SPIRVSubgroup2DBlockLoadTransposeINTELInst
: public SPIRVSubgroup2DBlockIOINTELInst {
SPIRVCapVec getRequiredCapability() const override {
return getVec(CapabilitySubgroup2DBlockTransposeINTEL);
}
};

class SPIRVSubgroup2DBlockLoadTransformINTELInst
: public SPIRVSubgroup2DBlockIOINTELInst {
SPIRVCapVec getRequiredCapability() const override {
return getVec(CapabilitySubgroup2DBlockTransformINTEL);
}
};

#define _SPIRV_OP(x, ...) \
typedef SPIRVInstTemplate<SPIRVSubgroup2DBlockIOINTELInst, Op##x##INTEL, \
__VA_ARGS__> \
SPIRV##x##INTEL;
_SPIRV_OP(Subgroup2DBlockLoad, false, 11)
_SPIRV_OP(Subgroup2DBlockPrefetch, false, 10)
_SPIRV_OP(Subgroup2DBlockStore, false, 11)
#undef _SPIRV_OP
#define _SPIRV_OP(x, ...) \
typedef SPIRVInstTemplate<SPIRVSubgroup2DBlockLoadTransposeINTELInst, \
Op##x##INTEL, __VA_ARGS__> \
SPIRV##x##INTEL;
_SPIRV_OP(Subgroup2DBlockLoadTranspose, false, 11)
#undef _SPIRV_OP
#define _SPIRV_OP(x, ...) \
typedef SPIRVInstTemplate<SPIRVSubgroup2DBlockLoadTransformINTELInst, \
Op##x##INTEL, __VA_ARGS__> \
SPIRV##x##INTEL;
_SPIRV_OP(Subgroup2DBlockLoadTransform, false, 11)
#undef _SPIRV_OP

} // namespace SPIRV
#endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H
3 changes: 3 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,9 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
add(CapabilityGlobalVariableHostAccessINTEL, "GlobalVariableHostAccessINTEL");
add(CapabilityGroupUniformArithmeticKHR, "GroupUniformArithmeticKHR");
add(CapabilityFPMaxErrorINTEL, "FPMaxErrorINTEL");
add(CapabilitySubgroup2DBlockIOINTEL, "Subgroup2DBlockIOINTEL");
add(CapabilitySubgroup2DBlockTransformINTEL, "Subgroup2DBlockTransformINTEL");
add(CapabilitySubgroup2DBlockTransposeINTEL, "Subgroup2DBlockTransposeINTEL");

// From spirv_internal.hpp
add(internal::CapabilityFPGADSPControlINTEL, "FPGADSPControlINTEL");
Expand Down
5 changes: 5 additions & 0 deletions lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,11 @@ _SPIRV_OP(ConstantCompositeContinuedINTEL, 6091)
_SPIRV_OP(SpecConstantCompositeContinuedINTEL, 6092)
_SPIRV_OP(ControlBarrierArriveINTEL, 6142)
_SPIRV_OP(ControlBarrierWaitINTEL, 6143)
_SPIRV_OP(Subgroup2DBlockLoadINTEL, 6231)
_SPIRV_OP(Subgroup2DBlockLoadTransformINTEL, 6232)
_SPIRV_OP(Subgroup2DBlockLoadTransposeINTEL, 6233)
_SPIRV_OP(Subgroup2DBlockPrefetchINTEL, 6234)
_SPIRV_OP(Subgroup2DBlockStoreINTEL, 6235)
_SPIRV_OP(GroupIMulKHR, 6401)
_SPIRV_OP(GroupFMulKHR, 6402)
_SPIRV_OP(GroupBitwiseAndKHR, 6403)
Expand Down
2 changes: 1 addition & 1 deletion spirv-headers-tag.conf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1c6bb2743599e6eb6f37b2969acc0aef812e32e3
2b2e05e088841c63c0b6fd4c9fb380d8688738d3
91 changes: 91 additions & 0 deletions test/extensions/INTEL/SPV_INTEL_2d_block_io/2d_block_io_generic.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
; Generated with:
; source.cl:
; void __spirv_Subgroup2DBlockLoadINTEL( int element_size, int block_width, int block_height, int block_count, const __global void* src_base_pointer, int memory_width, int memory_height, int memory_pitch, int2 coordinate, private void* dst_pointer);
; void __spirv_Subgroup2DBlockLoadTransposeINTEL(int element_size, int block_width, int block_height, int block_count, const __global void* src_base_pointer, int memory_width, int memory_height, int memory_pitch, int2 coordinate, private void* dst_pointer);
; void __spirv_Subgroup2DBlockLoadTransformINTEL(int element_size, int block_width, int block_height, int block_count, const __global void* src_base_pointer, int memory_width, int memory_height, int memory_pitch, int2 coordinate, private uint* dst_pointer);
; void __spirv_Subgroup2DBlockPrefetchINTEL( int element_size, int block_width, int block_height, int block_count, const __global void* src_base_pointer, int memory_width, int memory_height, int memory_pitch, int2 coordinate );
; void __spirv_Subgroup2DBlockStoreINTEL( int element_size, int block_width, int block_height, int block_count, const private void* src_pointer, __global void* dst_base_pointer, int memory_width, int memory_height, int memory_pitch, int2 coordinate );
;
; void foo(const __global void* base_address, __global void* dst_base_pointer, int width, int height, int pitch, int2 coord, private void* dst_pointer, const private void* src_pointer) {
; const int i = 42;
; __spirv_Subgroup2DBlockLoadINTEL(i, i, i, i, base_address, width, height, pitch, coord, dst_pointer);
; __spirv_Subgroup2DBlockLoadTransformINTEL(i, i, i, i, base_address, width, height, pitch, coord, (private uint*)dst_pointer);
; __spirv_Subgroup2DBlockLoadTransposeINTEL(i, i, i, i, base_address, width, height, pitch, coord, dst_pointer);
; __spirv_Subgroup2DBlockPrefetchINTEL(i, i, i, i, base_address, width, height, pitch, coord);
; __spirv_Subgroup2DBlockStoreINTEL(i, i, i, i, src_pointer, dst_base_pointer, width, height, pitch, coord);
; }
; clang -cc1 -cl-std=clc++2021 -triple spir64-unknown-unknown -emit-llvm -finclude-default-header source.cl -o tmp.ll

; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_2d_block_io
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV

; RUN: llvm-spirv %t.spv -o %t.rev.bc -r --spirv-target-env=SPV-IR
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM

; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
; CHECK-ERROR-NEXT: SPV_INTEL_2d_block_io

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spir64-unknown-unknown"

; CHECK-SPIRV: Capability Subgroup2DBlockIOINTEL
; CHECK-SPIRV: Capability Subgroup2DBlockTransformINTEL
; CHECK-SPIRV: Capability Subgroup2DBlockTransposeINTEL
; CHECK-SPIRV: Extension "SPV_INTEL_2d_block_io"
; CHECK-SPIRV-DAG: TypeInt [[#Int8Ty:]] 8 0
; CHECK-SPIRV-DAG: TypeInt [[#Int32Ty:]] 32 0
; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#Const42:]] 42
; CHECK-SPIRV-DAG: TypeVoid [[#VoidTy:]]
; CHECK-SPIRV-DAG: TypePointer [[#GlbPtrTy:]] 5 [[#Int8Ty]]
; CHECK-SPIRV-DAG: TypeVector [[#VectorTy:]] [[#Int32Ty]] 2
; CHECK-SPIRV-DAG: TypePointer [[#PrvPtrTy:]] 7 [[#Int8Ty]]
; CHECK-SPIRV-DAG: TypePointer [[#PrvPtrTy32:]] 7 [[#Int32Ty]]
; CHECK-SPIRV: FunctionParameter [[#GlbPtrTy]] [[#BaseSrc:]]
; CHECK-SPIRV: FunctionParameter [[#GlbPtrTy]] [[#BaseDst:]]
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#Width:]]
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#Height:]]
; CHECK-SPIRV: FunctionParameter [[#Int32Ty]] [[#Pitch:]]
; CHECK-SPIRV: FunctionParameter [[#VectorTy]] [[#Coord:]]
; CHECK-SPIRV: FunctionParameter [[#PrvPtrTy]] [[#Dst:]]
; CHECK-SPIRV: FunctionParameter [[#PrvPtrTy]] [[#Src:]]
; CHECK-SPIRV: Subgroup2DBlockLoadINTEL [[#Const42]] [[#Const42]] [[#Const42]] [[#Const42]] [[#BaseSrc]] [[#Width]] [[#Height]] [[#Pitch]] [[#Coord]] [[#Dst]]
; CHECK-SPIRV: Bitcast [[#PrvPtrTy32]] [[#Dst32:]] [[#Dst]]
; CHECK-SPIRV: Subgroup2DBlockLoadTransformINTEL [[#Const42]] [[#Const42]] [[#Const42]] [[#Const42]] [[#BaseSrc]] [[#Width]] [[#Height]] [[#Pitch]] [[#Coord]] [[#Dst32]]
; CHECK-SPIRV: Subgroup2DBlockLoadTransposeINTEL [[#Const42]] [[#Const42]] [[#Const42]] [[#Const42]] [[#BaseSrc]] [[#Width]] [[#Height]] [[#Pitch]] [[#Coord]] [[#Dst]]
; CHECK-SPIRV: Subgroup2DBlockPrefetchINTEL [[#Const42]] [[#Const42]] [[#Const42]] [[#Const42]] [[#BaseSrc]] [[#Width]] [[#Height]] [[#Pitch]] [[#Coord]]
; CHECK-SPIRV: Subgroup2DBlockStoreINTEL [[#Const42]] [[#Const42]] [[#Const42]] [[#Const42]] [[#Src]] [[#BaseDst]] [[#Width]] [[#Height]] [[#Pitch]] [[#Coord]]

; CHECK-LLVM: call spir_func void @_Z32__spirv_Subgroup2DBlockLoadINTELiiiiPU3AS1ciiiDv2_iPc(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}, i8* %{{.*}})
; CHECK-LLVM: call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransformINTELiiiiPU3AS1ciiiDv2_iPi(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}, i32* %{{.*}})
; CHECK-LLVM: call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransposeINTELiiiiPU3AS1ciiiDv2_iPc(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}, i8* %{{.*}})
; CHECK-LLVM: call spir_func void @_Z36__spirv_Subgroup2DBlockPrefetchINTELiiiiPU3AS1ciiiDv2_i(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})
; CHECK-LLVM: call spir_func void @_Z33__spirv_Subgroup2DBlockStoreINTELiiiiPcPU3AS1ciiiDv2_i(i32 42, i32 42, i32 42, i32 42, i8* %{{.*}}, i8 addrspace(1)* %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}})

define spir_func void @foo(i8 addrspace(1)* %base_address, i8 addrspace(1)* %dst_base_pointer, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, i8* %dst_pointer, i8* %src_pointer) {
entry:
call spir_func void @_Z32__spirv_Subgroup2DBlockLoadINTELiiiiPU3AS1KviiiDv2_iPv(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %base_address, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, i8* %dst_pointer)
%0 = bitcast i8* %dst_pointer to i32*
call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransformINTELiiiiPU3AS1KviiiDv2_iPj(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %base_address, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, i32* %0)
call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransposeINTELiiiiPU3AS1KviiiDv2_iPv(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %base_address, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, i8* %dst_pointer)
call spir_func void @_Z36__spirv_Subgroup2DBlockPrefetchINTELiiiiPU3AS1KviiiDv2_i(i32 42, i32 42, i32 42, i32 42, i8 addrspace(1)* %base_address, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord)
call spir_func void @_Z33__spirv_Subgroup2DBlockStoreINTELiiiiPKvPU3AS1viiiDv2_i(i32 42, i32 42, i32 42, i32 42, i8* %src_pointer, i8 addrspace(1)* %dst_base_pointer, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord)
ret void
}

declare spir_func void @_Z32__spirv_Subgroup2DBlockLoadINTELiiiiPU3AS1KviiiDv2_iPv(i32, i32, i32, i32, i8 addrspace(1)*, i32, i32, i32, <2 x i32>, i8*)
declare spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransformINTELiiiiPU3AS1KviiiDv2_iPj(i32, i32, i32, i32, i8 addrspace(1)*, i32, i32, i32, <2 x i32>, i32*)
declare spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransposeINTELiiiiPU3AS1KviiiDv2_iPv(i32, i32, i32, i32, i8 addrspace(1)*, i32, i32, i32, <2 x i32>, i8*)
declare spir_func void @_Z36__spirv_Subgroup2DBlockPrefetchINTELiiiiPU3AS1KviiiDv2_i(i32, i32, i32, i32, i8 addrspace(1)*, i32, i32, i32, <2 x i32>)
declare spir_func void @_Z33__spirv_Subgroup2DBlockStoreINTELiiiiPKvPU3AS1viiiDv2_i(i32, i32, i32, i32, i8*, i8 addrspace(1)*, i32, i32, i32, <2 x i32>)

!opencl.spir.version = !{!0}
!spirv.Source = !{!1}
!llvm.ident = !{!2}

!0 = !{i32 1, i32 0}
!1 = !{i32 4, i32 100000}
!2 = !{!"clang version 14.0.6"}
Loading