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

    <tr>
        <th>Summary</th>
        <td>
            [MLIR] ArithToLLVM fails to convert arith.index_cast operations with memref operands
        </td>
    </tr>

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

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

    <tr>
      <th>Reporter</th>
      <td>
          andidr
      </td>
    </tr>
</table>

<pre>
    The ArithToLLVM pass fails with an error message when the IR contains an `arith.index_cast` operation with a memref operand and an integer element type type that does not match the width of the index type. E.g., on AMD64:

```
$ cat debug/index_cast_i32.mlir
module {
 func.func @main(%arg0: memref<3xi32>) -> memref<3xindex> {
    %0 = arith.index_cast %arg0 : memref<3xi32> to memref<3xindex>
    return %0 : memref<3xindex>
  }
}
$ mlir-opt debug/index_cast_i32.mlir --convert-func-to-llvm
debug/index_cast_i32.mlir:3:10: error: 'llvm.sext' op operand #0 must be integer or LLVM dialect-compatible vector of integer, but got '!llvm.struct<(ptr<i32>, ptr<i32>, i64, array<1 x i64>, array<1 x i64>)>'
    %0 = arith.index_cast %arg0 : memref<3xi32> to memref<3xindex>
         ^
debug/sext_i32.mlir:3:10: note: see current operation: %6 = "llvm.sext"(%5) : (!llvm.struct<(ptr<i32>, ptr<i32>, i64, array<1 x i64>, array<1 x i64>)>) -> !llvm.struct<(ptr<i64>, ptr<i64>, i64, array<1 x i64>, array<1 x i64>)>
```
This is because the code of the rewriting pattern from `IndexCastOpLowering<OpTy, ExtCastTy>::matchAndRewrite()` in [mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp](https://github.com/llvm/llvm-project/blob/8827ff92b96d78ef455157574061d745df2909af/mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cpp#L239) only handles scalar and vector operands. Memref operands are treated the same way as scalars, resulting in an `llvm.sext` operation with the converted type of a memref, i.e., an `!llvm.struct<...>`, which fails verification later on.

I'd love to extend the pattern so that it also handles operations with memref operands, but the semantics of `arith.index_cast` operating on memrefs are unclear to me. I wouldn't expect the operation to allocate a new memref, but since there is no "output" operand, this is the only option to store the result. However, allocation of a new buffer would have consequences on memory management that cannot be treated directly in the pass, which would make it no longer self-contained.

Maybe @Mogball can clarify the semantics?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8VlFvozgQ_jXOyyiImBCShzxk00ZXqdVKq-peV8YM4Dtjc7Zpkn9_GkOSZrfq6Va6q1rA4M7Y3_fNNxbeq8Ygbln-heUPMzGE1rqtMJWq3Ky01Xn72iLsnArtq31-_v0FeuE91EJpD0cVWhAG0DnroEPvRYNwbNFAaBGevoG0JghlPM1iq1RQnESZCk_fpfCBrVKwPToRlDVTOOiwc1iP700F4x8oE7BBB6ixQxMgnHucLq0IUFn0YGyATgTZxvRHVYUWbB0HMWecn8Bj0iSM78Ea2L08rJYs27H0gaWX6yqdfschX4KkDFgODeOH2-q_q4wnnVZunNjZatAIrPgyjqEejEzoAmyZdkIZxteM58I1Kct20z5Zts9OKuMse2R8A3OWPd59oWz07hYWABjPU2DZA_wIKEzx4cMEEOxHsW9xHYbBmUv43WeTWfEw4XN94EsgNOa2_xQtmM-lNW_owpzAmQc71_qtG4N8hnK2y1i2W0TwouTogfGC_jvxeAqMF2D7q3IYz1LoBh-gxKt-rIMo40oJjTLMpe16EVSpEd5QButIMdNkEkk5BGgsAVswvhhTBTfIwLI94-s-OJbtL_zt4cexWi3pJpwTZ5btF3CKr8aPH73dxGvx33Mdf1j-eI87wfgx4sYGpLtHBDk4R0V4rd2RiXwVF8o4f0cJH1Wfk7rHaev_Ecipoj7JeA3y4_jXMn5kIa-t8qA8lCjF4DEakrQVXszJ4dGpoEwDvQgBnYHa2Y4M84lo2wsfvvbP9ohOmYZl-6_965kW8XgK9O31TImzHct20f12pvoWI2LEekMuqwyw_EsklR-0Khk_7GMRemKPH945_P0okX3P8gfG120Ivac0_MD4oVGhHcpE2o4CUv2Ot3nv7B8oA-OHUlvKs17zoq43vNysqmKN9TLPF3mRF8t0taiKZV7VfJNuRM344VfXx7Nnnm2IbWv0GVphKo0evBRauNhBLrU9WoNP4OWuy3gQDiE4FAGryIkXHcJRnEFc4niC3KEfdKRKmamp3bT-czcbmY5mR3GpXdn62uOiyhKMzWiM9ZNOkyQhcunLHo6tku3Ue9_QqVrJMZcWgazNJO_72BPjRQXaviF5AZ4CmnFrF5F5O_ZOFUBob6-wXfcwdfj7huwvrhhRwk6YoKSnbX3e4E1DDXeMNcI9GKlRuNGpEniCox10ZRgvAuCpRznmuEEaLAitrRQBQYDB4zscaUVeGRmryyGVm7FkRXYI_UA-dNkAzQ5TRcb4JBnbXzL4YB1OZUlcJ_CbPeLb2A2m9DQ18khrKIe6RjcuHlrxFhn3-NeARhKacdPWnaETRjTT6YVwl8LQiaW8Ca9SDmXQZxLXyJT3N-LHDJ34E4kyY0FbQy3No67n00kLqzsNvIhziXT8eLFNKbSmnCC1cKo-3xPIssOs2mbVJtuIGW4XxSJf51mWLmbtNl9LmaV5VVSpKOvFJi8KXIo0Xedyk66reqa2POXLNF-s0k2ep4tkxXGR8lKucJXldbpkyxQ7oXQS1W1dM1PeD7jd8KwoZlqUqH08g3I-egCn06jbRkcph8azZaqVD_4WIKig47n15fnpG8sf7g6pY40Eeym-n5vnP4h8Nji9_deOFzflGT_Eff0dAAD__y-PoFg">