Skip to content

Commit 55fa2fa

Browse files
authored
[SPIR-V] Add SPV_INTEL_bindless_images extension (#127737)
Adds instructions to convert convert unsigned integer handles to images, samplers and sampled images. Spec: https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_bindless_images.asciidoc --------- Signed-off-by: Sidorov, Dmitry <[email protected]>
1 parent e264317 commit 55fa2fa

File tree

8 files changed

+96
-0
lines changed

8 files changed

+96
-0
lines changed

llvm/docs/SPIRVUsage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
155155
- Adds atomic min and max instruction on floating-point numbers.
156156
* - ``SPV_INTEL_arbitrary_precision_integers``
157157
- Allows generating arbitrary width integer types.
158+
* - ``SPV_INTEL_bindless_images``
159+
- Adds instructions to convert convert unsigned integer handles to images, samplers and sampled images.
158160
* - ``SPV_INTEL_bfloat16_conversion``
159161
- Adds instructions to convert between single-precision 32-bit floating-point values and 16-bit bfloat16 values.
160162
* - ``SPV_INTEL_cache_controls``

llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,24 @@ static bool buildExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
10431043
return true;
10441044
}
10451045

1046+
/// Helper function for building Intel's bindless image instructions.
1047+
static bool buildBindlessImageINTELInst(const SPIRV::IncomingCall *Call,
1048+
unsigned Opcode,
1049+
MachineIRBuilder &MIRBuilder,
1050+
SPIRVGlobalRegistry *GR) {
1051+
// Generate SPIRV instruction accordingly.
1052+
if (Call->isSpirvOp())
1053+
return buildOpFromWrapper(MIRBuilder, Opcode, Call,
1054+
GR->getSPIRVTypeID(Call->ReturnType));
1055+
1056+
auto MIB = MIRBuilder.buildInstr(Opcode)
1057+
.addDef(Call->ReturnRegister)
1058+
.addUse(GR->getSPIRVTypeID(Call->ReturnType))
1059+
.addUse(Call->Arguments[0]);
1060+
1061+
return true;
1062+
}
1063+
10461064
static unsigned getNumComponentsForDim(SPIRV::Dim::Dim dim) {
10471065
switch (dim) {
10481066
case SPIRV::Dim::DIM_1D:
@@ -2232,6 +2250,17 @@ static bool generateExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
22322250
return buildExtendedBitOpsInst(Call, Opcode, MIRBuilder, GR);
22332251
}
22342252

2253+
static bool generateBindlessImageINTELInst(const SPIRV::IncomingCall *Call,
2254+
MachineIRBuilder &MIRBuilder,
2255+
SPIRVGlobalRegistry *GR) {
2256+
// Lookup the instruction opcode in the TableGen records.
2257+
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
2258+
unsigned Opcode =
2259+
SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
2260+
2261+
return buildBindlessImageINTELInst(Call, Opcode, MIRBuilder, GR);
2262+
}
2263+
22352264
static bool buildNDRange(const SPIRV::IncomingCall *Call,
22362265
MachineIRBuilder &MIRBuilder,
22372266
SPIRVGlobalRegistry *GR) {
@@ -2809,6 +2838,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
28092838
return generateCoopMatrInst(Call.get(), MIRBuilder, GR);
28102839
case SPIRV::ExtendedBitOps:
28112840
return generateExtendedBitOpsInst(Call.get(), MIRBuilder, GR);
2841+
case SPIRV::BindlessINTEL:
2842+
return generateBindlessImageINTELInst(Call.get(), MIRBuilder, GR);
28122843
}
28132844
return false;
28142845
}

llvm/lib/Target/SPIRV/SPIRVBuiltins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def Construct : BuiltinGroup;
6666
def CoopMatr : BuiltinGroup;
6767
def ICarryBorrow : BuiltinGroup;
6868
def ExtendedBitOps : BuiltinGroup;
69+
def BindlessINTEL : BuiltinGroup;
6970

