[Mlir-commits] [mlir] [MLIR] Fix allSymUsesVisible inside private symbol table (PR #179596)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Feb 3 21:32:36 PST 2026
https://github.com/neildhar updated https://github.com/llvm/llvm-project/pull/179596
>From c10e3d18b09a4497645f274353f03dc01fc54bf1 Mon Sep 17 00:00:00 2001
From: Neil Dhar <neildhar at meta.com>
Date: Tue, 3 Feb 2026 18:37:05 -0800
Subject: [PATCH] [MLIR] Fix allSymUsesVisible inside private symbol table
We currently always set `allSymUsesVisible` to true if the current
operation is a symbol table that defines a private symbol. However, this
is incorrect since the symbols inside that symbol table can still be
referenced by siblings of the symbol table.
For example, if we have a nested module defining a private symbol, the
functions inside it may be referenced by functions in the outer module.
This can affect `DeadCodeAnalysis` for example, which computes whether a
callable's uses are all known.
---
mlir/lib/IR/SymbolTable.cpp | 12 ++++--------
.../test-dead-code-analysis-nested-module.mlir | 16 ++++++++++++++++
2 files changed, 20 insertions(+), 8 deletions(-)
create mode 100644 mlir/test/Analysis/DataFlow/test-dead-code-analysis-nested-module.mlir
diff --git a/mlir/lib/IR/SymbolTable.cpp b/mlir/lib/IR/SymbolTable.cpp
index 4e191e7d612ad..0725d7b7a162d 100644
--- a/mlir/lib/IR/SymbolTable.cpp
+++ b/mlir/lib/IR/SymbolTable.cpp
@@ -357,14 +357,10 @@ void SymbolTable::walkSymbolTables(
Operation *op, bool allSymUsesVisible,
function_ref<void(Operation *, bool)> callback) {
bool isSymbolTable = op->hasTrait<OpTrait::SymbolTable>();
- if (isSymbolTable) {
- SymbolOpInterface symbol = dyn_cast<SymbolOpInterface>(op);
- allSymUsesVisible |= !symbol || symbol.isPrivate();
- } else {
- // Otherwise if 'op' is not a symbol table, any nested symbols are
- // guaranteed to be hidden.
- allSymUsesVisible = true;
- }
+ // If the current op is not a symbol table, or if it is a symbol table but
+ // does not itself define a symbol, outside ops cannot reference symbols
+ // defined inside it, so all their uses are visible.
+ allSymUsesVisible |= !isSymbolTable || !isa<SymbolOpInterface>(op);
for (Region ®ion : op->getRegions())
for (Block &block : region)
diff --git a/mlir/test/Analysis/DataFlow/test-dead-code-analysis-nested-module.mlir b/mlir/test/Analysis/DataFlow/test-dead-code-analysis-nested-module.mlir
new file mode 100644
index 0000000000000..0d10d011d79b4
--- /dev/null
+++ b/mlir/test/Analysis/DataFlow/test-dead-code-analysis-nested-module.mlir
@@ -0,0 +1,16 @@
+// RUN: mlir-opt --pass-pipeline="builtin.module(builtin.module(test-dead-code-analysis))" %s 2>&1 | FileCheck %s
+
+// Test that when dead code analysis runs directly on a nested module with a
+// private symbol name, we account for the fact that functions within that
+// module may be invoked from outside the module.
+module {
+ module @inner_module attributes {sym_visibility = "private"} {
+ // CHECK: nested:
+ // CHECK-NEXT: region #0
+ // CHECK-NEXT: ^bb0 = live
+ // CHECK-NEXT: op_preds: predecessors: (none)
+ func.func nested @nested_inner(%arg0: i32) -> i32 attributes {tag = "nested"} {
+ return %arg0 : i32
+ }
+ }
+}
More information about the Mlir-commits
mailing list