Skip to content

Commit 13896b6

Browse files
[mlir][bufferization] Fix handling of indirect function calls (#94896)
This commit fixes a crash in the ownership-based buffer deallocation pass when indirectly calling a function via SSA value. Such functions must be conservatively assumed to be public. Fixes #94780.
1 parent 9d0754a commit 13896b6

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

mlir/lib/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -822,10 +822,11 @@ FailureOr<Operation *> BufferDeallocation::handleInterface(CallOpInterface op) {
822822

823823
// Lookup the function operation and check if it has private visibility. If
824824
// the function is referenced by SSA value instead of a Symbol, it's assumed
825-
// to be always private.
825+
// to be public. (And we cannot easily change the type of the SSA value
826+
// anyway.)
826827
Operation *funcOp = op.resolveCallable(state.getSymbolTable());
827-
bool isPrivate = true;
828-
if (auto symbol = dyn_cast<SymbolOpInterface>(funcOp))
828+
bool isPrivate = false;
829+
if (auto symbol = dyn_cast_or_null<SymbolOpInterface>(funcOp))
829830
isPrivate = symbol.isPrivate() && !symbol.isDeclaration();
830831

831832
// If the private-function-dynamic-ownership option is enabled and we are

mlir/test/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation/dealloc-callop-interface.mlir

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,22 @@ func.func @g(%arg0: memref<f32>) -> memref<f32> {
131131
// CHECK-DYNAMIC-LABEL: func private @f
132132
// CHECK-DYNAMIC-SAME: (memref<f32>) -> memref<f32>
133133
// CHECK-DYNAMIC: call @f({{.*}}) : (memref<f32>) -> memref<f32>
134+
135+
// -----
136+
137+
func.func @func_call_indirect(%m: memref<?xf32>, %f: (memref<?xf32>) -> (memref<?xf32>)) {
138+
%0 = func.call_indirect %f(%m) : (memref<?xf32>) -> (memref<?xf32>)
139+
return
140+
}
141+
142+
// CHECK-LABEL: func @func_call_indirect(
143+
// CHECK: %[[true:.*]] = arith.constant true
144+
// CHECK: %[[call:.*]] = call_indirect {{.*}} : (memref<?xf32>) -> memref<?xf32>
145+
// CHECK: %[[base_call:.*]], %{{.*}}, %{{.*}}, %{{.*}} = memref.extract_strided_metadata %[[call]]
146+
// CHECK: bufferization.dealloc (%[[base_call]] : {{.*}}) if (%[[true]])
147+
148+
// CHECK-DYNAMIC-LABEL: func @func_call_indirect(
149+
// CHECK-DYNAMIC: %[[true:.*]] = arith.constant true
150+
// CHECK-DYNAMIC: %[[call:.*]] = call_indirect {{.*}} : (memref<?xf32>) -> memref<?xf32>
151+
// CHECK-DYNAMIC: %[[base_call:.*]], %{{.*}}, %{{.*}}, %{{.*}} = memref.extract_strided_metadata %[[call]]
152+
// CHECK-DYNAMIC: bufferization.dealloc (%[[base_call]] : {{.*}}) if (%[[true]])

0 commit comments

Comments
 (0)