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

    <tr>
        <th>Summary</th>
        <td>
            [mlir] Bug in MemrefToLLVM lowering pattern for memref.transpose
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    Permutation maps can sometimes be confusing because it's easy to mix up the source and the target dimensions. I think this is what happened with the lowering Pattern for memref.transpose:
https://github.com/llvm/llvm-project/blob/main/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp#L1562

For the testcase to demonstrate the problem I will use the textual representation of verified Ops where it is clear what the shape and strides should be as the reference:

test.mlir:
```mlir
func.func @transpose(%arg0: memref<1x2x3xf32, strided<[6, 3, 1], offset: ?>>) -> memref<3x1x2xf32, strided<[1, 6, 3], offset: ?>> {
  %0 = memref.transpose %arg0 (i, j, k) -> (k, i, j) : memref<1x2x3xf32, strided<[6, 3, 1], offset: ?>> to memref<3x1x2xf32, strided<[1, 6, 3], offset: ?>>
  return %0 : memref<3x1x2xf32, strided<[1, 6, 3], offset: ?>>
}
```

test.cpp:
```c++
#include <mlir/ExecutionEngine/CRunnerUtils.h>
#include <iostream>

extern "C" void _mlir_ciface_transpose(StridedMemRefType<float, 3> *, StridedMemRefType<float, 3> *);

int main() {
 StridedMemRefType<float, 3> in, out;

    in.sizes[0] = 1;
 in.sizes[1] = 2;
    in.sizes[2] = 3;
    in.strides[0] = 6;
 in.strides[1] = 3;
    in.strides[2] = 1;
 _mlir_ciface_transpose(&out, &in);

    std::cout << "output has sizes: [" << out.sizes[0] << ", " << 
        out.sizes[1] << ", " << out.sizes[2] << "] strides : [" << out.strides[0] << ", " << 
 out.strides[1] << ", " << out.strides[2] << "]\n";
    return 0;
}
```

```
$ mlir-opt --normalize-memrefs --memref-expand --finalize-memref-to-llvm --llvm-request-c-wrappers --convert-func-to-llvm --reconcile-unrealized-casts --llvm-legalize-for-export test.mlir -o test.llvm.mlir
$ mlir-translate --mlir-to-llvmir test.llvm.mlir -o test.ll
$ clang++-17 -I/mnt/build_llvm/llvm-project/mlir/include/ test.cpp test.ll
warning: overriding the module target triple with x86_64-pc-linux-gnu [-Woverride-module]
1 warning generated.
$ ./a.out 
output has sizes: [2, 3, 1] strides : [3, 1, 6]
```

We can see that instead of doing the (i,j,k)->(k,i,j) transposition, the lowering pass actually did it the other way around, i.e. (k,i,j)->(i,j,k).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV1lv2z4S_zT0y4CCRVk-HvwQ2zFQoMX-0T36GNDSyGZLkVoesdNPvxhKPuI02f6BBgYlDefmcOYX6b3aG8QlK1es3IxkDAfrlnHXnEY7W78s_0LXxiCDsgZa2XmopAFvWwyqRQ87hMqaJnpl9rDDSkaPoAITMw8o_QsEC606QewgHBC8ja5CkKZOn0G6PQaoVYvGK2t8Bp8gHJT5QasH5eF4kAEOsuvQYA1HFQ5JUtsjOrL5lwwBnYHGOmixddhkwUnjO-uRFQ9svGHjh0MInacvsWViu1fhEHdZZVsmtlo_nx-8c_Y7VoGJ7U7bHRPbVipDD60c8Siira15RkfeMrH9gu1XbP5lP3_-z5e7z6zqOiaKz3k5Fb0X_bq1ro8dfaikR8pQja01PjgZMO11zu40tvAJjkproJz2IqcQpQaHnUOPZjgW28AzOtUorOEfHaUMHR0Cpa_SKF2fxJT_g-z69PvgVI0e_MFGXdM5Sp9YHDbo0FTX7PUr-ZulTFzo03H_S9REaqKpMlqATcbXcxBzJkrp9mNWPAynxIp1fhKn4tQUgon14E_NijUrV1OiFLTkrNzQ0zaNx0DirNiy4pF-YgGcFY9XhcWJVP5KYU6UQeu7CoHNVn0YAEyUY2DF5k1NwRAJMDFXpOg7LT8uzjAx_0GU894C_mTM6Tr9oXDPoToM0ZlzxA9_WD-bbe6q5U1R0UV5U1MVEyv69VRRKFPpWCOwYj1cx8cTVpEuwKPZK4N0Nb9GY9D9Oyjts8PVhVfSyvrgULbX7bTiKbURJsSaCQHPVtXwRJaeKtXICp9uq_mffTKG6_7SISvWjbYy9ClJZfBA77_JuGDF6tYZZQL0vWeeKuhSl_9fHwmtwcZwpxIAQJnMq5_oWbkas3KT6ju_8N1u5-dtcd1-rUCcOYo3HH1nuTUyfW3kwpD_hhLxC0_fPRgmphS6WAMTU0rFfWZJvQ811VvxUNkYqCRYQfzCxtBFGjYe-iipmssVlcPAZGO4z-BZuLd54bxao79bufxDuVtOccdZbi5d-x3X7jP_sXOvRX7Dr_szufGMlWtDb7fHODSW8fUIPuwF90QxATpmbrsAnBvrWqnVT-R9f_LAhzeOp44mGueNMrcsPFhOcx14enCH_43oA6_40RGgcKSjSuM8cBpaNwIOK2sqpZFH4zBprXklffBnbRr3vbHGOnLBugCXGQnc9h_Eml3n4yWoVLSa5j3nPaE3rdyd3I2mq4pKS7PvGyTPZ8A_EUgxCbhEpeunX4OaoW8OvZCJLZzb72sLR-mMMnuqMfuMzqmagBZhg9bWUV9gW3Cq09hjstN8-jSd8K7iWpl44nsTqUD5t0ED8l6WSiUZyWEwA3s0SMinzq4BZkxsZZauZ6K9czXFq5l5fzuGjTSqyo8q7xv2qBYJZskAyviAsiZgVdtz7MO8p3FP054nBJJm_UBewLkTqZDQ4fo1Uu2k9yArQnD6BWpVE0QjDhsO6OAoX0A6G02d4EOGGdzpH0zeepGN6mVRL4qFHOEyny6KyWJWzKajw3IqmrLJSykWsp6Nd9WswVnTNPmu3pVigfORWoqxKMbzIs_LcppPs9l8Us2mNeaTyaxoFpJNxthKpftatG4_Ut5HXE7LfFKOtNyh9su-CRk8Qtrsm8HILVPp7eLes8lYKx_8VUtQQaf_N1I9lhtYxT0oA1_Spe3B823W3sf3o-j08m9j--SoZ2KbAvlfAAAA___9QuGH">