[Mlir-commits] [mlir] 2f89dcf - [mlir][SPIR-V] Deserialize replicated composites as attributes (#214469)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Aug 7 05:48:15 PDT 2026
Author: Niklas Lithammer
Date: 2026-08-07T14:48:10+02:00
New Revision: 2f89dcf270fb51d752cb1ddcfb7665520ef4fedd
URL: https://github.com/llvm/llvm-project/commit/2f89dcf270fb51d752cb1ddcfb7665520ef4fedd
DIFF: https://github.com/llvm/llvm-project/commit/2f89dcf270fb51d752cb1ddcfb7665520ef4fedd.diff
LOG: [mlir][SPIR-V] Deserialize replicated composites as attributes (#214469)
Some SPIR-V™ instructions encode attribute-like operands as IDs of
constant composite instructions. Deserialization currently fails when
such an operand is defined by OpConstantCompositeReplicateEXT instead of
OpConstantComposite.
Materialize replicated composite constants as splat attributes when they
are requested as constants. Check for replicated composites first when
materializing SSA values so they remain
spirv.EXT.ConstantCompositeReplicate operations.
Added:
mlir/test/Target/SPIRV/replicated-composite-tosa-attr.spvasm
Modified:
mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp
mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
Removed:
################################################################################
diff --git a/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp b/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp
index 0e6d199eeabf0..66c77c61597d5 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/DeserializeOps.cpp
@@ -46,6 +46,12 @@ static NameLoc getLocFromDebugInfoString(OpBuilder &builder, StringRef source) {
//===----------------------------------------------------------------------===//
Value spirv::Deserializer::getValue(uint32_t id) {
+ if (std::optional<std::pair<Attribute, Type>> constCompositeReplicateInfo =
+ getConstantCompositeReplicate(id)) {
+ return spirv::EXTConstantCompositeReplicateOp::create(
+ opBuilder, unknownLoc, constCompositeReplicateInfo->second,
+ constCompositeReplicateInfo->first);
+ }
if (auto constInfo = getConstant(id)) {
// Materialize a `spirv.Constant` op at every use site.
Location loc = unknownLoc;
@@ -54,12 +60,6 @@ Value spirv::Deserializer::getValue(uint32_t id) {
return spirv::ConstantOp::create(opBuilder, loc, constInfo->second,
constInfo->first);
}
- if (std::optional<std::pair<Attribute, Type>> constCompositeReplicateInfo =
- getConstantCompositeReplicate(id)) {
- return spirv::EXTConstantCompositeReplicateOp::create(
- opBuilder, unknownLoc, constCompositeReplicateInfo->second,
- constCompositeReplicateInfo->first);
- }
if (auto varOp = getGlobalVariable(id)) {
auto addressOfOp =
spirv::AddressOfOp::create(opBuilder, unknownLoc, varOp.getType(),
diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
index 6cfe58c43596c..9e44f43ad889d 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
@@ -924,9 +924,18 @@ spirv::Deserializer::processGraphEndARM(ArrayRef<uint32_t> operands) {
std::optional<std::pair<Attribute, Type>>
spirv::Deserializer::getConstant(uint32_t id) {
auto constIt = constantMap.find(id);
- if (constIt == constantMap.end())
+ if (constIt != constantMap.end())
+ return constIt->getSecond();
+
+ auto replicatedConstIt = constantCompositeReplicateMap.find(id);
+ if (replicatedConstIt == constantCompositeReplicateMap.end())
return std::nullopt;
- return constIt->getSecond();
+
+ auto [value, type] = replicatedConstIt->getSecond();
+ auto shapedType = dyn_cast<ShapedType>(type);
+ if (!shapedType)
+ return std::nullopt;
+ return std::make_pair(SplatElementsAttr::get(shapedType, value), type);
}
std::optional<std::pair<Attribute, Type>>
@@ -1949,14 +1958,6 @@ LogicalResult spirv::Deserializer::processConstantCompositeReplicateEXT(
uint32_t resultID = operands[1];
uint32_t constantID = operands[2];
- std::optional<std::pair<Attribute, Type>> constantInfo =
- getConstant(constantID);
- if (constantInfo.has_value()) {
- constantCompositeReplicateMap.try_emplace(
- resultID, constantInfo.value().first, resultType);
- return success();
- }
-
std::optional<std::pair<Attribute, Type>> replicatedConstantCompositeInfo =
getConstantCompositeReplicate(constantID);
if (replicatedConstantCompositeInfo.has_value()) {
@@ -1965,6 +1966,14 @@ LogicalResult spirv::Deserializer::processConstantCompositeReplicateEXT(
return success();
}
+ std::optional<std::pair<Attribute, Type>> constantInfo =
+ getConstant(constantID);
+ if (constantInfo.has_value()) {
+ constantCompositeReplicateMap.try_emplace(
+ resultID, constantInfo.value().first, resultType);
+ return success();
+ }
+
return emitError(unknownLoc, "OpConstantCompositeReplicateEXT operand <id> ")
<< constantID
<< " must come from a normal constant or a "
diff --git a/mlir/test/Target/SPIRV/replicated-composite-tosa-attr.spvasm b/mlir/test/Target/SPIRV/replicated-composite-tosa-attr.spvasm
new file mode 100644
index 0000000000000..ec1d076702116
--- /dev/null
+++ b/mlir/test/Target/SPIRV/replicated-composite-tosa-attr.spvasm
@@ -0,0 +1,54 @@
+; RUN: %if spirv-tools %{ spirv-as --target-env spv1.6 %s -o - | mlir-translate --deserialize-spirv - -o - | FileCheck %s %}
+
+; CHECK: spirv.Tosa.Conv2D
+; CHECK-SAME: pad = [0, 0, 0, 0]
+; CHECK-SAME: stride = [1, 1]
+; CHECK-SAME: dilation = [1, 1]
+
+ OpCapability Shader
+ OpCapability TensorsARM
+ OpCapability GraphARM
+ OpCapability ReplicatedCompositesEXT
+ OpExtension "SPV_ARM_tensors"
+ OpExtension "SPV_ARM_graph"
+ OpExtension "SPV_EXT_replicated_composites"
+ %tosa = OpExtInstImport "TOSA.001000.1"
+ OpMemoryModel Logical GLSL450
+
+ %bool = OpTypeBool
+ %false = OpConstantFalse %bool
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+ %uint_4 = OpConstant %uint 4
+ %float = OpTypeFloat 32
+ %float_0 = OpConstant %float 0
+
+ %array_1 = OpTypeArray %uint %uint_1
+ %array_2 = OpTypeArray %uint %uint_2
+ %array_4 = OpTypeArray %uint %uint_4
+ %shape_1 = OpConstantComposite %array_1 %uint_1
+ %shape_2 = OpConstantComposite %array_1 %uint_2
+ %shape_4 = OpConstantComposite %array_1 %uint_4
+%shape_1x1x1x1 = OpConstantComposite %array_4 %uint_1 %uint_1 %uint_1 %uint_1
+
+ %uint_s2 = OpTypeTensorARM %uint %uint_1 %shape_2
+ %uint_s4 = OpTypeTensorARM %uint %uint_1 %shape_4
+ %float_s1 = OpTypeTensorARM %float %uint_1 %shape_1
+%float_s1x1x1x1 = OpTypeTensorARM %float %uint_4 %shape_1x1x1x1
+
+ %pad = OpConstantComposite %uint_s4 %uint_0 %uint_0 %uint_0 %uint_0
+ %stride = OpConstantCompositeReplicateEXT %uint_s2 %uint_1
+ %dilation = OpConstantComposite %uint_s2 %uint_1 %uint_1
+ %zero_point = OpConstantComposite %float_s1 %float_0
+ %weights = OpGraphConstantARM %float_s1x1x1x1 0
+ %bias = OpGraphConstantARM %float_s1 1
+
+ %graph_type = OpTypeGraphARM 1 %float_s1x1x1x1 %float_s1x1x1x1
+ %graph = OpGraphARM %graph_type
+ %input = OpGraphInputARM %float_s1x1x1x1 %uint_0
+ %output = OpExtInst %float_s1x1x1x1 %tosa CONV2D %pad %stride %dilation %uint_3 %false %input %weights %bias %zero_point %zero_point
+ OpGraphSetOutputARM %output %uint_0
+ OpGraphEndARM
More information about the Mlir-commits
mailing list