diff --git a/lib/SPIRV/SPIRVUtil.cpp b/lib/SPIRV/SPIRVUtil.cpp index 9f5d3579e..4b0f721da 100644 --- a/lib/SPIRV/SPIRVUtil.cpp +++ b/lib/SPIRV/SPIRVUtil.cpp @@ -2518,30 +2518,6 @@ class SPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo { case internal::OpConvertHandleToSampledImageINTEL: addUnsignedArg(0); break; - case internal::OpSubgroup2DBlockLoadINTEL: - case internal::OpSubgroup2DBlockLoadTransposeINTEL: - case internal::OpSubgroup2DBlockLoadTransformINTEL: - addUnsignedArgs(0, 3); - setArgAttr(4, SPIR::ATTR_GLOBAL); - addVoidPtrArg(4); - addUnsignedArgs(5, 8); - setArgAttr(9, SPIR::ATTR_PRIVATE); - addVoidPtrArg(9); - break; - case internal::OpSubgroup2DBlockPrefetchINTEL: - addUnsignedArgs(0, 3); - setArgAttr(4, SPIR::ATTR_GLOBAL); - addVoidPtrArg(4); - addUnsignedArgs(5, 8); - break; - case internal::OpSubgroup2DBlockStoreINTEL: - addUnsignedArgs(0, 3); - setArgAttr(4, SPIR::ATTR_PRIVATE); - addVoidPtrArg(4); - setArgAttr(5, SPIR::ATTR_GLOBAL); - addVoidPtrArg(5); - addUnsignedArgs(6, 9); - break; default:; // No special handling is needed } diff --git a/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/lib/SPIRV/libSPIRV/SPIRVInstruction.h index 2ffc199be..575aefd49 100644 --- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -4195,7 +4195,7 @@ _SPIRV_OP(ConvertHandleToSamplerINTEL) _SPIRV_OP(ConvertHandleToSampledImageINTEL) #undef _SPIRV_OP -class SPIRVSubgroup2DBlockIOINTELInstBase : public SPIRVInstTemplateBase { +class SPIRVSubgroup2DBlockIOINTELInst : public SPIRVInstTemplateBase { public: std::optional getRequiredExtension() const override { return ExtensionID::SPV_INTEL_2d_block_io; @@ -4205,33 +4205,37 @@ class SPIRVSubgroup2DBlockIOINTELInstBase : public SPIRVInstTemplateBase { } }; -class SPIRVSubgroup2DBlockLoadINTELInst : public SPIRVSubgroup2DBlockIOINTELInstBase { -protected: - void validate() const override { - SPIRVInstruction::validate(); - std::string InstName = "Subgroup2DBlockLoadINTEL"; - SPIRVErrorLog &SPVErrLog = this->getModule()->getErrorLog(); +class SPIRVSubgroup2DBlockLoadTransposeINTELInst : public SPIRVSubgroup2DBlockIOINTELInst { + SPIRVCapVec getRequiredCapability() const override { + return getVec(internal::Subgroup2DBlockTransposeINTEL); + } +}; - SPVErrLog.checkError( - this->isOperandLiteral(0), SPIRVEC_InvalidInstruction, - InstName + "\nElement Size must be a constant instructions with scalar 32-bit integer type\n"); - SPVErrLog.checkError( - this->isOperandLiteral(1), SPIRVEC_InvalidInstruction, - InstName + "\nBlock Width must be a constant instructions with scalar 32-bit integer type\n"); - SPVErrLog.checkError( - this->isOperandLiteral(2), SPIRVEC_InvalidInstruction, - InstName + "\nBlock Height must be a constant instructions with scalar 32-bit integer type\n"); - SPVErrLog.checkError( - this->isOperandLiteral(3), SPIRVEC_InvalidInstruction, - InstName + "\nElement Size must be a constant instructions with scalar 32-bit integer type\n"); +class SPIRVSubgroup2DBlockLoadTransformINTELInst : public SPIRVSubgroup2DBlockIOINTELInst { + SPIRVCapVec getRequiredCapability() const override { + return getVec(internal::Subgroup2DBlockTransformINTEL); } }; -#define _SPIRV_OP(x, ...) \ - typedef SPIRVInstTemplate \ +#define _SPIRV_OP(x, ...) \ + typedef SPIRVInstTemplate \ + 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 \ + SPIRV##x##INTEL; +_SPIRV_OP(Subgroup2DBlockLoadTranspose, false, 11) +#undef _SPIRV_OP +#define _SPIRV_OP(x, ...) \ + typedef SPIRVInstTemplate \ SPIRV##x##INTEL; -_SPIRV_OP(Subgroup2DBlockLoad, true, 11) +_SPIRV_OP(Subgroup2DBlockLoadTransform, false, 11) #undef _SPIRV_OP } // namespace SPIRV diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index ec442aacf..73c2dcd2e 100644 --- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -675,6 +675,9 @@ template <> inline void SPIRVMap::init() { "SubgroupRequirementsINTEL"); add(internal::CapabilityTaskSequenceINTEL, "TaskSequenceINTEL"); add(internal::CapabilityBindlessImagesINTEL, "BindlessImagesINTEL"); + add(internal::CapabilitySubgroup2DBlockIOINTEL, "Subgroup2DBlockIOINTEL"); + add(internal::CapabilitySubgroup2DBlockTransformINTEL, "Subgroup2DBlockTransformINTEL"); + add(internal::CapabilitySubgroup2DBlockTransposeINTEL, "Subgroup2DBlockTransposeINTEL"); } SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap) diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h index f29008037..88597c8e6 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h @@ -43,3 +43,13 @@ _SPIRV_OP_INTERNAL(ConvertHandleToSamplerINTEL, internal::ConvertHandleToSamplerINTEL) _SPIRV_OP_INTERNAL(ConvertHandleToSampledImageINTEL, internal::ConvertHandleToSampledImageINTEL) +_SPIRV_OP_INTERNAL(Subgroup2DBlockLoadINTEL, + internal::Subgroup2DBlockLoadINTEL) +_SPIRV_OP_INTERNAL(Subgroup2DBlockLoadTransposeINTEL, + internal::Subgroup2DBlockLoadTransposeINTEL) +_SPIRV_OP_INTERNAL(Subgroup2DBlockLoadTransformINTEL, + internal::Subgroup2DBlockLoadTransformINTEL) +_SPIRV_OP_INTERNAL(Subgroup2DBlockPrefetchINTEL, + internal::Subgroup2DBlockPrefetchINTEL) +_SPIRV_OP_INTERNAL(Subgroup2DBlockStoreINTEL, + internal::Subgroup2DBlockStoreINTEL) diff --git a/lib/SPIRV/libSPIRV/spirv_internal.hpp b/lib/SPIRV/libSPIRV/spirv_internal.hpp index cdec3a959..737ecfaa3 100644 --- a/lib/SPIRV/libSPIRV/spirv_internal.hpp +++ b/lib/SPIRV/libSPIRV/spirv_internal.hpp @@ -90,6 +90,11 @@ enum InternalOp { IOpConvertHandleToImageINTEL = 6529, IOpConvertHandleToSamplerINTEL = 6530, IOpConvertHandleToSampledImageINTEL = 6531, + IOpSubgroup2DBlockLoadINTEL = 7775, + IOpSubgroup2DBlockLoadTransposeINTEL = 7776, + IOpSubgroup2DBlockLoadTransformINTEL = 7777, + IOpSubgroup2DBlockPrefetchINTEL = 7778, + IOpSubgroup2DBlockStoreINTEL = 7779, IOpPrev = OpMax - 2, IOpForward }; @@ -126,7 +131,10 @@ enum InternalCapability { ICapabilityJointMatrixPackedInt4ComponentTypeINTEL = 6439, ICapabilityCacheControlsINTEL = 6441, ICapabilitySubgroupRequirementsINTEL = 6445, - ICapabilityBindlessImagesINTEL = 6528 + ICapabilityBindlessImagesINTEL = 6528, + ICapabilitySubgroup2DBlockIOINTEL = 8887, + ICapabilitySubgroup2DBlockTransformINTEL = 8888, + ICapabilitySubgroup2DBlockTransposeINTEL = 8889, }; enum InternalFunctionControlMask { IFunctionControlOptNoneINTELMask = 0x10000 }; @@ -220,6 +228,17 @@ _SPIRV_OP(Capability, BindlessImagesINTEL) _SPIRV_OP(Op, ConvertHandleToImageINTEL) _SPIRV_OP(Op, ConvertHandleToSamplerINTEL) _SPIRV_OP(Op, ConvertHandleToSampledImageINTEL) + +_SPIRV_OP(Capability, Subgroup2DBlockIOINTEL) +_SPIRV_OP(Op, Subgroup2DBlockLoadINTEL) +_SPIRV_OP(Op, Subgroup2DBlockPrefetchINTEL) +_SPIRV_OP(Op, Subgroup2DBlockStoreINTEL) + +_SPIRV_OP(Capability, Subgroup2DBlockTransformINTEL) +_SPIRV_OP(Op, Subgroup2DBlockLoadTransformINTEL) + +_SPIRV_OP(Capability, Subgroup2DBlockTransposeINTEL) +_SPIRV_OP(Op, Subgroup2DBlockLoadTransposeINTEL) #undef _SPIRV_OP constexpr SourceLanguage SourceLanguagePython = diff --git a/test/extensions/INTEL/SPV_INTEL_2d_block_io/2d_block_io_generic.ll b/test/extensions/INTEL/SPV_INTEL_2d_block_io/2d_block_io_generic.ll new file mode 100644 index 000000000..69ed63029 --- /dev/null +++ b/test/extensions/INTEL/SPV_INTEL_2d_block_io/2d_block_io_generic.ll @@ -0,0 +1,39 @@ +; 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" + +define spir_func void @foo(ptr addrspace(1) noundef %base_address, ptr addrspace(1) noundef %dst_base_pointer, i32 noundef %width, i32 noundef %height, i32 noundef %pitch, <2 x i32> noundef %coord, ptr noundef %dst_pointer, ptr noundef %src_pointer) { +entry: + tail call spir_func void @_Z32__spirv_Subgroup2DBlockLoadINTELjjjjPU3AS1KvjjjDv2_jPv(i32 noundef 1, i32 noundef 32, i32 noundef 1, i32 noundef 1, ptr addrspace(1) noundef %base_address, i32 noundef %width, i32 noundef %height, i32 noundef %pitch, <2 x i32> noundef %coord, ptr noundef %dst_pointer) + tail call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransformINTELjjjjPU3AS1KvjjjDv2_jPv(i32 noundef 1, i32 noundef 16, i32 noundef 32, i32 noundef 1, ptr addrspace(1) noundef %base_address, i32 noundef %width, i32 noundef %height, i32 noundef %pitch, <2 x i32> noundef %coord, ptr noundef %dst_pointer) + tail call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransposeINTELjjjjPU3AS1KvjjjDv2_jPv(i32 noundef 4, i32 noundef 1, i32 noundef 16, i32 noundef 1, ptr addrspace(1) noundef %base_address, i32 noundef %width, i32 noundef %height, i32 noundef %pitch, <2 x i32> noundef %coord, ptr noundef %dst_pointer) + tail call spir_func void @_Z36__spirv_Subgroup2DBlockPrefetchINTELjjjjPU3AS1KvjjjDv2_j(i32 noundef 1, i32 noundef 32, i32 noundef 1, i32 noundef 1, ptr addrspace(1) noundef %base_address, i32 noundef %width, i32 noundef %height, i32 noundef %pitch, <2 x i32> noundef %coord) + tail call spir_func void @_Z33__spirv_Subgroup2DBlockStoreINTELjjjjPKvPU3AS1vjjjDv2_j(i32 noundef 1, i32 noundef 16, i32 noundef 1, i32 noundef 1, ptr noundef %src_pointer, ptr addrspace(1) noundef %dst_base_pointer, i32 noundef %width, i32 noundef %height, i32 noundef %pitch, <2 x i32> noundef %coord) + ret void +} + +declare spir_func void @_Z32__spirv_Subgroup2DBlockLoadINTELjjjjPU3AS1KvjjjDv2_jPv(i32 noundef, i32 noundef, i32 noundef, i32 noundef, ptr addrspace(1) noundef, i32 noundef, i32 noundef, i32 noundef, <2 x i32> noundef, ptr noundef) +declare spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransformINTELjjjjPU3AS1KvjjjDv2_jPv(i32 noundef, i32 noundef, i32 noundef, i32 noundef, ptr addrspace(1) noundef, i32 noundef, i32 noundef, i32 noundef, <2 x i32> noundef, ptr noundef) +declare spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransposeINTELjjjjPU3AS1KvjjjDv2_jPv(i32 noundef, i32 noundef, i32 noundef, i32 noundef, ptr addrspace(1) noundef, i32 noundef, i32 noundef, i32 noundef, <2 x i32> noundef, ptr noundef) +declare spir_func void @_Z36__spirv_Subgroup2DBlockPrefetchINTELjjjjPU3AS1KvjjjDv2_j(i32 noundef, i32 noundef, i32 noundef, i32 noundef, ptr addrspace(1) noundef, i32 noundef, i32 noundef, i32 noundef, <2 x i32> noundef) +declare spir_func void @_Z33__spirv_Subgroup2DBlockStoreINTELjjjjPKvPU3AS1vjjjDv2_j(i32 noundef, i32 noundef, i32 noundef, i32 noundef, ptr noundef, ptr addrspace(1) noundef, i32 noundef, i32 noundef, i32 noundef, <2 x i32> noundef) + +!opencl.spir.version = !{!0} +!spirv.Source = !{!1} +!llvm.ident = !{!2} + +!0 = !{i32 1, i32 0} +!1 = !{i32 4, i32 100000} +!2 = !{!"clang version 17.0.0"}