[Mlir-commits] [mlir] [mlir][transforms] Fix crash in remove-dead-values when function has non-call users (PR #183655)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Feb 26 17:00:08 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Mehdi Amini (joker-eph)
<details>
<summary>Changes</summary>
`processFuncOp` asserts that all symbol uses of a function are `CallOpInterface` operations. This is violated when a function is referenced by a non-call operation such as `spirv.EntryPoint`, which uses the function symbol for metadata purposes without calling it.
Fix this by replacing the assertion with an early return: if any user of the function symbol is not a `CallOpInterface`, skip the function entirely. This is safe because the pass cannot determine the semantics of arbitrary non-call references, so it should leave such functions alone.
Fixes #<!-- -->180416
---
Full diff: https://github.com/llvm/llvm-project/pull/183655.diff
2 Files Affected:
- (modified) mlir/lib/Transforms/RemoveDeadValues.cpp (+5-1)
- (modified) mlir/test/Transforms/remove-dead-values.mlir (+13)
``````````diff
diff --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp
index 12a47ba2fb65a..c70cd8d6beb68 100644
--- a/mlir/lib/Transforms/RemoveDeadValues.cpp
+++ b/mlir/lib/Transforms/RemoveDeadValues.cpp
@@ -302,7 +302,11 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module,
SymbolTable::UseRange uses = *funcOp.getSymbolUses(module);
for (SymbolTable::SymbolUse use : uses) {
Operation *callOp = use.getUser();
- assert(isa<CallOpInterface>(callOp) && "expected a call-like user");
+ // If a non-call operation references the function (e.g. spirv.EntryPoint),
+ // we cannot safely remove arguments or return values since we don't know
+ // what the user expects. Skip this function entirely.
+ if (!isa<CallOpInterface>(callOp))
+ return;
// Push an empty operand cleanup entry so that call-site specific logic in
// cleanUpDeadVals runs (it keys off CallOpInterface). The BitVector is
// intentionally all false to avoid generic erasure.
diff --git a/mlir/test/Transforms/remove-dead-values.mlir b/mlir/test/Transforms/remove-dead-values.mlir
index 87e77b2eb700f..7a08b2c94f0a8 100644
--- a/mlir/test/Transforms/remove-dead-values.mlir
+++ b/mlir/test/Transforms/remove-dead-values.mlir
@@ -826,3 +826,16 @@ func.func @replace_dead_operation_results_with_poison(%0: vector<1xindex>) -> ve
}
return %2 : vector<1xindex>
}
+
+// -----
+
+// Verify no crash when a function is referenced by a non-call op (spirv.EntryPoint).
+// The function should be preserved as-is since the pass cannot analyse non-call users.
+// CHECK: spirv.EntryPoint "GLCompute" @main_func
+// CHECK: llvm.func @main_func()
+module {
+ spirv.EntryPoint "GLCompute" @main_func
+ llvm.func @main_func() attributes {sym_visibility = "private"} {
+ llvm.return
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/183655
More information about the Mlir-commits
mailing list