[Mlir-commits] [mlir] [mlir][spirv] Handle signedness casts (PR #155388)
Michael Platings
llvmlistbot at llvm.org
Tue Aug 26 09:13:56 PDT 2025
mplatings wrote:
> > One instance is #141096.
>
> This fix looks fishy to me, I wouldn't not expect any unrealized_casts as an input for conversion to spirv.
>
> A motivating example at the level of arith/vector/sfc or the test dialect. would help me understand if this needs handling.
I can create an arith example by running `mlir-opt -pass-pipeline="builtin.module(func.func(tosa-to-linalg))"` on this test from #141096:
```
func.func @rescale_i8_unsigned_output_explicit(%arg0 : tensor<2xui8>) -> () {
%multiplier = "tosa.const"() {values = dense<19689> : tensor<1xi16> } : () -> tensor<1xi16>
%shift = "tosa.const"() {values = dense<15> : tensor<1xi8> } : () -> tensor<1xi8>
%input_zp = "tosa.const"() {values = dense<17> : tensor<1xui8>} : () -> tensor<1xui8>
%output_zp = "tosa.const"() {values = dense<-22> : tensor<1xi8>} : () -> tensor<1xi8>
%1 = tosa.rescale %arg0, %multiplier, %shift, %input_zp, %output_zp {scale32 = false, rounding_mode = "SINGLE_ROUND", per_channel = false, input_unsigned = true, output_unsigned = true} : (tensor<2xui8>, tensor<1xi16>, tensor<1xi8>, tensor<1xui8>, tensor<1xi8>) -> tensor<2xui8>
return
}
```
which gives you:
```
#map = affine_map<(d0) -> (d0)>
module {
func.func @rescale_i8_unsigned_output_explicit(%arg0: tensor<2xui8>) {
%0 = "tosa.const"() <{values = dense<19689> : tensor<1xi16>}> : () -> tensor<1xi16>
%1 = "tosa.const"() <{values = dense<15> : tensor<1xi8>}> : () -> tensor<1xi8>
%2 = "tosa.const"() <{values = dense<17> : tensor<1xui8>}> : () -> tensor<1xui8>
%3 = "tosa.const"() <{values = dense<-22> : tensor<1xi8>}> : () -> tensor<1xi8>
%c19689_i32 = arith.constant 19689 : i32
%c15_i8 = arith.constant 15 : i8
%4 = tensor.empty() : tensor<2xui8>
%5 = linalg.generic {indexing_maps = [#map, #map], iterator_types = ["parallel"]} ins(%arg0 : tensor<2xui8>) outs(%4 : tensor<2xui8>) {
^bb0(%in: ui8, %out: ui8):
%c17_i32 = arith.constant 17 : i32
%c234_i32 = arith.constant 234 : i32
%6 = builtin.unrealized_conversion_cast %in : ui8 to i8
%7 = arith.extui %6 : i8 to i32
%8 = arith.subi %7, %c17_i32 : i32
%9 = tosa.apply_scale %8, %c19689_i32, %c15_i8 {rounding_mode = "SINGLE_ROUND"} : (i32, i32, i8) -> i32
%10 = arith.addi %9, %c234_i32 : i32
%c0_i32 = arith.constant 0 : i32
%c255_i32 = arith.constant 255 : i32
%11 = arith.maxsi %c0_i32, %10 : i32
%12 = arith.minsi %c255_i32, %11 : i32
%13 = arith.trunci %12 : i32 to i8
%14 = builtin.unrealized_conversion_cast %13 : i8 to ui8
linalg.yield %14 : ui8
} -> tensor<2xui8>
return
}
}
```
Converting that with `mlir-opt -convert-arith-to-spirv` gives you:
```#map = affine_map<(d0) -> (d0)>
module attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Int8, Int16, Int64, Float16, Float64, Shader], []>, #spirv.resource_limits<>>} {
func.func @rescale_i8_unsigned_output_explicit(%arg0: tensor<2xui8>) {
%0 = "tosa.const"() <{values = dense<19689> : tensor<1xi16>}> : () -> tensor<1xi16>
%1 = "tosa.const"() <{values = dense<15> : tensor<1xi8>}> : () -> tensor<1xi8>
%2 = "tosa.const"() <{values = dense<17> : tensor<1xui8>}> : () -> tensor<1xui8>
%3 = "tosa.const"() <{values = dense<-22> : tensor<1xi8>}> : () -> tensor<1xi8>
%cst19689_i32 = spirv.Constant 19689 : i32
%cst15_i8 = spirv.Constant 15 : i8
%4 = tensor.empty() : tensor<2xui8>
%5 = linalg.generic {indexing_maps = [#map, #map], iterator_types = ["parallel"]} ins(%arg0 : tensor<2xui8>) outs(%4 : tensor<2xui8>) {
^bb0(%in: ui8, %out: ui8):
%cst17_i32 = spirv.Constant 17 : i32
%cst234_i32 = spirv.Constant 234 : i32
%6 = builtin.unrealized_conversion_cast %in : ui8 to i8
%7 = spirv.UConvert %6 : i8 to i32
%8 = spirv.ISub %7, %cst17_i32 : i32
%9 = tosa.apply_scale %8, %cst19689_i32, %cst15_i8 {rounding_mode = "SINGLE_ROUND"} : (i32, i32, i8) -> i32
%10 = spirv.IAdd %9, %cst234_i32 : i32
%cst0_i32 = spirv.Constant 0 : i32
%cst255_i32 = spirv.Constant 255 : i32
%11 = spirv.GL.SMax %10, %cst0_i32 : i32
%12 = spirv.GL.SMin %11, %cst255_i32 : i32
%13 = spirv.SConvert %12 : i32 to i8
%14 = builtin.unrealized_conversion_cast %13 : i8 to ui8
linalg.yield %14 : ui8
} -> tensor<2xui8>
return
}
}
```
So there's a problem at `%6 = builtin.unrealized_conversion_cast %in : ui8 to i8` because that should have been lowered to `spirv.Bitcast`
(Apologies if I've misunderstood you, I'm relatively new to MLIR)
https://github.com/llvm/llvm-project/pull/155388
More information about the Mlir-commits
mailing list