Skip to content

Buffer deallocation pass: non-deterministic output #59118

@bondhugula

Description

@bondhugula

Each run of the buffer-deallocation produces different IR (a different ordering of bufferization.clone operations). A simple test case is below. A previous commit from Feb 2022 mentions this issue, but this never got fixed.

commit d955ca49379e73485304eb7f500db53e33109b0f
Author: Benjamin Kramer <[email protected]>
Date:   Thu Feb 17 13:51:27 2022 +0100

    [BufferDeallocation] Don't assume successor operands are unique
    
    This would create a double free when a memref is passed twice to the
    same op. This wasn't a problem at the time the pass was written but is
    common since the introduction of scf.while.
    
    There's a latent non-determinism that's triggered by the test, but this
    change is messy enough as-is so I'll leave that for later.
    
    Differential Revision: https://reviews.llvm.org/D120044
module {
  memref.global "private" constant @__constant_xi32 : memref<i32> = dense<0>
  func.func @buffer_dealloc_issue(%arg0: memref<32x64xf32>, %arg1: memref<32x64x6xf32>, %arg2: memref<i32>, %arg3: memref<32x64xf32>) {
    %c0_i32 = arith.constant 0 : i32
    %0 = memref.get_global @__constant_xi32 : memref<i32>
    %1 = affine.load %arg2[] : memref<i32>
    %2 = arith.maxsi %1, %c0_i32 : i32
    %3:4 = scf.while (%arg4 = %0, %arg5 = %0, %arg6 = %arg0, %arg7 = %arg1) : (memref<i32>, memref<i32>, memref<32x64xf32>, memref<32x64x6xf32>) -> (memref<i32>, memref<i32>, memref<32x64xf32>, memref<32x64x6xf32>) {
      %4 = affine.load %arg5[] : memref<i32>
      %5 = arith.cmpi slt, %4, %2 : i32
      scf.condition(%5) %arg4, %arg5, %arg6, %arg7 : memref<i32>, memref<i32>, memref<32x64xf32>, memref<32x64x6xf32>
    } do {
    ^bb0(%arg4: memref<i32>, %arg5: memref<i32>, %arg6: memref<32x64xf32>, %arg7: memref<32x64x6xf32>):  // no predecessors
      %4 = memref.alloc() : memref<i32>
      %5 = memref.alloc() : memref<32x64xf32>
      %6 = memref.alloc() : memref<32x64x6xf32>
      %7 = memref.alloc() : memref<i32>
      scf.yield %7, %4, %5, %6 : memref<i32>, memref<i32>, memref<32x64xf32>, memref<32x64x6xf32>
    }
    return
  }
}

$ mlir-opt -buffer-deallocation test_case.mlir

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions