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

    <tr>
        <th>Summary</th>
        <td>
            [mlir][bufferization] linalg.map in loops bufferize error
        </td>
    </tr>

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

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

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

<pre>
    We have found that linalg.map in the loop may produce incorrect results in certain specific scenarios when using one-shot-bufferize.

```
func.func private @f(%arg: tensor<32x1xf32>) -> ()
func.func @test(%arg0: i32, %arg2: tensor<32x1xf32>, %arg3: tensor<32x1xf32>) {
      %cst_0 = arith.constant 0.000000e+00 : f32
      %c0_i32 = arith.constant 0 : i32
      %c1_i32 = arith.constant 1 : i32
      %0 = tensor.empty() : tensor<32x1xf32>
 %1 = linalg.fill ins(%cst_0 : f32) outs(%0 : tensor<32x1xf32>) -> tensor<32x1xf32>
      scf.for %arg1 = %c0_i32 to %arg0 step %c1_i32 : i32 {
        %2 = linalg.map { arith.subf } ins(%1, %arg2 : tensor<32x1xf32>, tensor<32x1xf32>) outs(%0 : tensor<32x1xf32>)
        %3 = tensor.empty() : tensor<32x1xf32>
        %4 = linalg.map { arith.subf } ins(%2, %arg3 : tensor<32x1xf32>, tensor<32x1xf32>) outs(%3 : tensor<32x1xf32>)
 func.call @f(%4) : (tensor<32x1xf32>) -> ()
      }
 return
}
```
This IR will be bufferized into the following form:
```
// ./bin/mlir-opt -one-shot-bufferize -allow-unregistered-dialect bufferize_test.mlir 
module {
  func.func private @f(tensor<32x1xf32>)
  func.func @test(%arg0: i32, %arg1: tensor<32x1xf32>, %arg2: tensor<32x1xf32>) {
    %0 = bufferization.to_memref %arg2 : memref<32x1xf32, strided<[?, ?], offset: ?>>
    %1 = bufferization.to_memref %arg1 : memref<32x1xf32, strided<[?, ?], offset: ?>>
    %cst = arith.constant 0.000000e+00 : f32
 %c0_i32 = arith.constant 0 : i32
    %c1_i32 = arith.constant 1 : i32
 %alloc = memref.alloc() {alignment = 64 : i64} : memref<32x1xf32>
 linalg.fill ins(%cst : f32) outs(%alloc : memref<32x1xf32>)
    scf.for %arg3 = %c0_i32 to %arg0 step %c1_i32  : i32 {
      linalg.map { arith.subf } ins(%alloc, %1 : memref<32x1xf32>, memref<32x1xf32, strided<[?, ?], offset: ?>>) outs(%alloc : memref<32x1xf32>)
      %alloc_0 = memref.alloc() {alignment = 64 : i64} : memref<32x1xf32>
      linalg.map { arith.subf } ins(%alloc, %0 : memref<32x1xf32>, memref<32x1xf32, strided<[?, ?], offset: ?>>) outs(%alloc_0 : memref<32x1xf32>)
      %2 = bufferization.to_tensor %alloc_0 : memref<32x1xf32>
      func.call @f(%2) : (tensor<32x1xf32>) -> ()
    }
    return
  }
}
```
The %alloc is modified in each iteration, but semantically in the original graph, the result of %1 should be the fixed output of fill and should not be modified. Therefore, it seems that there is an issue with the bufferization here.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV1Fv6jgT_TXmZUTk2AmUBx5auEjf66cr7WNlkjHxyrGR7dy2--tXdhKgXMJtu3e1UUUhGc_MmfGcEwvv1cEgrkn5RMrtTHShsW796IJ1Svic8dne1m_rPxAa8QNB2s7UEBoRQCsj9CFrxRGUgdAgaGuP0Io3ODpbdxWCMpV1DqsADn2ng4-WFboglAF_xEpJVYGv0AinrIeXBg10XpkDWINz39gw33dSolN_YUboltDH4XNBh7_0U3amyuIHHJ36IQICKagk7IGwUrgD4Y8Q0HjrCN9w9pq_Ss4I_0bYCuaEf4Nkubr2RQoa0IeTGxr9KM4I20B_h017Hk34veBk-dQHhXQRVlY-PFMgfAvCqdBklTU-CBOAZjRdSNgTjRaPEP1crabPirOby2FM_mpFPrUin1jRZ9cjyrA9hre-ejAJtF9PWJmnpcPGkUprUMb35R1x96jYCmwXhkd02vPYvzth0-UrmUnrhpb0aZzLFezwgIIPeHxXllSB6z6lOrBLMHEKyPJpqKHv9hLIcnuGl1_smTtwNpMwP1iOn7LkX-zW2UPxGZwXs8H_Ic5760ecaVYrofXFvBcjOsIePjz0A9rldvjpMHTODFwz3r0ine-N8vC__8NL3Mh7hBNT1aBMsIkSpdXavkRCk9a1hN-mL8J2hO0gI2y3V4awXauVm9tjgPnPPAhzEX3OO-PwoHxAh_W8VkJHnj1ZPUfmyqIf6GO0tu40Xu7kSdL8xd76DEHmvybIOxx6RZAn8hlRiqCsyYJ9brF1KN8NWH_r0iPbgA9O1VgTvol6x3cpC74j5TZ-s1J6DGnr8F1M4HIaTvR1P3j-bwWvfPi0LHxWET6lBxGv1rZKtj3gLN0YCWb5JLQ6mBZNn_mi6D0sikgZt8t0Aj0lErclYkxkwuXllL-XAv5hKZjSgg8S41CZzbiPpjLd_K6989X6wKmxw3vIb2_tV8tG_5uyPd-Le104dpsienqDj7i88HdL3dhX1e2sbQDv5O3i0bTS4XnclYfW1kqqpHOAompABXQJbCzrvgvgsRUmqJj823g8sE4dYtfh4MSxSS8BDQ4nA7Cynwzf2E7XUU6TfKpXrGNDjl0ySXQgTD2aGRui6ZhPBt8bdCitw-hexTyw9f15JcRHMXthQHnfIbyo0KQw7_oF0S6b1Wter_hKzHCdL_OCsrLIF7NmjbLcC7qU5ZIulgtc1Jzlq4dFvZRLtpKczdSaUVbQgpV0kdN8ka1k8fDA85rmS75aUUEKiq1QOtP6R5tZd5ildNYrSvPVTIs9ap_OY4xF_SaMxZOZW0fz-b47eFJQrXzwZwdBBZ3OcGlBuSXl0ztMpNxendfiWc2fXxcAnbNu1jm9bkI4-vimkl5KDio03T6rbEvYLsYb_s2Pzv6JVSBsl7L3hO0SgL8DAAD__wfiFks">