Issue 90019
Summary [mlir][bufferization] linalg.map in loops bufferize error
Labels mlir
Assignees
Reporter Artorias123
    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.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to