<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/141667>141667</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[MLIR] Bufferization of `tensor.generate` does not take into account repetitions
</td>
</tr>
<tr>
<th>Labels</th>
<td>
mlir
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
erick-xanadu
</td>
</tr>
</table>
<pre>
Hello,
I have what I believe is an error in the bufferization of `tensor.generate`. When `tensor.generate` is being bufferized, it will bufferize the function body with the same rules as outside the body. In the following example, we see that `circuit_0` is called with a different value in the argument each time it is called. This value is obtained through the extraction, addition, and insertion into a tensor obtained from the context above.
```mlir
func.func private @circuit_0.finitediff0(%arg0: tensor<2xf64>) -> tensor<2x2xf64> {
%cst = arith.constant 3.000000e-01 : f64
%cst_0 = arith.constant dense<3.000000e-01> : tensor<2x2xf64>
%0 = call @circuit_0(%arg0) : (tensor<2xf64>) -> tensor<2xf64>
%generated = tensor.generate {
^bb0(%arg1: index, %arg2: index):
// important bit
%extracted = tensor.extract %arg0[%arg2] : tensor<2xf64>
%2 = arith.addf %extracted, %cst : f64
%inserted = tensor.insert %2 into %arg0[%arg2] : tensor<2xf64>
// new value being passed here each time we loop trhough tensor.generate
%3 = func.call @circuit_0(%inserted) : (tensor<2xf64>) -> tensor<2xf64>
%4 = arith.subf %3, %0 : tensor<2xf64>
%extracted_1 = tensor.extract %4[%arg1] : tensor<2xf64>
tensor.yield %extracted_1 : f64
} : tensor<2x2xf64>
%1 = arith.divf %generated, %cst_0 : tensor<2x2xf64>
return %1 : tensor<2x2xf64>
}
```
However, after bufferization, we see the following code:
```mlir
func.func private @circuit_0.finitediff0(%arg0: memref<2xf64>) -> memref<2x2xf64> {
%cst = arith.constant 3.000000e-01 : f64
%0 = memref.get_global @__constant_2x2xf64 : memref<2x2xf64>
%1 = call @circuit_0(%arg0) : (memref<2xf64>) -> memref<2xf64>
%alloc = memref.alloc() {alignment = 64 : i64} : memref<2x2xf64>
linalg.map outs(%alloc : memref<2x2xf64>)
() {
%2 = linalg.index 0 : index
%3 = linalg.index 1 : index
%4 = memref.load %arg0[%3] : memref<2xf64>
%5 = arith.addf %4, %cst : f64
memref.store %5, %arg0[%3] : memref<2xf64>
// value of arg0 changes
// with each iteration
%6 = func.call @circuit_0(%arg0) : (memref<2xf64>) -> memref<2xf64>
linalg.generic {indexing_maps = [affine_map<(d0) -> (d0)>, affine_map<(d0) -> (d0)>, affine_map<(d0) -> (d0)>], iterator_types = ["parallel"]} ins(%6, %1 : memref<2xf64>, memref<2xf64>) outs(%6 : memref<2xf64>) {
^bb0(%in: f64, %in_0: f64, %out: f64):
%8 = arith.subf %in, %in_0 : f64
linalg.yield %8 : f64
}
%7 = memref.load %6[%2] : memref<2xf64>
linalg.yield %7 : f64
}
linalg.generic {indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>], iterator_types = ["parallel", "parallel"]} ins(%alloc, %0 : memref<2x2xf64>, memref<2x2xf64>) outs(%alloc : memref<2x2xf64>) {
^bb0(%in: f64, %in_0: f64, %out: f64):
%2 = arith.divf %in, %in_0 : f64
linalg.yield %2 : f64
}
return %alloc : memref<2x2xf64>
}
```
It looks like this may stem from the lack of bufferization of the `linalg.map` op, but I am not entirely sure.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0WElv4zoS_jX0pRBBpizZPviQOB10gJnLYIA5GpRYsjihSIOk7OT9-gdSq5csne5nNDoJxaqv1q_KYtaKvULckPSBpI8z1rhKmw0aUbzcvTLFeDPLNX_b_EQpNaFbEt-T-P4ZKnZEOFXMwTPkKAUeEYQFpgCN0QaEAlch5E1ZohF_MSe0Al0CyWKHymoT7VGhYQ5JFkfwvwrV7Wdea45C7QddyAndgnBwElKOpwGvbFQRoLzRcBKuCseW1QimkWiBWdCNs4K3Av5eBM-ttaWWUp88Fr6y-iDRA50QLPrLzHkLC2GKRrhd3NlWMCmRt1AMuPDWoHJwZLLBPgzM7JvanyIrKnCiRm__IB3BfythexELOndMKOTgKqObfesDvjrDgnPeKsa5GH5XHISyaILnQjkNDNpIjqpKo-ugp9DK4asDlusjRm0-SRa3_2opDInvQxwj_x8cjDgyh0AWo-tRKZRw6J2NCV0RmjKzj0ly36GSZEtfy2xBkh-EruGOJD-mT_pnQJYPHgwACE0L64Akj8CMcFVUaGUdUw6SKA4fvIvn4CG87FRoF98S46gskmQ7FQ-Q50YOZg4aW20-L2cuT9yk66CF0NWXvL0E6GubB6CLgodpTNIfeT4Czz2oUBxffc7bMzo5W5Pkvs0mQAv1ROgTiPqgTQhJLtzkYdrV07kd3SH0vqYPPVD6eBm7M8eCSjrJBOO8PIPprG7TPE1jEG3r99yY9qxVHKr6W1aFKCg8de3VcsmBWYscKjQ46ckTgtT6AM5UbdtdsNHE3iQYGtrknVrpPfp2vXTJJDRdTOJqmzzENeniGX-eliEFu_k7uV4MIZ1_HtJO_E2g5Nfqzxp0eaXruh_mE-e4OJZnPTIWze7K0akqg64xqlf3PiJZPk7prg3xT33CI5pApaVDcz61zmbAdEYUmuPQc1cM-m0KrbE2WN4qksmT36ZQuGS8Vnm0R7fbS52zUNK7Xa9k12HChYmDIV_9XCb-a0z7paD0IRkQmJS6mHoXDgLA2keOSbFXYS77O51zIlv0dftdPzsLpFBM7qOaHcLK0TnW2XRTe7Br7NzeThjZAC7ItsMIMwDaFmnnQcscyfWl-XgJzjUupqGSmvFzwk16ang35J2e9MYYWHxA_9BjWqcNBg3jiPsU_DIwge9brtel37xiKCqm9mivr4WtLfC_cJ5wfLufuZJ9SvPfL9Se30fALk-B_UThMx_SJNR-V7ODDbaQ9IGVpVDoj0iyJXTF4wGk_ysAezr7wzfTx3b39sHSZufeDjiYRSg9MOMXWkmoH82-jYTq6j7rUjp_J4t0e5v5xs7J3pNcT1gQLhYnofpqa-GF2sXnJ7pxw8E6ZHHUFGpgdWP6CjXRN3Dq7308blcBw2xd3WiWwE5nVbq81bhZ2zj0S117ibu8nBP96PzNMt0Cn18WVnf2QSH-I1K_UMoh1R8VdzdXJgvZTXLfvsf5vzIelg_fK60_1RUXe36_st3uiEHqssDo1SIyVvW4zH0cDe_UrX3u2fk1_sWCFC9-aRMWavYG1mE9fg2WrHjxA-LqDYV_SLJ4HN7-i74-eO_yxsEzsBqUdoDKCYPyDWxjMIIZ3yR8nazZDDfz5WKVLJfLJJlVm3yxKtIsLfJlxmPKMJ9nSU6zdLFervIV8pnY0JimcUqXNKarNInWa87jJMFijSWfrxZkEWPNhIykPNaRNvuZsLbBzXwxz7LlTLIcpd20ZRvWz1CgM7Px9-_yZm_JIpbCOjtqcMLJ8Nbn3_96_o-niIcvvakBrtEG9x17we5dQ1HoRjkweEAXXkrYWWPkpnLuYP2CHGbtXriqyaNC14Q-eTO6H3cHo_-PhSP0KXhlCX3qHDtu6N8BAAD__2HNQb4">