<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54292>54292</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[mlir] Incorrect strides after `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>
youben11
</td>
</tr>
</table>
<pre>
Trying to execute the code generated from this IR would result in a segfault
```
#map = affine_map<(d0, d1, d2) -> (d1 * 8194 + d0 * 4097 + d2)>
module {
func @main(%arg0: memref<3x2x4097xi64>) -> memref<2x3x4097xi64> {
%0 = memref.transpose %arg0 (d0, d1, d2) -> (d1, d0, d2) : memref<3x2x4097xi64> to memref<2x3x4097xi64, #map>
%1 = memref.alloc() : memref<2x3x4097xi64>
memref.copy %0, %1 : memref<2x3x4097xi64, #map> to memref<2x3x4097xi64>
return %1 : memref<2x3x4097xi64>
}
}
```
After investigating, I found that the main reason was that the strides of the source tensor (%0) in the copy were set [4097, 8194, 8194] (which in my understanding should be set to [4097, 8194, 1]), which will definitely lead to computing an index out of the memory region of the source memref.
In case this can be helpful, the transpose operation is generated using a custom lowering of a custom transpose op, which is special in the sense that the last dimension is kept as is.
```
mlir::Value createMemRefTransposeOp(mlir::PatternRewriter &rewriter,
mlir::Location loc, mlir::Value tensor,
mlir::OpResult result) {
std::vector<unsigned int> perms = {};
auto n_dim = tensor.getType().cast<MemRefType>().getShape().size();
// invert dimensions except last one
for (int i = n_dim - 2; i >= 0; i--)
perms.push_back(i);
perms.push_back(n_dim - 1);
AffineMapAttr perm = AffineMapAttr::get(
AffineMap::getPermutationMap(perms, rewriter.getContext()));
mlir::memref::TransposeOp transposeOp =
rewriter.create<mlir::memref::TransposeOp>(loc, tensor, perm);
// we allocate a new buffer and copy the strided memref into it to produce
// a totally new tranposed memref
mlir::memref::AllocOp allocOp = rewriter.create<mlir::memref::AllocOp>(
loc, result.getType().cast<MemRefType>());
rewriter.create<mlir::memref::CopyOp>(loc, transposeOp.getResult(),
allocOp.getResult());
return allocOp.getODSResults(0).front();
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJydVslu4zgQ_Rr5QsSQJXk7-OA4HSDANNJIB3MNaKlkc1oiBS6xPV8_VaQsyU46SY8hyFxqeax6VdRWFafVsz4JuWNWMThC7iwwuweWqwLYDiRobqFgpVY1rgvDHp7YQbmqYBqMqywTknFmYFdynEXxXRSv2_csbp8wTdKaNyxK7xgvSyHhBadRuomSRRFHyYYVE_9OomTJbqL0G6OdCb7XbDFZZji4ZUXs51m8nIc5SaNscFGrwlXAWDS_DQuMlU7mLMrimguJ9qJkyvUujtI1q6HWUCKA9JgcyeBRzDIydXbfCSTHdCgwNI--kmnsDxXEx1ZzaRplgLW-2CcH9Gtxv_MRNkrS-7BQPQS4C0YLbjIEx6tK5T4MV36ujthbaBVz1Zz8UYMjb_V36kMovwc8dKLBOi0_s9trRPO7llPd4Ipr_r0uLWjk5ysYK3bcIssJ3AMrlZMFsplbT3XiBmLgRkl24KbfMFaLAgxTZZgqp3OsDpBGaRbYFFMoUT2UDAbpABolwbJoekvQySPRt_uf3pHqYS_yPSnWJ4ZgQBvLZUF1aPa-urbBCsbvHUMTtELEx2EwdBBVxQrAshIWqhOrgBekm6u6cXRwxiV6K-DIlLPnA2GclT7h0XcCj355yjbxw3g-SJZzA6EN5GgQMe6hakpXERJS7tmvGuocZBeF-z7ijAfDcmcsdpRKYbxoBZ13i0Mj_RHRjGkgF7w6x9tgIqDPVsWNZYWocbV1-wsayzChwow_aEx1JTSyDp-_eeUwjUgFC9-hfoLy-QzlEZEseskf3CK35BMctCCSRclMt2NE3DP7s19v8S-Vh3D5Ct2wa1SBdf_T-GPzFJp16Nm-_PsmZmwRxF4ht-gj3TgM4U5iuoS0VMWYy9r4RkJqWHRpp8wd0ky-YNz9foA53oF9PjUQWs0YWYNmNm1IaZ3arN9CwZ973kka8W87HLiIknt8fCHrQYYN3lc5ZdgnXknoen6oTsTOhAcV4N2wBI36pW-0GvvZzQ0562LqTzpunNm_bHn-i8xcgnkrcLY-uRRc-0vuO2_W1mqv5rFcLIewYwzozIO8dkKdwA_Ud9YzhJaThcdBRDnzjkK5UdLC0bYRDE-PqOfDucHSeEDxvvIe_UU9hNS5CeWB6fzUXMhyy-eOvz4U7yb4AMxfUGgem4GEA9u6ssTqws4YmmvflIu2QRFDFRO-UTYa7_8crqxy3LJo9-Qt0gkJ3Vn_49isCQ7Ggrf_lMCvBqLVbak-iGQbkFCKX66Uy4h9FcQGo3adiD5B5Pyp7QjBxx90F_q1cXlr5xKrv90Hso93P4M4EnhBN-gYPy-lvSr8t5f7qFilxTJd8pEVtoIV3oz-2HilPshcaY39q7u0ub_9Uev6w4wMOV2t9tY2hsLkebITdu-2-KGD3Lyvqtfz3w2y6h-0i1NhjAOEfD_NkmUy2q-m28lim5UZ8GyapTPI5lBmM76YzxbLNEmXo4pvoTKEM0oSop83gWOEPBKrJE6SOI2X8TKJs-U4WxR5kU0WPIYZn8wT_GwF_DapxoRjrPRupFce0tbtDG5WwljTb3Ljm7YPC9nHzrxXenVSbgtyMhl53yuP_T9OW5Fg">