[llvm] [SPIRV] Support for the extension SPV_EXT_image_raw10_raw12 (PR #160032)
Aadesh Premkumar via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 21 22:23:05 PDT 2025
https://github.com/aadeshps-mcw created https://github.com/llvm/llvm-project/pull/160032
--Added support for SPV_EXT_image_raw10_raw12 extension.
>From 5752f0670c4cad89f7dc29284096391eb6244a2b Mon Sep 17 00:00:00 2001
From: Aadesh PremKumar <aadesh.premkumar at multicorewareinc.com>
Date: Thu, 28 Aug 2025 14:17:26 +0530
Subject: [PATCH] --Added support for SPV_EXT_image_raw10_raw12 extension.
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 30 +++++++++++++
llvm/lib/Target/SPIRV/SPIRVBuiltins.td | 2 +
llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp | 4 +-
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 43 ++++++++++++++++++
.../lib/Target/SPIRV/SPIRVSymbolicOperands.td | 3 ++
.../SPV_EXT_image_raw10_raw12/constant_use.ll | 32 +++++++++++++
.../SPV_EXT_image_raw10_raw12/writer.ll | 45 +++++++++++++++++++
7 files changed, 158 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/constant_use.ll
create mode 100644 llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/writer.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 2abd9d36f7606..b00e7c34c09d5 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1078,6 +1078,23 @@ static bool buildTernaryBitwiseFunctionINTELInst(
return true;
}
+static bool buildImageChannelDataTypeInst(const SPIRV::IncomingCall *Call,
+ unsigned Opcode,
+ MachineIRBuilder &MIRBuilder,
+ SPIRVGlobalRegistry *GR) {
+ 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));
+ for (unsigned i = 0; i < Call->Arguments.size(); ++i)
+ MIB.addUse(Call->Arguments[i]);
+
+ return true;
+}
+
/// Helper function for building Intel's 2d block io instructions.
static bool build2DBlockIOINTELInst(const SPIRV::IncomingCall *Call,
unsigned Opcode,
@@ -2339,6 +2356,17 @@ generateTernaryBitwiseFunctionINTELInst(const SPIRV::IncomingCall *Call,
return buildTernaryBitwiseFunctionINTELInst(Call, Opcode, MIRBuilder, GR);
}
+static bool generateImageChannelDataTypeInst(const SPIRV::IncomingCall *Call,
+ MachineIRBuilder &MIRBuilder,
+ SPIRVGlobalRegistry *GR) {
+ const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
+ unsigned Opcode =
+ SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
+
+
+ return buildImageChannelDataTypeInst(Call, Opcode, MIRBuilder, GR);
+}
+
static bool generate2DBlockIOINTELInst(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
@@ -2948,6 +2976,8 @@ std::optional<bool> lowerBuiltin(const StringRef DemangledCall,
return generateTernaryBitwiseFunctionINTELInst(Call.get(), MIRBuilder, GR);
case SPIRV::Block2DLoadStore:
return generate2DBlockIOINTELInst(Call.get(), MIRBuilder, GR);
+ case SPIRV::ImageChannelDataTypes:
+ return generateImageChannelDataTypeInst(Call.get(), MIRBuilder, GR);
}
return false;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
index d08560bb6565a..31cec3417b59d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
@@ -69,6 +69,7 @@ def ExtendedBitOps : BuiltinGroup;
def BindlessINTEL : BuiltinGroup;
def TernaryBitwiseINTEL : BuiltinGroup;
def Block2DLoadStore : BuiltinGroup;
+def ImageChannelDataTypes : BuiltinGroup;
//===----------------------------------------------------------------------===//
// Class defining a demangled builtin record. The information in the record
@@ -1445,6 +1446,7 @@ defm : DemangledImageQueryBuiltin<"get_image_array_size", OpenCL_std, 3>;
defm : DemangledNativeBuiltin<"get_image_num_samples", OpenCL_std, ImageMiscQuery, 1, 1, OpImageQuerySamples>;
defm : DemangledNativeBuiltin<"get_image_num_mip_levels", OpenCL_std, ImageMiscQuery, 1, 1, OpImageQueryLevels>;
+defm : DemangledNativeBuiltin<"get_image_channel_data_type", OpenCL_std, ImageChannelDataTypes, 1, 1, OpImageQueryFormat>;
//===----------------------------------------------------------------------===//
// Class defining a "convert_destType<_sat><_roundingMode>" call record for
diff --git a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
index e7da5504b2d58..4526468be014d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
@@ -147,7 +147,9 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
{"SPV_KHR_float_controls2",
SPIRV::Extension::Extension::SPV_KHR_float_controls2},
{"SPV_INTEL_tensor_float32_conversion",
- SPIRV::Extension::Extension::SPV_INTEL_tensor_float32_conversion}};
+ SPIRV::Extension::Extension::SPV_INTEL_tensor_float32_conversion},
+ {"SPV_EXT_image_raw10_raw12",
+ SPIRV::Extension::Extension::SPV_EXT_image_raw10_raw12}};
bool SPIRVExtensionsParser::parse(cl::Option &O, StringRef ArgName,
StringRef ArgValue,
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 8039cf0c432fa..45be657547ed0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1432,6 +1432,49 @@ void addInstrRequirements(const MachineInstr &MI,
}
break;
}
+ case SPIRV::OpImageQueryFormat: {
+ Register ResultReg = MI.getOperand(0).getReg();
+ const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
+ static const unsigned CompareOps[] = {
+ SPIRV::OpIEqual, SPIRV::OpINotEqual,
+ SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
+ SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
+ SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
+ SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
+
+ auto CheckAndAddExtension = [&](int64_t ImmVal) {
+ if (ImmVal == 4323 || ImmVal == 4324) {
+ if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
+ Reqs.addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
+ else
+ report_fatal_error("This requires the "
+ "SPV_EXT_image_raw10_raw12 extension");
+ }
+ };
+
+ for (MachineInstr &UseInst : MRI.use_instructions(ResultReg)) {
+ unsigned Opc = UseInst.getOpcode();
+
+ if (Opc == SPIRV::OpSwitch) {
+ for (const MachineOperand &Op : UseInst.operands())
+ if (Op.isImm())
+ CheckAndAddExtension(Op.getImm());
+ }
+ else if (llvm::is_contained(CompareOps, Opc)) {
+ for (unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
+ Register UseReg = UseInst.getOperand(i).getReg();
+ MachineInstr *ConstInst = MRI.getVRegDef(UseReg);
+ if (ConstInst && ConstInst->getOpcode() == SPIRV::OpConstantI) {
+ int64_t ImmVal = ConstInst->getOperand(2).getImm();
+ if (ImmVal)
+ CheckAndAddExtension(ImmVal);
+ }
+ }
+ }
+ }
+ break;
+ }
+
case SPIRV::OpGroupNonUniformShuffle:
case SPIRV::OpGroupNonUniformShuffleXor:
Reqs.addCapability(SPIRV::Capability::GroupNonUniformShuffle);
diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
index d2824ee2d2caf..51ddafa08663f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
+++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
@@ -382,6 +382,7 @@ defm SPV_INTEL_2d_block_io : ExtensionOperand<122, [EnvOpenCL]>;
defm SPV_INTEL_int4 : ExtensionOperand<123, [EnvOpenCL]>;
defm SPV_KHR_float_controls2 : ExtensionOperand<124, [EnvVulkan, EnvOpenCL]>;
defm SPV_INTEL_tensor_float32_conversion : ExtensionOperand<125, [EnvOpenCL]>;
+defm SPV_EXT_image_raw10_raw12 :ExtensionOperand<126, [EnvOpenCL]>;
//===----------------------------------------------------------------------===//
// Multiclass used to define Capabilities enum values and at the same time
@@ -1078,6 +1079,8 @@ defm HalfFloat : ImageChannelDataTypeOperand<13, [Kernel]>;
defm Float : ImageChannelDataTypeOperand<14, [Kernel]>;
defm UnormInt24 : ImageChannelDataTypeOperand<15, [Kernel]>;
defm UnormInt101010_2 : ImageChannelDataTypeOperand<16, [Kernel]>;
+defm UnsignedIntRaw10EXT : ImageChannelDataTypeOperand<17, [Kernel]>;
+defm UnsignedIntRaw12EXT : ImageChannelDataTypeOperand<18, [Kernel]>;
//===----------------------------------------------------------------------===//
// Multiclass used to define ImageOperand enum values and at the same time
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/constant_use.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/constant_use.ll
new file mode 100644
index 0000000000000..680a74f89b1d9
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/constant_use.ll
@@ -0,0 +1,32 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_EXT_image_raw10_raw12 %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s --spirv-ext=+SPV_EXT_image_raw10_raw12 -o - -filetype=obj | spirv-val %}
+
+; CHECK-NOT: OpExtension "SPV_EXT_image_raw10_raw12"
+
+define dso_local spir_kernel void @test_raw1012(ptr addrspace(1) noundef writeonly align 4 captures(none) %dst, i32 noundef %value) {
+entry:
+ switch i32 %value, label %sw.epilog [
+ i32 4323, label %sw.epilog.sink.split
+ i32 4324, label %sw.bb1
+ ]
+
+sw.bb1:
+ br label %sw.epilog.sink.split
+
+sw.epilog.sink.split:
+ %.sink = phi i32 [ 12, %sw.bb1 ], [ 10, %entry ]
+ store i32 %.sink, ptr addrspace(1) %dst, align 4
+ br label %sw.epilog
+
+sw.epilog:
+ %0 = add i32 %value, -4323
+ %or.cond = icmp ult i32 %0, 2
+ br i1 %or.cond, label %if.then, label %if.end
+
+if.then:
+ store i32 1012, ptr addrspace(1) %dst, align 4
+ br label %if.end
+
+if.end:
+ ret void
+}
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/writer.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/writer.ll
new file mode 100644
index 0000000000000..41f6940d06782
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_image_raw10_raw12/writer.ll
@@ -0,0 +1,45 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_EXT_image_raw10_raw12 %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s --spirv-ext=+SPV_EXT_image_raw10_raw12 -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpExtension "SPV_EXT_image_raw10_raw12"
+
+ define dso_local spir_kernel void @test_raw1012(ptr addrspace(1) noundef writeonly align 4 captures(none) %dst, target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) %img) {
+ entry:
+ %call = tail call spir_func i32 @_Z27get_image_channel_data_type14ocl_image2d_ro(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) %img)
+ switch i32 %call, label %sw.epilog [
+ i32 4304, label %sw.epilog.sink.split
+ i32 4323, label %sw.bb1
+ i32 4324, label %sw.bb2
+ ]
+
+ sw.bb1:
+ br label %sw.epilog.sink.split
+
+ sw.bb2:
+ br label %sw.epilog.sink.split
+
+ sw.epilog.sink.split:
+ %.sink = phi i32 [ 12, %sw.bb2 ], [ 10, %sw.bb1 ], [ 8, %entry ]
+ store i32 %.sink, ptr addrspace(1) %dst, align 4
+ br label %sw.epilog
+
+ sw.epilog:
+ %call3 = tail call spir_func i32 @_Z27get_image_channel_data_type14ocl_image2d_ro(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) %img)
+ %cmp = icmp eq i32 %call3, 4323
+ br i1 %cmp, label %if.end7.sink.split, label %if.else
+
+ if.else:
+ %call4 = tail call spir_func i32 @_Z27get_image_channel_data_type14ocl_image2d_ro(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0) %img)
+ %cmp5 = icmp eq i32 %call4, 4324
+ br i1 %cmp5, label %if.end7.sink.split, label %if.end7
+
+ if.end7.sink.split:
+ %.sink14 = phi i32 [ 1010, %sw.epilog ], [ 1212, %if.else ]
+ store i32 %.sink14, ptr addrspace(1) %dst, align 4
+ br label %if.end7
+
+ if.end7:
+ ret void
+ }
+
+ declare spir_func i32 @_Z27get_image_channel_data_type14ocl_image2d_ro(target("spirv.Image", void, 1, 0, 0, 0, 0, 0, 0))
More information about the llvm-commits
mailing list