7071
//===----------------------------------------------------------------------===//
7172
// Class defining a demangled builtin record. The information in the record
@@ -708,6 +709,11 @@ defm : DemangledNativeBuiltin<"__spirv_CooperativeMatrixStoreCheckedINTEL", Open
708709
defm : DemangledNativeBuiltin<"__spirv_CooperativeMatrixConstructCheckedINTEL", OpenCL_std, CoopMatr, 5, 5, OpCooperativeMatrixConstructCheckedINTEL>;
709710
defm : DemangledNativeBuiltin<"__spirv_CooperativeMatrixGetElementCoordINTEL", OpenCL_std, CoopMatr, 2, 2, OpCooperativeMatrixGetElementCoordINTEL>;
710711

712+
// SPV_INTEL_bindless_images builtin records:
713+
defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToImageINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToImageINTEL>;
714+
defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToSamplerINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToSamplerINTEL>;
715+
defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToSampledImageINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToSampledImageINTEL>;
716+
711717
//===----------------------------------------------------------------------===//
712718
// Class defining a work/sub group builtin that should be translated into a
713719
// SPIR-V instruction using the defined properties.

llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
7171
SPIRV::Extension::Extension::SPV_KHR_linkonce_odr},
7272
{"SPV_INTEL_inline_assembly",
7373
SPIRV::Extension::Extension::SPV_INTEL_inline_assembly},
74+
{"SPV_INTEL_bindless_images",
75+
SPIRV::Extension::Extension::SPV_INTEL_bindless_images},
7476
{"SPV_INTEL_bfloat16_conversion",
7577
SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion},
7678
{"SPV_KHR_subgroup_rotate",

llvm/lib/Target/SPIRV/SPIRVInstrInfo.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,3 +931,11 @@ def OpCooperativeMatrixPrefetchINTEL: Op<6449, (outs),
931931
// SPV_EXT_arithmetic_fence
932932
def OpArithmeticFenceEXT: Op<6145, (outs ID:$res), (ins TYPE:$type, ID:$target),
933933
"$res = OpArithmeticFenceEXT $type $target">;
934+
935+
// SPV_INTEL_bindless_images
936+
def OpConvertHandleToImageINTEL: Op<6529, (outs ID:$res), (ins TYPE:$type, ID:$operand),
937+
"$res = OpConvertHandleToImageINTEL $type $operand">;
938+
def OpConvertHandleToSamplerINTEL: Op<6530, (outs ID:$res), (ins TYPE:$type, ID:$operand),
939+
"$res = OpConvertHandleToSamplerINTEL $type $operand">;
940+
def OpConvertHandleToSampledImageINTEL: Op<6531, (outs ID:$res), (ins TYPE:$type, ID:$operand),
941+
"$res = OpConvertHandleToSampledImageINTEL $type $operand">;

llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,17 @@ void addInstrRequirements(const MachineInstr &MI,
16771677
Reqs.addCapability(
16781678
SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
16791679
break;
1680+
case SPIRV::OpConvertHandleToImageINTEL:
1681+
case SPIRV::OpConvertHandleToSamplerINTEL:
1682+
case SPIRV::OpConvertHandleToSampledImageINTEL:
1683+
if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
1684+
report_fatal_error("OpConvertHandleTo[Image/Sampler/SampledImage]INTEL "
1685+
"instructions require the following SPIR-V extension: "
1686+
"SPV_INTEL_bindless_images",
1687+
false);
1688+
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
1689+
Reqs.addCapability(SPIRV::Capability::BindlessImagesINTEL);
1690+
break;
16801691
case SPIRV::OpKill: {
16811692
Reqs.addCapability(SPIRV::Capability::Shader);
16821693
} break;

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ defm SPV_EXT_arithmetic_fence : ExtensionOperand<112>;
309309
defm SPV_EXT_optnone : ExtensionOperand<113>;
310310
defm SPV_INTEL_joint_matrix : ExtensionOperand<114>;
311311
defm SPV_INTEL_float_controls2 : ExtensionOperand<115>;
312+
defm SPV_INTEL_bindless_images : ExtensionOperand<116>;
312313

313314
//===----------------------------------------------------------------------===//
314315
// Multiclass used to define Capabilities enum values and at the same time
@@ -505,6 +506,7 @@ defm CooperativeMatrixBFloat16ComponentTypeINTEL : CapabilityOperand<6437, 0, 0,
505506
defm RoundToInfinityINTEL : CapabilityOperand<5582, 0, 0, [SPV_INTEL_float_controls2], []>;
506507
defm FloatingPointModeINTEL : CapabilityOperand<5583, 0, 0, [SPV_INTEL_float_controls2], []>;
507508
defm FunctionFloatControlINTEL : CapabilityOperand<5821, 0, 0, [SPV_INTEL_float_controls2], []>;
509+
defm BindlessImagesINTEL : CapabilityOperand<6528, 0, 0, [SPV_INTEL_bindless_images], []>;
508510

509511
//===----------------------------------------------------------------------===//
510512
// Multiclass used to define SourceLanguage enum values and at the same time
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
2+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bindless_images %s -o - | FileCheck %s
3+
4+
; CHECK-ERROR: LLVM ERROR: OpConvertHandleTo[Image/Sampler/SampledImage]INTEL instruction
5+
; CHECK-ERROR-SAME: require the following SPIR-V extension: SPV_INTEL_bindless_images
6+
7+
; CHECK: OpCapability BindlessImagesINTEL
8+
; CHECK: OpExtension "SPV_INTEL_bindless_images"
9+
10+
; CHECK-DAG: %[[#VoidTy:]] = OpTypeVoid
11+
; CHECK-DAG: %[[#Int64Ty:]] = OpTypeInt 64
12+
; CHECK-DAG: %[[#Const42:]] = OpConstant %[[#Int64Ty]] 42
13+
; CHECK-DAG: %[[#Const43:]] = OpConstant %[[#Int64Ty]] 43
14+
; CHECK-DAG: %[[#IntImgTy:]] = OpTypeImage %[[#Int64Ty]]
15+
; CHECK-DAG: %[[#SamplerTy:]] = OpTypeSampler
16+
; CHECK-DAG: %[[#IntSmpImgTy:]] = OpTypeImage %[[#Int64Ty]]
17+
; CHECK-DAG: %[[#SampImageTy:]] = OpTypeSampledImage %[[#IntSmpImgTy]]
18+
; CHECK: %[[#Input:]] = OpFunctionParameter %[[#Int64Ty]]
19+
; CHECK: %[[#]] = OpConvertHandleToImageINTEL %[[#IntImgTy]] %[[#Input]]
20+
; CHECK: %[[#]] = OpConvertHandleToSamplerINTEL %[[#SamplerTy]] %[[#Const42]]
21+
; CHECK: %[[#]] = OpConvertHandleToSampledImageINTEL %[[#SampImageTy]] %[[#Const43]]
22+
23+
define spir_func void @foo(i64 %in) {
24+
%img = call spir_func target("spirv.Image", i64, 2, 0, 0, 0, 0, 0, 0) @_Z33__spirv_ConvertHandleToImageINTELl(i64 %in)
25+
%samp = call spir_func target("spirv.Sampler") @_Z35__spirv_ConvertHandleToSamplerINTELl(i64 42)
26+
%sampImage = call spir_func target("spirv.SampledImage", i64, 1, 0, 0, 0, 0, 0, 0) @_Z40__spirv_ConvertHandleToSampledImageINTELl(i64 43)
27+
ret void
28+
}
29+
30+
declare spir_func target("spirv.Image", i64, 2, 0, 0, 0, 0, 0, 0) @_Z33__spirv_ConvertHandleToImageINTELl(i64)
31+
32+
declare spir_func target("spirv.Sampler") @_Z35__spirv_ConvertHandleToSamplerINTELl(i64)
33+
34+
declare spir_func target("spirv.SampledImage", i64, 1, 0, 0, 0, 0, 0, 0) @_Z40__spirv_ConvertHandleToSampledImageINTELl(i64)

0 commit comments

Comments
 (0)