Skip to content

Commit 6397d6f

Browse files
committed
[SPIR-V] SPV_INTEL_bindless_images
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 738f3a1 commit 6397d6f

File tree

8 files changed

+106
-0
lines changed

8 files changed

+106
-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: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,37 @@ 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+
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
1052+
const auto *ST =
1053+
static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
1054+
if ((Opcode == SPIRV::OpConvertHandleToImageINTEL ||
1055+
Opcode == SPIRV::OpConvertHandleToSamplerINTEL ||
1056+
Opcode == SPIRV::OpConvertHandleToSampledImageINTEL) &&
1057+
!ST->canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images)) {
1058+
std::string DiagMsg = std::string(Builtin->Name) +
1059+
": the builtin requires the following SPIR-V "
1060+
"extension: SPV_INTEL_bindless_images";
1061+
report_fatal_error(DiagMsg.c_str(), false);
1062+
}
1063+
1064+
// Generate SPIRV instruction accordingly.
1065+
if (Call->isSpirvOp())
1066+
return buildOpFromWrapper(MIRBuilder, Opcode, Call,
1067+
GR->getSPIRVTypeID(Call->ReturnType));
1068+
1069+
auto MIB = MIRBuilder.buildInstr(Opcode)
1070+
.addDef(Call->ReturnRegister)
1071+
.addUse(GR->getSPIRVTypeID(Call->ReturnType));
1072+
MIB.addUse(Call->Arguments[0]);
1073+
1074+
return true;
1075+
}
1076+
10461077
static unsigned getNumComponentsForDim(SPIRV::Dim::Dim dim) {
10471078
switch (dim) {
10481079
case SPIRV::Dim::DIM_1D:
@@ -2232,6 +2263,17 @@ static bool generateExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
22322263
return buildExtendedBitOpsInst(Call, Opcode, MIRBuilder, GR);
22332264
}
22342265

2266+
static bool generateBindlessImageINTELInst(const SPIRV::IncomingCall *Call,
2267+
MachineIRBuilder &MIRBuilder,
2268+
SPIRVGlobalRegistry *GR) {
2269+
// Lookup the instruction opcode in the TableGen records.
2270+
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
2271+
unsigned Opcode =
2272+
SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
2273+
2274+
return buildBindlessImageINTELInst(Call, Opcode, MIRBuilder, GR);
2275+
}
2276+
22352277
static bool buildNDRange(const SPIRV::IncomingCall *Call,
22362278
MachineIRBuilder &MIRBuilder,
22372279
SPIRVGlobalRegistry *GR) {
@@ -2809,6 +2851,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
28092851
return generateCoopMatrInst(Call.get(), MIRBuilder, GR);
28102852
case SPIRV::ExtendedBitOps:
28112853
return generateExtendedBitOpsInst(Call.get(), MIRBuilder, GR);
2854+
case SPIRV::BindlessINTEL:
2855+
return generateBindlessImageINTELInst(Call.get(), MIRBuilder, GR);
28122856
}
28132857
return false;
28142858
}

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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,15 @@ 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("Intel bindless images handles require the following "
1685+
"SPIR-V extension: SPV_INTEL_bindless_images", false);
1686+
Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
1687+
Reqs.addCapability(SPIRV::Capability::BindlessImagesINTEL);
1688+
break;
16801689
case SPIRV::OpKill: {
16811690
Reqs.addCapability(SPIRV::Capability::Shader);
16821691
} 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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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: __spirv_ConvertHandleToImageINTEL: the builtin requires the following SPIR-V extension: SPV_INTEL_bindless_images
5+
6+
; CHECK: OpCapability BindlessImagesINTEL
7+
; CHECK: OpExtension "SPV_INTEL_bindless_images"
8+
9+
; CHECK-DAG: %[[#VoidTy:]] = OpTypeVoid
10+
; CHECK-DAG: %[[#Int64Ty:]] = OpTypeInt 64
11+
; CHECK-DAG: %[[#Const42:]] = OpConstant %[[#Int64Ty]] 42
12+
; CHECK-DAG: %[[#Const43:]] = OpConstant %[[#Int64Ty]] 43
13+
; CHECK-DAG: %[[#IntImgTy:]] = OpTypeImage %[[#Int64Ty]]
14+
; CHECK-DAG: %[[#SamplerTy:]] = OpTypeSampler
15+
; CHECK-DAG: %[[#IntSmpImgTy:]] = OpTypeImage %[[#Int64Ty]]
16+
; CHECK-DAG: %[[#SampImageTy:]] = OpTypeSampledImage %[[#IntSmpImgTy]]
17+
; CHECK: %[[#Input:]] = OpFunctionParameter %[[#Int64Ty]]
18+
; CHECK: %[[#]] = OpConvertHandleToImageINTEL %[[#IntImgTy]] %[[#Input]]
19+
; CHECK: %[[#]] = OpConvertHandleToSamplerINTEL %[[#SamplerTy]] %[[#Const42]]
20+
; CHECK: %[[#]] = OpConvertHandleToSampledImageINTEL %[[#SampImageTy]] %[[#Const43]]
21+
22+
define spir_func void @foo(i64 %in) {
23+
%img = call spir_func target("spirv.Image", i64, 2, 0, 0, 0, 0, 0, 0) @_Z33__spirv_ConvertHandleToImageINTELl(i64 %in)
24+
%samp = call spir_func target("spirv.Sampler") @_Z35__spirv_ConvertHandleToSamplerINTELl(i64 42)
25+
%sampImage = call spir_func target("spirv.SampledImage", i64, 1, 0, 0, 0, 0, 0, 0) @_Z40__spirv_ConvertHandleToSampledImageINTELl(i64 43)
26+
ret void
27+
}
28+
29+
declare spir_func target("spirv.Image", i64, 2, 0, 0, 0, 0, 0, 0) @_Z33__spirv_ConvertHandleToImageINTELl(i64)
30+
31+
declare spir_func target("spirv.Sampler") @_Z35__spirv_ConvertHandleToSamplerINTELl(i64)
32+
33+
declare spir_func target("spirv.SampledImage", i64, 1, 0, 0, 0, 0, 0, 0) @_Z40__spirv_ConvertHandleToSampledImageINTELl(i64)

0 commit comments

Comments
 (0)