Skip to content

[SPIRV] Added support for extension SPV_INTEL_2d_block_io #133911

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
16 changes: 15 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
Original file line number Diff line number Diff line change
@@ -697,7 +697,8 @@ static bool buildAtomicStoreInst(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
if (Call->isSpirvOp())
return buildOpFromWrapper(MIRBuilder, SPIRV::OpAtomicStore, Call, Register(0));
return buildOpFromWrapper(MIRBuilder, SPIRV::OpAtomicStore, Call,
Register(0));

Register ScopeRegister =
buildConstantIntReg32(SPIRV::Scope::Device, MIRBuilder, GR);
@@ -2252,6 +2253,17 @@ static bool generateExtendedBitOpsInst(const SPIRV::IncomingCall *Call,

return buildExtendedBitOpsInst(Call, Opcode, MIRBuilder, GR);
}
static bool generateSubgroup2DBlockInst(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
unsigned Opcode =
SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
auto MIB = MIRBuilder.buildInstr(Opcode);
for (unsigned i = 0; i < Call->Arguments.size(); i++)
MIB.addUse(Call->Arguments[i]);
return true;
}

static bool generateBindlessImageINTELInst(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
@@ -2845,6 +2857,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
return generateExtendedBitOpsInst(Call.get(), MIRBuilder, GR);
case SPIRV::BindlessINTEL:
return generateBindlessImageINTELInst(Call.get(), MIRBuilder, GR);
case SPIRV::Subgroup2DBlock:
return generateSubgroup2DBlockInst(Call.get(), MIRBuilder, GR);
}
return false;
}
8 changes: 8 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVBuiltins.td
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ def CoopMatr : BuiltinGroup;
def ICarryBorrow : BuiltinGroup;
def ExtendedBitOps : BuiltinGroup;
def BindlessINTEL : BuiltinGroup;
def Subgroup2DBlock: BuiltinGroup;

//===----------------------------------------------------------------------===//
// Class defining a demangled builtin record. The information in the record
@@ -714,6 +715,13 @@ defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToImageINTEL", OpenCL_std, B
defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToSamplerINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToSamplerINTEL>;
defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToSampledImageINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToSampledImageINTEL>;

//SPV_INTEL_2d_block_io
defm : DemangledNativeBuiltin<"__spirv_Subgroup2DBlockLoadINTEL", OpenCL_std, Subgroup2DBlock, 10, 10, OpSubgroup2DBlockLoadINTEL>;
defm : DemangledNativeBuiltin<"__spirv_Subgroup2DBlockLoadTransposeINTEL", OpenCL_std, Subgroup2DBlock, 10, 10, OpSubgroup2DBlockLoadTransposeINTEL>;
defm : DemangledNativeBuiltin<"__spirv_Subgroup2DBlockLoadTransformINTEL", OpenCL_std, Subgroup2DBlock, 10, 10, OpSubgroup2DBlockLoadTransformINTEL>;
defm : DemangledNativeBuiltin<"__spirv_Subgroup2DBlockPrefetchINTEL", OpenCL_std, Subgroup2DBlock, 9, 9, OpSubgroup2DBlockPrefetchINTEL>;
defm : DemangledNativeBuiltin<"__spirv_Subgroup2DBlockStoreINTEL", OpenCL_std, Subgroup2DBlock, 10, 10, OpSubgroup2DBlockStoreINTEL>;

//===----------------------------------------------------------------------===//
// Class defining a work/sub group builtin that should be translated into a
// SPIR-V instruction using the defined properties.
4 changes: 3 additions & 1 deletion llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
Original file line number Diff line number Diff line change
@@ -92,7 +92,9 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
{"SPV_INTEL_long_composites",
SPIRV::Extension::Extension::SPV_INTEL_long_composites},
{"SPV_INTEL_fp_max_error",
SPIRV::Extension::Extension::SPV_INTEL_fp_max_error}};
SPIRV::Extension::Extension::SPV_INTEL_fp_max_error},
{"SPV_INTEL_2d_block_io",
SPIRV::Extension::Extension::SPV_INTEL_2d_block_io}};

