Issue |
156032
|
Summary |
[mlir][bufferization] Possibly missing side-effects on `bufferization.to_buffer`
|
Labels |
mlir:bufferization
|
Assignees |
|
Reporter |
zero9178
|
Given the following example:
```mlir
func.func private @read_tensor(memref<32xi32>)
func.func @foo(%0 : index) {
scf.forall (%arg0) in (%0) {
%c = arith.index_cast %arg0 : index to i32
%t = tensor.empty() : tensor<32xi32>
%m = bufferization.to_buffer %t : tensor<32xi32> to memref<32xi32>
linalg.fill ins(%c : i32) outs(%m : memref<32xi32>)
func.call @read_tensor(%m) : (memref<32xi32>) -> ()
}
return
}
```
the program has different bevahiour if LICM is run or not.
`mlir-opt -p "builtin.module(loop-invariant-code-motion, one-shot-bufferize)"`:
```mlir
module {
func.func private @read_tensor(memref<32xi32>)
func.func @foo(%arg0: index) {
%alloc = memref.alloc() {alignment = 64 : i64} : memref<32xi32>
scf.forall (%arg1) in (%arg0) {
%0 = arith.index_cast %arg1 : index to i32
linalg.fill ins(%0 : i32) outs(%alloc : memref<32xi32>)
func.call @read_tensor(%alloc) : (memref<32xi32>) -> ()
}
return
}
}
```
desired behaviour without LICM:
`mlir-opt -p "builtin.module(one-shot-bufferize)"`:
```mlir
module {
func.func private @read_tensor(memref<32xi32>)
func.func @foo(%arg0: index) {
scf.forall (%arg1) in (%arg0) {
%0 = arith.index_cast %arg1 : index to i32
%alloc = memref.alloc() {alignment = 64 : i64} : memref<32xi32>
linalg.fill ins(%0 : i32) outs(%alloc : memref<32xi32>)
func.call @read_tensor(%alloc) : (memref<32xi32>) -> ()
}
return
}
}
```
(https://godbolt.org/z/fEjz75En7)
The root cause for the behaviour is that both `tensor.empty()` and `bufferization.to_buffer` are moved out of the `scf.forall`. If only `tensor.empty` were to be moved out of the `scf.forall` the privatization logic of bufferization would kick in and ensure correctness through copying (https://godbolt.org/z/esM4vxbK7)
I am not 100% sure about what is the right fix, but I believe a viable option would be for `bufferization.to_buffer` to have side-effects.
I believe these could be either:
* A `write` effect on the resulting `memref` unless the `readonly` attribute is set. Note that in reality it is not guaranteed that there is a write effect on the result. I am unsure whether the effects interface models the presence of a side-effect as "yes or no" or "maybe or no".
* Simply remove `Pure`. This is conservative and properly models the "maybe".
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs