<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/77664>77664</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [mlir][spirv] Investigate legalization of the func argument.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            mlir:spirv
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          jungpark-mlir
      </td>
    </tr>
</table>

<pre>
    Compilation pipeline lowering to the spirv generates `unrealized_conversion_cast`s.
Each pass handles the legalization of relevant ops but the cast between func argument and ops are not covered anywhere.
Discussed [here](https://discourse.llvm.org/t/plumbing-spirv-lowering-path/76131)

My first approach was to have an rewrite pattern in the `func-to-spirv` [patch](https://github.com/llvm/llvm-project/pull/77344/files#diff-4f747472a4273c022fff69d9b84e3955cd5872b3ae25cb02307a037cf9e749b2R85-R123) but it might not be the desired way.
Otherwise, I suppose it can be addressed
- Let each *-to-spirv to convert the `owner` - sounds not right, we basically want to allow `unrealized_conversion_cast` during the pipeline so it can be cancelled.
- Legalize block argument in the `func-to-spirv` pass but do it differently?

Here's examples of offensive ir
```
module {
  gpu.module @forward_kernel_1 attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Addresses, Int64, Int8, Kernel], []>, api=OpenCL, #spirv.resource_limits<>>} {
    gpu.func @forward_kernel_1_forward_kernel(%arg0: index, %arg1: memref<f32>, %arg2: index, %arg3: memref<f32>, %arg4: index, %arg5: memref<f32>, %arg6: index, %arg7: memref<f32>, %arg8: index, %arg9: index, %arg10: index) kernel attributes {gpu.known_block_size = array<i32: 1, 1, 1>, spirv.entry_point_abi = #spirv.entry_point_abi<>} {
      %0 = gpu.block_id  x
      %1 = gpu.block_id  y
      scf.for %arg11 = %arg8 to %arg9 step %arg10 {
 %2 = arith.muli %0, %arg0 : index
        %3 = arith.addi %2, %arg11 : index
        %reinterpret_cast = memref.reinterpret_cast %arg1 to offset: [%3], sizes: [], strides: [] : memref<f32> to memref<f32>
        %4 = memref.load %reinterpret_cast[] : memref<f32>
        %5 = arith.muli %arg11, %arg2 : index
        %6 = arith.addi %5, %1 : index
 %reinterpret_cast_0 = memref.reinterpret_cast %arg3 to offset: [%6], sizes: [], strides: [] : memref<f32> to memref<f32>
        %7 = memref.load %reinterpret_cast_0[] : memref<f32>
        %8 = arith.muli %0, %arg4 : index
        %9 = arith.addi %8, %1 : index
 %reinterpret_cast_1 = memref.reinterpret_cast %arg5 to offset: [%9], sizes: [], strides: [] : memref<f32> to memref<f32>
        %10 = memref.load %reinterpret_cast_1[] : memref<f32>
        %11 = arith.mulf %4, %7 : f32
        %12 = arith.addf %10, %11 : f32
        %13 = arith.muli %0, %arg6 : index
        %14 = arith.addi %13, %1 : index
 %reinterpret_cast_2 = memref.reinterpret_cast %arg7 to offset: [%14], sizes: [], strides: [] : memref<f32> to memref<f32>
        memref.store %12, %reinterpret_cast_2[] : memref<f32>
      }
      gpu.return
 }
  }
}
```
expected to be lowered with 
./mlir-opt ./scf.ir -convert-scf-to-spirv -canonicalize | ./opt -pass-pipeline='builtin.module(convert-gpu-to-spirv{use-64bit-index=false})'

but
```
<stdin>:4:12: error: failed to legalize operation 'builtin.unrealized_conversion_cast'
 %0 = builtin.unrealized_conversion_cast %arg8 : index to i32
 ^
<stdin>:4:12: note: see current operation: %0 = "builtin.unrealized_conversion_cast"(<<UNKNOWN SSA VALUE>>) : (index) -> i32
```

Another IR with arith dialect.
```
module attributes {gpu.container_module, spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Addresses, Int64, Kernel], []>, #spirv.resource_limits<>>} {
  gpu.module @forward_kernel_1 [#spirv.target_env<#spirv.vce<v1.0, [Addresses, Int64, Kernel], []>, #spirv.resource_limits<>>]  attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.0, [Addresses, Int64, Kernel], []>, api=OpenCL, #spirv.resource_limits<>>} {
    gpu.func @test_kernel(%arg0: index, %arg1: index, %arg2: memref<3x3xi32>) kernel attributes {gpu.known_block_size = array<i32: 1, 1, 1>, gpu.known_grid_size = array<i32: 3, 3, 1>, spirv.entry_point_abi = #spirv.entry_point_abi<>} {
      %0 = gpu.block_id  x
      %1 = gpu.block_id  y
      %2 = arith.addi %arg0, %arg1 : index
      %3 = index.casts %2 : index to i32
 memref.store %3, %arg2[%0, %1] : memref<3x3xi32>
      gpu.return
 }
  }
}
```





</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWF-P4ygS_zTkBTmywX_ihzykk4lutHMz0qz27jHCdjlhh4AFOOncpz-B7cSddme6pd25kyLHBqr41a8KqIIZw_cSYImSJ5RsZqy1B6WXf7Zy3zD9IzgKrmeFqi7LtTo2XDDLlcQNb0BwCVioM2gu99gqbA-ATcP1Ce9BgmYWDEZp2EoNTPD_QLUrlTyBNlzJXcmMRWlo5ijcoHD1iZUH3DBj8IHJSoDx2gTsnWQ3p6qxBgEnJi1WjcFFa_0gpwkXYM8AEtetLDHT-_YI0mImKz-UacBSWVyqE2ioMJOX8wE09JNvuClbY6DCKHly7SjZILI4WNsYRFeIbBHZVtyUqtUG5kKcjnOl94hsLSLbRrTHgst94G0PBkaChtkDItssjWiESN5N1T3_ecE118Zi1jRaOdPPzDgKD-wEmEms4ay5Bdwwa0FLzKU3FaWhMzCwqpsMpaGD3DBbHqYw77k9tMW8VEdEtg52_xc0Wv0JpUffCuFQZjSOEdnWXIBBhFa8roO4zuIszgiLSUbLkJC6rtO8yotFDDRPkrJKFhkpKAOSlEVIaJixkGZlnUMW5wX5vkiC7xGhiOTeW9ziI98frPdFAd6kCgx3LjmzS--Nb_YA-swNILLGn7Fpm0YZcMIlk06MVZUG565ufIC_gMXgWERkdeXG0dnFmx24U2cJ2nEWYKNaWRkPRDtIbq4z4IIZXjIhLvjswswqzIRQ55-GMa7abhUc4LY2jBqBLpksQQio5jfUPrgBF0KVP25B-8DXfoE4Jiuv2jkJNEgrLohuxwH2DxfEJDMYntmxcctJ1VjVNUjDT4C57genYf_zn0dVtQIwyp66b4z3TTsfWuOwVvrMdLX7AVqC2EWYWat50fqFnj15mHPL9B7sDuQJI7rBiND7dkTX19ZTCYiuT9E8dB5AydOqd67x3pc2jfuXhfv_zc_sQ92Pdm_0k_tgDUd0860Buf7iO4cZNBjV6hJ2gh-5NW5y-sn9ss3Y0s5Wv31MWLp72YDIApGE6X2I6ApzWcFzN6dri1zbEY4aakTXNSU9wq6XTEjQhxLxhETyUCKdkMgeSiwmJPIp28YG57hj4y4MHI8_pDrLnQ_snXEx7kKBac0uiK459SRETm3_6LB0DgNp9WXXKC7tjhX8ZRTddfbevHcldnBDL-nQdDh4hfHz3ZhoYsxlPMaU9bxWejA_6tF4ztz20FOFjYXmytEIDCIJ6Y3n9jA_toJ7bDdKHcyB0tHEHh4dibKq8qJk5I3ogawGLi3oRoP1u5RX1QXA_HVfp89ZpOragHV63foiCe1Xm3OjGZr7Jqt5NW7EE0HmdN7H3T3WeAxOKFZNGfD2FK_0JROUe75G6_ABdekE7Ukv-pryCai78B1s0ym201_AdvYetnfhB_hePA7x-AHX-QTXiw9xHb2D62SK6_wXcB2F7yI7-gDZ_SZ0Zbv2K6inLPMqnOQrMfKS6bqDN1AdvS1IH3s3feDdKJ5wb0Q_5F_yDv9mU_6N4r_bwT0oY5WGjuPestdGvM_BKNuMP93BpMG2Wg783Pqvr7eXl9kcPDdQWqicFUVfqblEm9sD7kbMEdm6-i5QjcXuw512XOOgz5sDU9a3fDoomVTSpcf-QM_WXsSJBi4vDYa8F9ENIlnRcmG57LNHRBaDzn3T3nLa7Kk1EKRxwW3QxQHd1EwYcEaRHJFsnNUWrZ20FNG1sRWXPrFbuXwp8hkGaK20D2vGRUeEGJJu1bgK1dWVI7APcvwByS2z-LnQNVG4hrmDwK9rDCWfHhsglQX3bwBw2WqX6t-A-9gdwCBC3mMEcZmry5nWf3z97eu3f3_Fv_--wv9affnjU58Vkxx3ihfXLC9wS-GK-p57_1xJ5ao2_Pl7F19-weOKMwGlnT8qNl7njqWSlnEJejfEzpAZ_i2lxdslxUdLiJ8US35T-l8jTjb411Vtv6pas2DsuyuzuzbyYkemz_SZ97XRX17e3CT3mldvCvrTkf6f10V3dc1wtHvib3xPZwbXwsb3zN3OZAaFk_vk_TFLx-7zR_01jXl1xo48-lcdrG89Z9WSVjnN2QyWURbGeRQRGs4OywwWGU1YFqVZWFRFGYYEIMxLVrFFDgWd8SUJSRxGURgtSBaF80VZQ1yGJCpjUqQkQ3EIR8bF9e5xxo1pYZllaRrPBCtAGH-DS4g70BFddecrISjZzPTSX_oV7d6gOBTcWHNTZLkV_vbXCyYblHRbgmPyszyBsXzP7Ou7WHuAl7et81mrxfLDF5DeEOOvINM0_m8AAAD___I7tz4">