-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[SPIR-V] Add SPV_INTEL_bindless_images extension #127737
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
Conversation
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]>
@llvm/pr-subscribers-backend-spir-v Author: Dmitry Sidorov (MrSidims) ChangesAdds instructions to convert convert unsigned integer handles to images, samplers and sampled images. Full diff: https://github.com/llvm/llvm-project/pull/127737.diff 8 Files Affected:
diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst
index b7601b26beb89..93c53a04bc447 100644
--- a/llvm/docs/SPIRVUsage.rst
+++ b/llvm/docs/SPIRVUsage.rst
@@ -155,6 +155,8 @@ list of supported SPIR-V extensions, sorted alphabetically by their extension na
- Adds atomic min and max instruction on floating-point numbers.
* - ``SPV_INTEL_arbitrary_precision_integers``
- Allows generating arbitrary width integer types.
+ * - ``SPV_INTEL_bindless_images``
+ - Adds instructions to convert convert unsigned integer handles to images, samplers and sampled images.
* - ``SPV_INTEL_bfloat16_conversion``
- Adds instructions to convert between single-precision 32-bit floating-point values and 16-bit bfloat16 values.
* - ``SPV_INTEL_cache_controls``
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 7b897f7e34c6f..df549f9fff2f9 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1043,6 +1043,37 @@ static bool buildExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
return true;
}
+/// Helper function for building Intel's bindless image instructions.
+static bool buildBindlessImageINTELInst(const SPIRV::IncomingCall *Call,
+ unsigned Opcode,
+ MachineIRBuilder &MIRBuilder,
+ SPIRVGlobalRegistry *GR) {
+ const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
+ const auto *ST =
+ static_cast<const SPIRVSubtarget *>(&MIRBuilder.getMF().getSubtarget());
+ if ((Opcode == SPIRV::OpConvertHandleToImageINTEL ||
+ Opcode == SPIRV::OpConvertHandleToSamplerINTEL ||
+ Opcode == SPIRV::OpConvertHandleToSampledImageINTEL) &&
+ !ST->canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images)) {
+ std::string DiagMsg = std::string(Builtin->Name) +
+ ": the builtin requires the following SPIR-V "
+ "extension: SPV_INTEL_bindless_images";
+ report_fatal_error(DiagMsg.c_str(), false);
+ }
+
+ // Generate SPIRV instruction accordingly.
+ if (Call->isSpirvOp())
+ return buildOpFromWrapper(MIRBuilder, Opcode, Call,
+ GR->getSPIRVTypeID(Call->ReturnType));
+
+ auto MIB = MIRBuilder.buildInstr(Opcode)
+ .addDef(Call->ReturnRegister)
+ .addUse(GR->getSPIRVTypeID(Call->ReturnType));
+ MIB.addUse(Call->Arguments[0]);
+
+ return true;
+}
+
static unsigned getNumComponentsForDim(SPIRV::Dim::Dim dim) {
switch (dim) {
case SPIRV::Dim::DIM_1D:
@@ -2232,6 +2263,17 @@ static bool generateExtendedBitOpsInst(const SPIRV::IncomingCall *Call,
return buildExtendedBitOpsInst(Call, Opcode, MIRBuilder, GR);
}
+static bool generateBindlessImageINTELInst(const SPIRV::IncomingCall *Call,
+ MachineIRBuilder &MIRBuilder,
+ SPIRVGlobalRegistry *GR) {
+ // Lookup the instruction opcode in the TableGen records.
+ const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
+ unsigned Opcode =
+ SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
+
+ return buildBindlessImageINTELInst(Call, Opcode, MIRBuilder, GR);
+}
+
static bool buildNDRange(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
@@ -2809,6 +2851,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
return generateCoopMatrInst(Call.get(), MIRBuilder, GR);
case SPIRV::ExtendedBitOps:
return generateExtendedBitOpsInst(Call.get(), MIRBuilder, GR);
+ case SPIRV::BindlessINTEL:
+ return generateBindlessImageINTELInst(Call.get(), MIRBuilder, GR);
}
return false;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
index 85f42fc08a4e0..c9a5c92ee3a66 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
@@ -66,6 +66,7 @@ def Construct : BuiltinGroup;
def CoopMatr : BuiltinGroup;
def ICarryBorrow : BuiltinGroup;
def ExtendedBitOps : BuiltinGroup;
+def BindlessINTEL : BuiltinGroup;
//===----------------------------------------------------------------------===//
// Class defining a demangled builtin record. The information in the record
@@ -708,6 +709,11 @@ defm : DemangledNativeBuiltin<"__spirv_CooperativeMatrixStoreCheckedINTEL", Open
defm : DemangledNativeBuiltin<"__spirv_CooperativeMatrixConstructCheckedINTEL", OpenCL_std, CoopMatr, 5, 5, OpCooperativeMatrixConstructCheckedINTEL>;
defm : DemangledNativeBuiltin<"__spirv_CooperativeMatrixGetElementCoordINTEL", OpenCL_std, CoopMatr, 2, 2, OpCooperativeMatrixGetElementCoordINTEL>;
+// SPV_INTEL_bindless_images builtin records:
+defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToImageINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToImageINTEL>;
+defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToSamplerINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToSamplerINTEL>;
+defm : DemangledNativeBuiltin<"__spirv_ConvertHandleToSampledImageINTEL", OpenCL_std, BindlessINTEL, 1, 1, OpConvertHandleToSampledImageINTEL>;
+
//===----------------------------------------------------------------------===//
// Class defining a work/sub group builtin that should be translated into a
// SPIR-V instruction using the defined properties.
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index 13683fd9a266d..2472e92b360be 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -71,6 +71,8 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::SPV_KHR_linkonce_odr},
{"SPV_INTEL_inline_assembly",
SPIRV::Extension::Extension::SPV_INTEL_inline_assembly},
+ {"SPV_INTEL_bindless_images",
+ SPIRV::Extension::Extension::SPV_INTEL_bindless_images},
{"SPV_INTEL_bfloat16_conversion",
SPIRV::Extension::Extension::SPV_INTEL_bfloat16_conversion},
{"SPV_KHR_subgroup_rotate",
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index 981e224a66399..65cf14fc93864 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -931,3 +931,11 @@ def OpCooperativeMatrixPrefetchINTEL: Op<6449, (outs),
// SPV_EXT_arithmetic_fence
def OpArithmeticFenceEXT: Op<6145, (outs ID:$res), (ins TYPE:$type, ID:$target),
"$res = OpArithmeticFenceEXT $type $target">;
+
+// SPV_INTEL_bindless_images
+def OpConvertHandleToImageINTEL: Op<6529, (outs ID:$res), (ins TYPE:$type, ID:$operand),
+ "$res = OpConvertHandleToImageINTEL $type $operand">;
+def OpConvertHandleToSamplerINTEL: Op<6530, (outs ID:$res), (ins TYPE:$type, ID:$operand),
+ "$res = OpConvertHandleToSamplerINTEL $type $operand">;
+def OpConvertHandleToSampledImageINTEL: Op<6531, (outs ID:$res), (ins TYPE:$type, ID:$operand),
+ "$res = OpConvertHandleToSampledImageINTEL $type $operand">;
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index a7a5ecead6f5f..0db046ebed963 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1677,6 +1677,15 @@ void addInstrRequirements(const MachineInstr &MI,
Reqs.addCapability(
SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
break;
+ case SPIRV::OpConvertHandleToImageINTEL:
+ case SPIRV::OpConvertHandleToSamplerINTEL:
+ case SPIRV::OpConvertHandleToSampledImageINTEL:
+ if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
+ report_fatal_error("Intel bindless images handles require the following "
+ "SPIR-V extension: SPV_INTEL_bindless_images", false);
+ Reqs.addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
+ Reqs.addCapability(SPIRV::Capability::BindlessImagesINTEL);
+ break;
case SPIRV::OpKill: {
Reqs.addCapability(SPIRV::Capability::Shader);
} break;
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index fec3cb0091bf5..ada19a40c42f1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -309,6 +309,7 @@ defm SPV_EXT_arithmetic_fence : ExtensionOperand<112>;
defm SPV_EXT_optnone : ExtensionOperand<113>;
defm SPV_INTEL_joint_matrix : ExtensionOperand<114>;
defm SPV_INTEL_float_controls2 : ExtensionOperand<115>;
+defm SPV_INTEL_bindless_images : ExtensionOperand<116>;
//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
@@ -505,6 +506,7 @@ defm CooperativeMatrixBFloat16ComponentTypeINTEL : CapabilityOperand<6437, 0, 0,
defm RoundToInfinityINTEL : CapabilityOperand<5582, 0, 0, [SPV_INTEL_float_controls2], []>;
defm FloatingPointModeINTEL : CapabilityOperand<5583, 0, 0, [SPV_INTEL_float_controls2], []>;
defm FunctionFloatControlINTEL : CapabilityOperand<5821, 0, 0, [SPV_INTEL_float_controls2], []>;
+defm BindlessImagesINTEL : CapabilityOperand<6528, 0, 0, [SPV_INTEL_bindless_images], []>;
//===----------------------------------------------------------------------===//
// Multiclass used to define SourceLanguage enum values and at the same time
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bindless_images/bindless_images_generic.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bindless_images/bindless_images_generic.ll
new file mode 100644
index 0000000000000..a24340529eaea
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_bindless_images/bindless_images_generic.ll
@@ -0,0 +1,33 @@
+; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown %s -o %t.spvt 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_bindless_images %s -o - | FileCheck %s
+
+; CHECK-ERROR: LLVM ERROR: __spirv_ConvertHandleToImageINTEL: the builtin requires the following SPIR-V extension: SPV_INTEL_bindless_images
+
+; CHECK: OpCapability BindlessImagesINTEL
+; CHECK: OpExtension "SPV_INTEL_bindless_images"
+
+; CHECK-DAG: %[[#VoidTy:]] = OpTypeVoid
+; CHECK-DAG: %[[#Int64Ty:]] = OpTypeInt 64
+; CHECK-DAG: %[[#Const42:]] = OpConstant %[[#Int64Ty]] 42
+; CHECK-DAG: %[[#Const43:]] = OpConstant %[[#Int64Ty]] 43
+; CHECK-DAG: %[[#IntImgTy:]] = OpTypeImage %[[#Int64Ty]]
+; CHECK-DAG: %[[#SamplerTy:]] = OpTypeSampler
+; CHECK-DAG: %[[#IntSmpImgTy:]] = OpTypeImage %[[#Int64Ty]]
+; CHECK-DAG: %[[#SampImageTy:]] = OpTypeSampledImage %[[#IntSmpImgTy]]
+; CHECK: %[[#Input:]] = OpFunctionParameter %[[#Int64Ty]]
+; CHECK: %[[#]] = OpConvertHandleToImageINTEL %[[#IntImgTy]] %[[#Input]]
+; CHECK: %[[#]] = OpConvertHandleToSamplerINTEL %[[#SamplerTy]] %[[#Const42]]
+; CHECK: %[[#]] = OpConvertHandleToSampledImageINTEL %[[#SampImageTy]] %[[#Const43]]
+
+define spir_func void @foo(i64 %in) {
+ %img = call spir_func target("spirv.Image", i64, 2, 0, 0, 0, 0, 0, 0) @_Z33__spirv_ConvertHandleToImageINTELl(i64 %in)
+ %samp = call spir_func target("spirv.Sampler") @_Z35__spirv_ConvertHandleToSamplerINTELl(i64 42)
+ %sampImage = call spir_func target("spirv.SampledImage", i64, 1, 0, 0, 0, 0, 0, 0) @_Z40__spirv_ConvertHandleToSampledImageINTELl(i64 43)
+ ret void
+}
+
+declare spir_func target("spirv.Image", i64, 2, 0, 0, 0, 0, 0, 0) @_Z33__spirv_ConvertHandleToImageINTELl(i64)
+
+declare spir_func target("spirv.Sampler") @_Z35__spirv_ConvertHandleToSamplerINTELl(i64)
+
+declare spir_func target("spirv.SampledImage", i64, 1, 0, 0, 0, 0, 0, 0) @_Z40__spirv_ConvertHandleToSampledImageINTELl(i64)
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @MrSidims , looks great, just a complaint from the code formatter and a nit question
Signed-off-by: Sidorov, Dmitry <[email protected]>
Signed-off-by: Sidorov, Dmitry <[email protected]>
Fix warning after #127737 Signed-off-by: Sidorov, Dmitry <[email protected]>
Fix warning after llvm/llvm-project#127737 Signed-off-by: Sidorov, Dmitry <[email protected]>
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