[Mlir-commits] [mlir] [mlir][spirv] Add definition for GL Pack/UnpackSnorm4x8 (PR #174574)
Igor Wodiany
llvmlistbot at llvm.org
Tue Jan 6 03:55:10 PST 2026
https://github.com/IgWod-IMG created https://github.com/llvm/llvm-project/pull/174574
None
>From f3229867f053cd7915555cde2490e84130b501f6 Mon Sep 17 00:00:00 2001
From: Igor Wodiany <igor.wodiany at imgtec.com>
Date: Tue, 6 Jan 2026 11:33:48 +0000
Subject: [PATCH] [mlir][spirv] Add definition for GL Pack/UnpackSnorm4x8
---
.../mlir/Dialect/SPIRV/IR/SPIRVGLOps.td | 93 +++++++++++++++
mlir/test/Dialect/SPIRV/IR/gl-ops.mlir | 110 +++++++++++++++++-
mlir/test/Target/SPIRV/gl-ops.mlir | 8 ++
3 files changed, 208 insertions(+), 3 deletions(-)
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLOps.td
index 8c4da9b2dce18..01fe12a4660af 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLOps.td
@@ -1476,4 +1476,97 @@ def SPIRV_GLUnpackHalf2x16Op : SPIRV_GLOp<"UnpackHalf2x16", 62, [Pure]> {
let hasVerifier = 0;
}
+// -----
+
+def SPIRV_GLPackSnorm4x8Op : SPIRV_GLOp<"PackSnorm4x8", 54, [Pure]> {
+ let summary = "Pack four-component vector of normalized 32-bit floats into a 32-bit integer";
+
+ let description = [{
+ First, converts each component of the normalized floating-point value v into
+ 8-bit integer values. These are then packed into the result.
+
+ The conversion for component c of v to fixed point is done as follows:
+
+ ```
+ round(clamp(c, -1, +1) * 127.0)
+ ```
+
+ The RelaxedPrecision Decoration only affects the conversion step of the instruction.
+
+ The first component of the vector is written to the least significant bits of the
+ output; the last component is written to the most significant bits.
+
+ The v operand must be a vector of 4 components whose type is a 32-bit floating-point.
+
+ Result Type must be a 32-bit integer type.
+
+ #### Example:
+
+ ```mlir
+ %0 = spirv.GL.PackSnorm4x8 %1 : vector<4xf32> -> i32
+ ```
+ }];
+
+ let arguments = (ins
+ VectorOfLengthAndType<[4], [SPIRV_Float32]>:$operand
+ );
+
+ let results = (outs
+ SPIRV_Int32:$result
+ );
+
+ let assemblyFormat = [{
+ attr-dict $operand `:` type($operand) `->` type($result)
+ }];
+
+ let hasVerifier = 0;
+}
+
+
+// -----
+
+def SPIRV_GLUnpackSnorm4x8Op : SPIRV_GLOp<"UnpackSnorm4x8", 63, [Pure]> {
+ let summary = "Unpack 32-bit integer into four-component vector of normalized 32-bit floats";
+
+ let description = [{
+ First, unpacks a single 32-bit unsigned integer p into four 8-bit signed integers.
+ Then, each component is converted to a normalized floating-point value to generate
+ the result. The conversion for unpacked fixed-point value f to floating point is
+ done as follows:
+
+ ```
+ clamp(f / 127.0, -1, +1)
+ ```
+
+ The first component of the result is extracted from the least significant bits of the
+ input; the last component is extracted from the most significant bits.
+
+ The RelaxedPrecision Decoration only affects the conversion step of the instruction.
+
+ The p operand must be a scalar with 32-bit integer type.
+
+ Result Type must be a vector of 4 components whose type is 32-bit floating point.
+
+ #### Example:
+
+ ```mlir
+ %0 = spirv.GL.UnpackSnorm4x8 %1 : i32 -> vector<4xf32>
+ ```
+ }];
+
+ let arguments = (ins
+ SPIRV_Int32:$operand
+ );
+
+ let results = (outs
+ VectorOfLengthAndType<[4], [SPIRV_Float32]>:$result
+ );
+
+ let assemblyFormat = [{
+ attr-dict $operand `:` type($operand) `->` type($result)
+ }];
+
+ let hasVerifier = 0;
+}
+
#endif // MLIR_DIALECT_SPIRV_IR_GL_OPS
diff --git a/mlir/test/Dialect/SPIRV/IR/gl-ops.mlir b/mlir/test/Dialect/SPIRV/IR/gl-ops.mlir
index fd8a2ffbbddf9..bab12b183faf1 100644
--- a/mlir/test/Dialect/SPIRV/IR/gl-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/gl-ops.mlir
@@ -943,9 +943,9 @@ func.func @pack_half_2x16_scalar_in(%arg0 : f32) -> () {
// -----
-func.func @unpack_half_2x16_vector_out(%arg0 : vector<2xf32>) -> () {
- // expected-error @+1 {{invalid kind of type specified: expected builtin.integer, but found 'vector<2xf32>'}}
- %0 = spirv.GL.UnpackHalf2x16 %arg0 : vector<2xf32> -> vector<2xi32>
+func.func @pack_half_2x16_vector_out(%arg0 : vector<2xf32>) -> () {
+ // expected-error @+1 {{invalid kind of type specified: expected builtin.integer, but found 'vector<2xi32>'}}
+ %0 = spirv.GL.PackHalf2x16 %arg0 : vector<2xf32> -> vector<2xi32>
return
}
@@ -1003,6 +1003,110 @@ func.func @unpack_half_2x16_scalar_out(%arg0 : i32) -> () {
// -----
+//===----------------------------------------------------------------------===//
+// spirv.GL.PackSnorm4x8
+//===----------------------------------------------------------------------===//
+
+func.func @pack_snorm_4x8(%arg0 : vector<4xf32>) -> () {
+ // CHECK: spirv.GL.PackSnorm4x8 {{%.*}} : vector<4xf32> -> i32
+ %0 = spirv.GL.PackSnorm4x8 %arg0 : vector<4xf32> -> i32
+ return
+}
+
+// -----
+
+func.func @pack_snorm_4x8_i16_output(%arg0 : vector<4xf32>) -> () {
+ // expected-error @+1 {{op result #0 must be Int32, but got 'i16'}}
+ %0 = spirv.GL.PackSnorm4x8 %arg0 : vector<4xf32> -> i16
+ return
+}
+
+// -----
+
+func.func @pack_snorm_4x8_wrong_vec_size(%arg0 : vector<3xf32>) -> () {
+ // expected-error @+1 {{op operand #0 must be vector of Float32 values of length 4, but got 'vector<3xf32>'}}
+ %0 = spirv.GL.PackSnorm4x8 %arg0 : vector<3xf32> -> i32
+ return
+}
+
+// -----
+
+func.func @pack_snorm_4x8_wrong_vec_type(%arg0 : vector<4xi32>) -> () {
+ // expected-error @+1 {{op operand #0 must be vector of Float32 values of length 4, but got 'vector<4xi32>'}}
+ %0 = spirv.GL.PackSnorm4x8 %arg0 : vector<4xi32> -> i32
+ return
+}
+
+// -----
+
+func.func @pack_snorm_4x8_scalar_in(%arg0 : f32) -> () {
+ // expected-error @+1 {{invalid kind of type specified: expected builtin.vector, but found 'f32'}}
+ %0 = spirv.GL.PackSnorm4x8 %arg0 : f32 -> i32
+ return
+}
+
+// -----
+
+func.func @pack_snorm_4x8_vector_out(%arg0 : vector<4xf32>) -> () {
+ // expected-error @+1 {{invalid kind of type specified: expected builtin.integer, but found 'vector<4xi32>'}}
+ %0 = spirv.GL.PackSnorm4x8 %arg0 : vector<4xf32> -> vector<4xi32>
+ return
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.GL.UnpackSnorm4x8
+//===----------------------------------------------------------------------===//
+
+func.func @unpack_snorm_4x8(%arg0 : i32) -> () {
+ // CHECK: spirv.GL.UnpackSnorm4x8 {{%.*}} : i32 -> vector<4xf32>
+ %0 = spirv.GL.UnpackSnorm4x8 %arg0 : i32 -> vector<4xf32>
+ return
+}
+
+// -----
+
+func.func @unpack_snorm_4x8_i16_input(%arg0 : i16) -> () {
+ // expected-error @+1 {{op operand #0 must be Int32, but got 'i16'}}
+ %0 = spirv.GL.UnpackSnorm4x8 %arg0 : i16 -> vector<4xf32>
+ return
+}
+
+// -----
+
+func.func @unpack_snorm_4x8_wrong_vec_size(%arg0 : i32) -> () {
+ // expected-error @+1 {{op result #0 must be vector of Float32 values of length 4, but got 'vector<3xf32>'}}
+ %0 = spirv.GL.UnpackSnorm4x8 %arg0 : i32 -> vector<3xf32>
+ return
+}
+
+// -----
+
+func.func @unpack_snorm_4x8_wrong_vec_type(%arg0 : i32) -> () {
+ // expected-error @+1 {{op result #0 must be vector of Float32 values of length 4, but got 'vector<4xi32>'}}
+ %0 = spirv.GL.UnpackSnorm4x8 %arg0 : i32 -> vector<4xi32>
+ return
+}
+
+// -----
+
+func.func @unpack_snorm_4x8_vec_in(%arg0 : vector<4xf32>) -> () {
+ // expected-error @+1 {{invalid kind of type specified: expected builtin.integer, but found 'vector<4xf32>'}}
+ %0 = spirv.GL.UnpackSnorm4x8 %arg0 : vector<4xf32> -> vector<4xf32>
+ return
+}
+
+// -----
+
+func.func @unpack_snorm_4x8_scalar_out(%arg0 : i32) -> () {
+ // expected-error @+1 {{invalid kind of type specified: expected builtin.vector, but found 'f32'}}
+ %0 = spirv.GL.UnpackSnorm4x8 %arg0 : i32 -> f32
+ return
+}
+
+// -----
+
//===----------------------------------------------------------------------===//
// spirv.GL.Length
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Target/SPIRV/gl-ops.mlir b/mlir/test/Target/SPIRV/gl-ops.mlir
index 3c661f88e90d2..3255044770159 100644
--- a/mlir/test/Target/SPIRV/gl-ops.mlir
+++ b/mlir/test/Target/SPIRV/gl-ops.mlir
@@ -147,4 +147,12 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader, Linkage], []> {
%1 = spirv.GL.PackHalf2x16 %0 : vector<2xf32> -> i32
spirv.Return
}
+
+ spirv.func @pack_snorm_4x8(%arg0 : i32) "None" {
+ // CHECK: {{%.*}} = spirv.GL.UnpackSnorm4x8 {{%.*}} : i32 -> vector<4xf32>
+ %0 = spirv.GL.UnpackSnorm4x8 %arg0 : i32 -> vector<4xf32>
+ // CHECK: {{%.*}} = spirv.GL.PackSnorm4x8 {{%.*}} : vector<4xf32> -> i32
+ %1 = spirv.GL.PackSnorm4x8 %0 : vector<4xf32> -> i32
+ spirv.Return
+ }
}
More information about the Mlir-commits
mailing list