bool SPIRVExtensionsParser::parse(cl::Option &O, llvm::StringRef ArgName,
llvm::StringRef ArgValue,
17 changes: 17 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
Original file line number Diff line number Diff line change
@@ -928,3 +928,20 @@ def OpAliasScopeDeclINTEL: Op<5912, (outs ID:$res), (ins ID:$AliasDomain, variab
"$res = OpAliasScopeDeclINTEL $AliasDomain">;
def OpAliasScopeListDeclINTEL: Op<5913, (outs ID:$res), (ins variable_ops),
"$res = OpAliasScopeListDeclINTEL">;

//SPV_INTEL_2d_block_io
def OpSubgroup2DBlockLoadINTEL: Op<6231, (outs),
(ins ID:$elementSize, ID:$blockWidth, ID:$blockHeight, ID:$blockCount, ID:$srcBasePointer, ID:$memoryWidth, ID:$memoryHeight, ID:$memoryPitch, ID:$coordinate, ID:$dstPointer),
"OpSubgroup2DBlockLoadINTEL $elementSize $blockWidth $blockHeight $blockCount $srcBasePointer $memoryWidth $memoryHeight $memoryPitch $coordinate $dstPointer">;
def OpSubgroup2DBlockLoadTransposeINTEL: Op<6232, (outs),
(ins ID:$elementSize, ID:$blockWidth, ID:$blockHeight, ID:$blockCount, ID:$srcBasePointer, ID:$memoryWidth, ID:$memoryHeight, ID:$memoryPitch, ID:$coordinate, ID:$dstPointer),
"OpSubgroup2DBlockLoadTransposeINTEL $elementSize $blockWidth $blockHeight $blockCount $srcBasePointer $memoryWidth $memoryHeight $memoryPitch $coordinate $dstPointer">;
def OpSubgroup2DBlockLoadTransformINTEL: Op<6233, (outs),
(ins ID:$elementSize, ID:$blockWidth, ID:$blockHeight, ID:$blockCount, ID:$srcBasePointer, ID:$memoryWidth, ID:$memoryHeight, ID:$memoryPitch, ID:$coordinate, ID:$dstPointer),
"OpSubgroup2DBlockLoadTransformINTEL $elementSize $blockWidth $blockHeight $blockCount $srcBasePointer $memoryWidth $memoryHeight $memoryPitch $coordinate $dstPointer">;
def OpSubgroup2DBlockPrefetchINTEL: Op<6234, (outs),
(ins ID:$elementSize, ID:$blockWidth, ID:$blockHeight, ID:$blockCount, ID:$srcPointer, ID:$memoryWidth, ID:$memoryHeight, ID:$memoryPitch, ID:$coordinate),
"OpSubgroup2DBlockPrefetchINTEL $elementSize $blockWidth $blockHeight $blockCount $srcPointer $memoryWidth $memoryHeight $memoryPitch $coordinate">;
def OpSubgroup2DBlockStoreINTEL: Op<6235, (outs),
(ins ID:$elementSize, ID:$blockWidth, ID:$blockHeight, ID:$blockCount, ID:$srcPointer, ID:$dstBasePointer, ID:$memoryWidth, ID:$memoryHeight, ID:$memoryPitch, ID:$coordinate),
"OpSubgroup2DBlockStoreINTEL $elementSize $blockWidth $blockHeight $blockCount $srcPointer $dstBasePointer $memoryWidth $memoryHeight $memoryPitch $coordinate">;
33 changes: 33 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Original file line number Diff line number Diff line change
@@ -1517,6 +1517,39 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(SPIRV::Capability::FunctionPointersINTEL);
}
break;

case SPIRV::OpSubgroup2DBlockLoadINTEL:
case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
case SPIRV::OpSubgroup2DBlockStoreINTEL: {
if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
report_fatal_error(
"OpSubgroup2DBlockLoadTransposeINTEL instruction requires the "
"following SPIR-V extension: SPV_INTEL_2d_block_io",
false);
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
Reqs.addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
break;
}
case SPIRV::OpSubgroup2DBlockLoadTransformINTEL: {
if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
report_fatal_error(
"OpSubgroup2DBlockLoadTransformINTEL instruction requires the "
"following SPIR-V extension: SPV_INTEL_2d_block_io",
false);
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
Reqs.addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
break;
}
case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL: {
if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
report_fatal_error(
"OpSubgroup2DBlockLoadTransposeINTEL instruction requires the "
"following SPIR-V extension: SPV_INTEL_2d_block_io",
false);
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
Reqs.addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
break;
}
case SPIRV::OpAtomicFAddEXT:
case SPIRV::OpAtomicFMinEXT:
case SPIRV::OpAtomicFMaxEXT:
4 changes: 4 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
@@ -313,6 +313,7 @@ defm SPV_INTEL_bindless_images : ExtensionOperand<116>;
defm SPV_INTEL_long_composites : ExtensionOperand<117>;
defm SPV_INTEL_memory_access_aliasing : ExtensionOperand<118>;
defm SPV_INTEL_fp_max_error : ExtensionOperand<119>;
defm SPV_INTEL_2d_block_io : ExtensionOperand<120>;

//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
@@ -513,6 +514,9 @@ defm LongCompositesINTEL : CapabilityOperand<6089, 0, 0, [SPV_INTEL_long_composi
defm BindlessImagesINTEL : CapabilityOperand<6528, 0, 0, [SPV_INTEL_bindless_images], []>;
defm MemoryAccessAliasingINTEL : CapabilityOperand<5910, 0, 0, [SPV_INTEL_memory_access_aliasing], []>;
defm FPMaxErrorINTEL : CapabilityOperand<6169, 0, 0, [SPV_INTEL_fp_max_error], []>;
defm Subgroup2DBlockIOINTEL : CapabilityOperand<6228, 0, 0, [SPV_INTEL_2d_block_io], []>;
defm Subgroup2DBlockTransformINTEL : CapabilityOperand<6229, 0, 0, [SPV_INTEL_2d_block_io], []>;
defm Subgroup2DBlockTransposeINTEL : CapabilityOperand<6230, 0, 0, [SPV_INTEL_2d_block_io], []>;

//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
; 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 void* 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, 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: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_2d_block_io %s -o %t.spt
; RUN: FileCheck %s --input-file=%t.spt
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_2d_block_io %s -o - -filetype=obj | spirv-val %}

; CHECK: OpCapability Subgroup2DBlockIOINTEL
; CHECK: OpCapability Subgroup2DBlockTransformINTEL
; CHECK: OpCapability Subgroup2DBlockTransposeINTEL
; CHECK: OpExtension "SPV_INTEL_2d_block_io"
; CHECK: %[[#Int8Ty:]] = OpTypeInt 8 0
; CHECK: %[[#GlbPtrTy:]] = OpTypePointer CrossWorkgroup %[[#Int8Ty]]
; CHECK: %[[#Int32Ty:]] = OpTypeInt 32 0
; CHECK: %[[#VectorTy:]] = OpTypeVector %[[#Int32Ty]] 2
; CHECK: %[[#PrvPtrTy:]] = OpTypePointer Function %[[#Int8Ty]]
; CHECK: %[[#VoidTy:]] = OpTypeVoid
; CHECK: %[[#Const42:]] = OpConstant %[[#Int32Ty]] 42
; CHECK: %[[#BaseSrc:]] = OpFunctionParameter %[[#GlbPtrTy]]
; CHECK: %[[#BaseDst:]] = OpFunctionParameter %[[#GlbPtrTy]]
; CHECK: %[[#Width:]] = OpFunctionParameter %[[#Int32Ty]]
; CHECK: %[[#Height:]] = OpFunctionParameter %[[#Int32Ty]]
; CHECK: %[[#Pitch:]] = OpFunctionParameter %[[#Int32Ty]]
; CHECK: %[[#Coord:]] = OpFunctionParameter %[[#VectorTy]]
; CHECK: %[[#Dst:]] = OpFunctionParameter %[[#PrvPtrTy]]
; CHECK: %[[#Src:]] = OpFunctionParameter %[[#PrvPtrTy]]
; CHECK: OpSubgroup2DBlockLoadINTEL %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#BaseSrc]] %[[#Width]] %[[#Height]] %[[#Pitch]] %[[#Coord]] %[[#Dst]]
; CHECK: OpSubgroup2DBlockLoadTransformINTEL %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#BaseSrc]] %[[#Width]] %[[#Height]] %[[#Pitch]] %[[#Coord]] %[[#Dst]]
; CHECK: OpSubgroup2DBlockLoadTransposeINTEL %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#BaseSrc]] %[[#Width]] %[[#Height]] %[[#Pitch]] %[[#Coord]] %[[#Dst]]
; CHECK: OpSubgroup2DBlockPrefetchINTEL %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#BaseSrc]] %[[#Width]] %[[#Height]] %[[#Pitch]] %[[#Coord]]
; CHECK: OpSubgroup2DBlockStoreINTEL %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#Const42]] %[[#Src]] %[[#BaseDst]] %[[#Width]] %[[#Height]] %[[#Pitch]] %[[#Coord]]



define spir_func void @foo(ptr addrspace(1) %base_address, ptr addrspace(1) %dst_base_pointer, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, ptr %dst_pointer, ptr %src_pointer) {
entry:
call spir_func void @_Z32__spirv_Subgroup2DBlockLoadINTELiiiiPU3AS1KviiiDv2_iPv(i32 42, i32 42, i32 42, i32 42, ptr addrspace(1) %base_address, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, ptr %dst_pointer)
call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransformINTELiiiiPU3AS1KviiiDv2_iPv(i32 42, i32 42, i32 42, i32 42, ptr addrspace(1) %base_address, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, ptr %dst_pointer)
call spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransposeINTELiiiiPU3AS1KviiiDv2_iPv(i32 42, i32 42, i32 42, i32 42, ptr addrspace(1) %base_address, i32 %width, i32 %height, i32 %pitch, <2 x i32> %coord, ptr %dst_pointer)
call spir_func void @_Z36__spirv_Subgroup2DBlockPrefetchINTELiiiiPU3AS1KviiiDv2_i(i32 42, i32 42, i32 42, i32 42, ptr 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, ptr %src_pointer, ptr 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, ptr addrspace(1), i32, i32, i32, <2 x i32>, ptr)
declare spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransformINTELiiiiPU3AS1KviiiDv2_iPv(i32, i32, i32, i32, ptr addrspace(1), i32, i32, i32, <2 x i32>, ptr)
declare spir_func void @_Z41__spirv_Subgroup2DBlockLoadTransposeINTELiiiiPU3AS1KviiiDv2_iPv(i32, i32, i32, i32, ptr addrspace(1), i32, i32, i32, <2 x i32>, ptr)
declare spir_func void @_Z36__spirv_Subgroup2DBlockPrefetchINTELiiiiPU3AS1KviiiDv2_i(i32, i32, i32, i32, ptr addrspace(1), i32, i32, i32, <2 x i32>)
declare spir_func void @_Z33__spirv_Subgroup2DBlockStoreINTELiiiiPKvPU3AS1viiiDv2_i(i32, i32, i32, i32, ptr, ptr 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 17.0.0"}
Loading
Oops, something went wrong.