[Mlir-commits] [mlir] 57d9118 - [mlir][SPIR-V] Support SaturatedConversion serialization (#231622)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Oct 13 22:09:21 PDT 2026
Author: Alexander Shaposhnikov
Date: 2026-10-13T22:09:16-07:00
New Revision: 57d911854d22390aab3a4b893efd8bdc3bf7ea40
URL: https://github.com/llvm/llvm-project/commit/57d911854d22390aab3a4b893efd8bdc3bf7ea40
DIFF: https://github.com/llvm/llvm-project/commit/57d911854d22390aab3a4b893efd8bdc3bf7ea40.diff
LOG: [mlir][SPIR-V] Support SaturatedConversion serialization (#231622)
Handle SaturatedConversion as an operand-free decoration during SPIR-V
serialization and deserialization, represented by a unit attribute in
MLIR. This allows saturated integer conversions to round-trip instead of
failing with an unhandled decoration error.
Add round-trip coverage for scalar and vector saturated conversions,
including saturation combined with FPRoundingMode. Also extend rounding
mode coverage across floating-point conversion instructions.
Added:
Modified:
mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
mlir/test/Target/SPIRV/decorations.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
index 9df544d861767..00b51dc68bdcd 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
@@ -361,6 +361,7 @@ LogicalResult spirv::Deserializer::processDecoration(ArrayRef<uint32_t> words) {
case spirv::Decoration::Patch:
case spirv::Decoration::Coherent:
case spirv::Decoration::Volatile:
+ case spirv::Decoration::SaturatedConversion:
if (words.size() != 2) {
return emitError(unknownLoc, "OpDecorate with ")
<< decorationName << " needs a single target <id>";
diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
index 3919c3ed5ec36..d22d198ee8c07 100644
--- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
@@ -416,6 +416,7 @@ LogicalResult Serializer::processDecorationAttr(Location loc, uint32_t resultID,
case spirv::Decoration::Patch:
case spirv::Decoration::Coherent:
case spirv::Decoration::Volatile:
+ case spirv::Decoration::SaturatedConversion:
// For unit attributes and decoration attributes, the args list
// has no values so we do nothing.
if (isa<UnitAttr, DecorationAttr>(attr))
diff --git a/mlir/test/Target/SPIRV/decorations.mlir b/mlir/test/Target/SPIRV/decorations.mlir
index bbbe02b598244..2d3f256715caa 100644
--- a/mlir/test/Target/SPIRV/decorations.mlir
+++ b/mlir/test/Target/SPIRV/decorations.mlir
@@ -159,6 +159,66 @@ spirv.func @fp_rounding_mode(%arg: f32) -> f16 "None" {
// -----
+spirv.module Logical OpenCL requires #spirv.vce<v1.0, [Kernel, Linkage, Float64], []> {
+spirv.func @f_convert_rounding_mode(%arg: f64) -> f32 "None" {
+ // CHECK: spirv.FConvert %{{.*}} {fp_rounding_mode = #spirv.fp_rounding_mode<RTZ>} : f64 to f32
+ %0 = spirv.FConvert %arg {fp_rounding_mode = #spirv.fp_rounding_mode<RTZ>} : f64 to f32
+ spirv.ReturnValue %0 : f32
+}
+spirv.func @convert_s_to_f_rounding_mode(%arg: i32) -> f32 "None" {
+ // CHECK: spirv.ConvertSToF %{{.*}} {fp_rounding_mode = #spirv.fp_rounding_mode<RTE>} : i32 to f32
+ %0 = spirv.ConvertSToF %arg {fp_rounding_mode = #spirv.fp_rounding_mode<RTE>} : i32 to f32
+ spirv.ReturnValue %0 : f32
+}
+spirv.func @convert_u_to_f_rounding_mode(%arg: vector<4xi32>) -> vector<4xf32> "None" {
+ // CHECK: spirv.ConvertUToF %{{.*}} {fp_rounding_mode = #spirv.fp_rounding_mode<RTP>} : vector<4xi32> to vector<4xf32>
+ %0 = spirv.ConvertUToF %arg {fp_rounding_mode = #spirv.fp_rounding_mode<RTP>} : vector<4xi32> to vector<4xf32>
+ spirv.ReturnValue %0 : vector<4xf32>
+}
+spirv.func @convert_f_to_s_rounding_mode(%arg: f32) -> i32 "None" {
+ // CHECK: spirv.ConvertFToS %{{.*}} {fp_rounding_mode = #spirv.fp_rounding_mode<RTN>} : f32 to i32
+ %0 = spirv.ConvertFToS %arg {fp_rounding_mode = #spirv.fp_rounding_mode<RTN>} : f32 to i32
+ spirv.ReturnValue %0 : i32
+}
+spirv.func @convert_f_to_u_rounding_mode(%arg: f32) -> i32 "None" {
+ // CHECK: spirv.ConvertFToU %{{.*}} {fp_rounding_mode = #spirv.fp_rounding_mode<RTE>} : f32 to i32
+ %0 = spirv.ConvertFToU %arg {fp_rounding_mode = #spirv.fp_rounding_mode<RTE>} : f32 to i32
+ spirv.ReturnValue %0 : i32
+}
+}
+
+// -----
+
+spirv.module Logical OpenCL requires #spirv.vce<v1.0, [Kernel, Linkage, Int8, Int64], []> {
+spirv.func @convert_f_to_s_saturated(%arg: f32) -> i32 "None" {
+ // CHECK: spirv.ConvertFToS %{{.*}} {saturated_conversion} : f32 to i32
+ %0 = spirv.ConvertFToS %arg {saturated_conversion} : f32 to i32
+ spirv.ReturnValue %0 : i32
+}
+spirv.func @convert_f_to_u_saturated(%arg: vector<4xf32>) -> vector<4xi32> "None" {
+ // CHECK: spirv.ConvertFToU %{{.*}} {saturated_conversion} : vector<4xf32> to vector<4xi32>
+ %0 = spirv.ConvertFToU %arg {saturated_conversion} : vector<4xf32> to vector<4xi32>
+ spirv.ReturnValue %0 : vector<4xi32>
+}
+spirv.func @s_convert_saturated(%arg: i64) -> i32 "None" {
+ // CHECK: spirv.SConvert %{{.*}} {saturated_conversion} : i64 to i32
+ %0 = spirv.SConvert %arg {saturated_conversion} : i64 to i32
+ spirv.ReturnValue %0 : i32
+}
+spirv.func @u_convert_saturated(%arg: i32) -> i8 "None" {
+ // CHECK: spirv.UConvert %{{.*}} {saturated_conversion} : i32 to i8
+ %0 = spirv.UConvert %arg {saturated_conversion} : i32 to i8
+ spirv.ReturnValue %0 : i8
+}
+spirv.func @convert_f_to_s_saturated_rounding_mode(%arg: f32) -> i32 "None" {
+ // CHECK: spirv.ConvertFToS %{{.*}} {fp_rounding_mode = #spirv.fp_rounding_mode<RTE>, saturated_conversion} : f32 to i32
+ %0 = spirv.ConvertFToS %arg {fp_rounding_mode = #spirv.fp_rounding_mode<RTE>, saturated_conversion} : f32 to i32
+ spirv.ReturnValue %0 : i32
+}
+}
+
+// -----
+
spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader, Linkage], []> {
// CHECK: spirv.func @relaxed_precision_arg({{%.*}}: !spirv.ptr<f32, Function> {spirv.decoration = #spirv.decoration<RelaxedPrecision>}) "None" attributes {relaxed_precision} {
spirv.func @relaxed_precision_arg(%arg0: !spirv.ptr<f32, Function> {spirv.decoration = #spirv.decoration<RelaxedPrecision>}) -> () "None" attributes {relaxed_precision} {
More information about the Mlir-commits
mailing list