<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/122869>122869</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[MLIR] Bufferization behaving differently based on the position of extract_slice.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
mlir:bufferization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
pashu123
</td>
</tr>
</table>
<pre>
**Input IR:**
```
func.func @test_one(%arg0: index, %arg1: vector<64x64xf32>, %arg2: tensor<2x4096x10x64xf16>) -> tensor<1x64x1x64xf16> {
%c0 = arith.constant 0 : index
%0 = tensor.empty() : tensor<64x64xf16>
%1 = arith.truncf %arg1 : vector<64x64xf32> to vector<64x64xf16>
%2 = vector.transfer_write %1, %0[%c0, %c0] {in_bounds = [true, true]} : vector<64x64xf16>, tensor<64x64xf16>
%extracted_slice = tensor.extract_slice %arg2[%arg0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<2x4096x10x64xf16> to tensor<1x64x1x64xf16>
%inserted_slice = tensor.insert_slice %2 into %extracted_slice[0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<64x64xf16> into tensor<1x64x1x64xf16>
return %inserted_slice : tensor<1x64x1x64xf16>
}
func.func @test_two(%arg0: index, %arg1: vector<64x64xf32>, %arg2: tensor<2x4096x10x64xf16>) -> tensor<1x64x1x64xf16> {
%c0 = arith.constant 0 : index
%0 = tensor.empty() : tensor<64x64xf16>
%1 = arith.truncf %arg1 : vector<64x64xf32> to vector<64x64xf16>
%extracted_slice = tensor.extract_slice %arg2[%arg0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<2x4096x10x64xf16> to tensor<1x64x1x64xf16>
%2 = vector.transfer_write %1, %0[%c0, %c0] {in_bounds = [true, true]} : vector<64x64xf16>, tensor<64x64xf16>
%inserted_slice = tensor.insert_slice %2 into %extracted_slice[0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<64x64xf16> into tensor<1x64x1x64xf16>
return %inserted_slice : tensor<1x64x1x64xf16>
}
```
**Command**: `mlir-opt above.mlir -eliminate-empty-tensors -canonicalize`
**Output**
```
module {
func.func @test_one(%arg0: index, %arg1: vector<64x64xf32>, %arg2: tensor<2x4096x10x64xf16>) -> tensor<1x64x1x64xf16> {
%c0 = arith.constant 0 : index
%0 = tensor.empty() : tensor<64x64xf16>
%1 = arith.truncf %arg1 : vector<64x64xf32> to vector<64x64xf16>
%2 = vector.transfer_write %1, %0[%c0, %c0] {in_bounds = [true, true]} : vector<64x64xf16>, tensor<64x64xf16>
%extracted_slice = tensor.extract_slice %arg2[%arg0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<2x4096x10x64xf16> to tensor<1x64x1x64xf16>
%inserted_slice = tensor.insert_slice %2 into %extracted_slice[0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<64x64xf16> into tensor<1x64x1x64xf16>
return %inserted_slice : tensor<1x64x1x64xf16>
}
func.func @test_two(%arg0: index, %arg1: vector<64x64xf32>, %arg2: tensor<2x4096x10x64xf16>) -> tensor<1x64x1x64xf16> {
%c0 = arith.constant 0 : index
%0 = arith.truncf %arg1 : vector<64x64xf32> to vector<64x64xf16>
%extracted_slice = tensor.extract_slice %arg2[%arg0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<2x4096x10x64xf16> to tensor<1x64x1x64xf16>
%extracted_slice_0 = tensor.extract_slice %extracted_slice[0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<1x64x1x64xf16> to tensor<64x64xf16>
%1 = vector.transfer_write %0, %extracted_slice_0[%c0, %c0] {in_bounds = [true, true]} : vector<64x64xf16>, tensor<64x64xf16>
%inserted_slice = tensor.insert_slice %1 into %extracted_slice[0, 0, 0, 0] [1, 64, 1, 64] [1, 1, 1, 1] : tensor<64x64xf16> into tensor<1x64x1x64xf16>
return %inserted_slice : tensor<1x64x1x64xf16>
}
```
The only difference between `test_one` and `test_two` is the placement of `tensor.extract_slice`. test_one doesn't get rid of the empty buffer, whereas test_two gets rid of the empty buffer and reuses the extracted slice.
@matthias-springer Could you suggest what would be happening here? Do you know if it is the intended behaviour?
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWN1u4zYTfRr6ZmCBon5sX_jCsdfAAt-HAoveB7Q0lthKpECOYmefviAlJU6dpD-bttlgAUO2ycPhnOHM4UDSOVVpxDXLbli2m8meamPXnXR1H4tkdjDl_ZqJDRObz7rrCT5_YclmGGA8fHI-fvjm2Osi8g9gKSd0dGs0MrFkIpO24izZgNIlnpnYwjAW-7E7LMhYlmzz9Jyn52MiWPLpESM8hlC7gBHnlK_yc8wDNM4DdAVzlnx6BMV-Mn5EAFvcML4Bb7HgwJIdSKuojgqjHUlN4Acn70bggBtsRth2dB-orOCJP6PPgyPjyvhiB7K9Lo4TXXiRL5C5mnhiVASjAyQiK7U7or09WUUY9hwDxv1Jepbj_4KzbOf5K317ML0uXbDDshuyPXpQ-M52bLF71rsxxNvXKeOZrCwIy1vXqAKfhG6YmibGMw1ehqwQW7h8ZMG5QCdP_XP6eTFx-ch28EcJ4mP7Ym5MDJR2aJ8lMMw8-i9AaTLPsGbZzZvTuQz2sO_rTCxSb_WzhDavLmWL3VDR11VMJ_Ojit-mir__OnnfOvSjine_u5SHy3pr2lbqcry5Ex-snLeNsnPTEciDucPI_4U5NqpVWhLOQ7XMh90czAupjVaFbNRXHE1P1n_qqevppbagNWXf4FS9779J-AsC8y0S8w-JzHsv0o8ggx9Jar5BbAAemgZ4pq7fW9vw9-r6DWvzu0_8awK3_FUK_0K-Xx33JYnXRPdFdZzU8Irqf6WWf15p4o-vNJedxc81gtHNPZTqeESLukA4IJ0Qte9vHrqLnIPU5cOQF6acg3JANULXyAJb1ATmOECuc5nlPILJHJQGnWZiQVAhgVWlX-lNhcsfDr13xsfsVKNF6WDa1ePdSwuCixZ7h4NfDycIwYVopJ_yVhLVSrq566zSFVrYmr4p4d704PqqQkdwqiXBKQwfEGrZdaiVrsA7xJI97EyA_6rNCdQRFE3RUJpQl-iX1fJOmd6yZM_4Zlauk3KVrOQM1_EiyZdpkiWrWb0-yiLP8kXBcZGneZGLVZKsOBfFwiOycqbWgouMx3HKl4mIVxEeFss8O6bZEsWqlDlLObZSNVHT3LWRsdVMOdfjOhZima9mjTxg48IbKiF8j8qSzRAx9VWSMpoJwbLdzK79-vmhrxxLeaMcuUeLpKgJb7n-_7_PX3wm31xaGMnq6iGRqLmHg3RYgtFDlhinAtQc4UlqRLPeNuuaqHPh1dieiX2lqO4PUWFaJvbeh_Fr3lnzCxbExD5QdEzsR5Z3a_FbAAAA___3l6ab">