Skip to content

[MLIR][SymbolTable] Fix crash when SymbolTable is built on unverified IR#183945

Merged
joker-eph merged 1 commit into
llvm:mainfrom
joker-eph:fix/issue-159673
Mar 1, 2026
Merged

[MLIR][SymbolTable] Fix crash when SymbolTable is built on unverified IR#183945
joker-eph merged 1 commit into
llvm:mainfrom
joker-eph:fix/issue-159673

Conversation

@joker-eph
Copy link
Copy Markdown
Contributor

The SymbolTable::SymbolTable constructor asserted that all symbol names in the region were unique. This could cause mlir-opt to crash instead of producing a proper diagnostic when the IR contained both:

  1. An IsolatedFromAbove op (e.g., irdl.dialect) with a symbol user that looks up symbols in an ancestor symbol table, and
  2. Duplicate symbols in that ancestor (e.g., two func.func @test).

The crash occurred because IsolatedFromAbove ops are verified in verifyOnExit() before verifyRegionInvariants() runs the SymbolTable trait's verifyRegionTrait (which produces the proper duplicate-symbol diagnostic). When the isolated op's symbol use verification triggered SymbolTableCollection::getSymbolTable() on the ancestor, the constructor would assert instead of gracefully handling the invalid-but-not-yet- reported duplicate symbols.

The fix removes the assertion and silently skips duplicate symbol insertions (keeping the first definition). The proper diagnostic is still produced by the SymbolTable trait's verifyRegionTrait, which runs after all children have been verified.

Add a regression test in invalid.irdl.mlir using a self-referencing IRDL parametric type combined with duplicate function symbols.

Fixes #159673

The SymbolTable::SymbolTable constructor asserted that all symbol names
in the region were unique. This could cause mlir-opt to crash instead of
producing a proper diagnostic when the IR contained both:

1. An IsolatedFromAbove op (e.g., irdl.dialect) with a symbol user
   that looks up symbols in an ancestor symbol table, and
2. Duplicate symbols in that ancestor (e.g., two func.func @test).

The crash occurred because IsolatedFromAbove ops are verified in
verifyOnExit() before verifyRegionInvariants() runs the SymbolTable
trait's verifyRegionTrait (which produces the proper duplicate-symbol
diagnostic). When the isolated op's symbol use verification triggered
SymbolTableCollection::getSymbolTable() on the ancestor, the constructor
would assert instead of gracefully handling the invalid-but-not-yet-
reported duplicate symbols.

The fix removes the assertion and silently skips duplicate symbol
insertions (keeping the first definition). The proper diagnostic is
still produced by the SymbolTable trait's verifyRegionTrait, which
runs after all children have been verified.

Add a regression test in invalid.irdl.mlir using a self-referencing
IRDL parametric type combined with duplicate function symbols.

Fixes llvm#159673
@joker-eph joker-eph requested a review from jpienaar February 28, 2026 20:15
@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir mlir:irdl labels Feb 28, 2026
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Feb 28, 2026

@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-mlir-irdl

@llvm/pr-subscribers-mlir-core

Author: Mehdi Amini (joker-eph)

Changes

The SymbolTable::SymbolTable constructor asserted that all symbol names in the region were unique. This could cause mlir-opt to crash instead of producing a proper diagnostic when the IR contained both:

  1. An IsolatedFromAbove op (e.g., irdl.dialect) with a symbol user that looks up symbols in an ancestor symbol table, and
  2. Duplicate symbols in that ancestor (e.g., two func.func @test).

The crash occurred because IsolatedFromAbove ops are verified in verifyOnExit() before verifyRegionInvariants() runs the SymbolTable trait's verifyRegionTrait (which produces the proper duplicate-symbol diagnostic). When the isolated op's symbol use verification triggered SymbolTableCollection::getSymbolTable() on the ancestor, the constructor would assert instead of gracefully handling the invalid-but-not-yet- reported duplicate symbols.

The fix removes the assertion and silently skips duplicate symbol insertions (keeping the first definition). The proper diagnostic is still produced by the SymbolTable trait's verifyRegionTrait, which runs after all children have been verified.

Add a regression test in invalid.irdl.mlir using a self-referencing IRDL parametric type combined with duplicate function symbols.

Fixes #159673


Full diff: https://github.com/llvm/llvm-project/pull/183945.diff

2 Files Affected:

  • (modified) mlir/lib/IR/SymbolTable.cpp (+7-4)
  • (modified) mlir/test/Dialect/IRDL/invalid.irdl.mlir (+20)
diff --git a/mlir/lib/IR/SymbolTable.cpp b/mlir/lib/IR/SymbolTable.cpp
index 4e191e7d612ad..078401c8380f4 100644
--- a/mlir/lib/IR/SymbolTable.cpp
+++ b/mlir/lib/IR/SymbolTable.cpp
@@ -130,10 +130,13 @@ SymbolTable::SymbolTable(Operation *symbolTableOp)
     if (!name)
       continue;
 
-    auto inserted = symbolTable.insert({name, &op});
-    (void)inserted;
-    assert(inserted.second &&
-           "expected region to contain uniquely named symbol operations");
+    // Silently skip duplicate symbol names. Duplicate symbols are an
+    // invalid IR condition diagnosed by the SymbolTable trait's
+    // verifyRegionTrait. The constructor may be called before verification
+    // completes (e.g., when IsolatedFromAbove ops look up symbols in an
+    // ancestor symbol table during verification), so an assert here would
+    // crash instead of producing a proper diagnostic.
+    symbolTable.try_emplace(name, &op);
   }
 }
 
diff --git a/mlir/test/Dialect/IRDL/invalid.irdl.mlir b/mlir/test/Dialect/IRDL/invalid.irdl.mlir
index 8a7fffe1a9cbd..4ff7445c80de8 100644
--- a/mlir/test/Dialect/IRDL/invalid.irdl.mlir
+++ b/mlir/test/Dialect/IRDL/invalid.irdl.mlir
@@ -179,3 +179,23 @@ irdl.dialect @invalid_parametric {
     irdl.results(foo: %param)
   }
 }
+
+// -----
+
+// Regression test for https://github.com/llvm/llvm-project/issues/159673
+// A self-referencing IRDL parametric type combined with duplicate function
+// symbols in the enclosing module used to crash with a SymbolTable assertion
+// instead of producing a proper "redefinition of symbol" diagnostic.
+
+irdl.dialect @testd {
+  irdl.type @self_referencing {
+    %0 = irdl.any
+    %1 = irdl.parametric @testd::@self_referencing<%0>
+    irdl.parameters(foo: %1)
+  }
+}
+
+// expected-note@+1 {{see existing symbol definition here}}
+func.func @test() { return }
+// expected-error@+1 {{redefinition of symbol named 'test'}}
+func.func @test() { return }

@joker-eph joker-eph merged commit 6fa90a3 into llvm:main Mar 1, 2026
14 checks passed
@llvm-ci
Copy link
Copy Markdown

llvm-ci commented Mar 1, 2026

LLVM Buildbot has detected a new failure on builder sanitizer-aarch64-linux-bootstrap-asan running on sanitizer-buildbot8 while building mlir at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/24/builds/18047

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using ld.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 95442 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 
FAIL: LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s (58176 of 95442)
******************** TEST 'LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp && mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
# executed command: rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
# note: command had no output on stdout or stderr
# executed command: mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
# note: command had no output on stdout or stderr
# RUN: at line 2
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s
# executed command: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s
# note: command had no output on stdout or stderr
# RUN: at line 3
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# executed command: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# note: command had no output on stdout or stderr
# RUN: at line 4
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# executed command: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Slowest Tests:
--------------------------------------------------------------------------
160.24s: Clang :: Preprocessor/riscv-target-features.c
134.27s: Clang :: Driver/arm-cortex-cpus-1.c
131.96s: Clang :: Driver/arm-cortex-cpus-2.c
127.95s: Clang :: OpenMP/target_defaultmap_codegen_01.cpp
126.61s: Clang :: OpenMP/target_update_codegen.cpp
116.99s: LLVM :: CodeGen/RISCV/attributes.ll
116.58s: Clang :: Preprocessor/aarch64-target-features.c
Step 11 (stage2/asan check) failure: stage2/asan check (failure)
...
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using ld.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using lld-link: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/lld-link
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using ld64.lld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:561: note: using wasm-ld: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 95442 tests, 72 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 
FAIL: LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s (58176 of 95442)
******************** TEST 'LLVM :: ExecutionEngine/JITLink/x86-64/MachO_weak_references.s' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp && mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
# executed command: rm -rf /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
# note: command had no output on stdout or stderr
# executed command: mkdir -p /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp
# note: command had no output on stdout or stderr
# RUN: at line 2
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s
# executed command: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s
# note: command had no output on stdout or stderr
# RUN: at line 3
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# executed command: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-present -abs bar=0x1 -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# note: command had no output on stdout or stderr
# RUN: at line 4
/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# executed command: /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/bin/llvm-jitlink -noexec -check-name=jitlink-check-bar-absent -check=/home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_weak_references.s /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm_build_asan/test/ExecutionEngine/JITLink/x86-64/Output/MachO_weak_references.s.tmp/macho_weak_refs.o
# note: command had no output on stdout or stderr
# error: command failed with exit status: 1

--

********************
Testing:  0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. 
Slowest Tests:
--------------------------------------------------------------------------
160.24s: Clang :: Preprocessor/riscv-target-features.c
134.27s: Clang :: Driver/arm-cortex-cpus-1.c
131.96s: Clang :: Driver/arm-cortex-cpus-2.c
127.95s: Clang :: OpenMP/target_defaultmap_codegen_01.cpp
126.61s: Clang :: OpenMP/target_update_codegen.cpp
116.99s: LLVM :: CodeGen/RISCV/attributes.ll
116.58s: Clang :: Preprocessor/aarch64-target-features.c

sahas3 pushed a commit to sahas3/llvm-project that referenced this pull request Mar 4, 2026
… IR (llvm#183945)

The SymbolTable::SymbolTable constructor asserted that all symbol names
in the region were unique. This could cause mlir-opt to crash instead of
producing a proper diagnostic when the IR contained both:

1. An IsolatedFromAbove op (e.g., irdl.dialect) with a symbol user that
looks up symbols in an ancestor symbol table, and
2. Duplicate symbols in that ancestor (e.g., two func.func @test).

The crash occurred because IsolatedFromAbove ops are verified in
verifyOnExit() before verifyRegionInvariants() runs the SymbolTable
trait's verifyRegionTrait (which produces the proper duplicate-symbol
diagnostic). When the isolated op's symbol use verification triggered
SymbolTableCollection::getSymbolTable() on the ancestor, the constructor
would assert instead of gracefully handling the invalid-but-not-yet-
reported duplicate symbols.

The fix removes the assertion and silently skips duplicate symbol
insertions (keeping the first definition). The proper diagnostic is
still produced by the SymbolTable trait's verifyRegionTrait, which runs
after all children have been verified.

Add a regression test in invalid.irdl.mlir using a self-referencing IRDL
parametric type combined with duplicate function symbols.

Fixes llvm#159673
sujianIBM pushed a commit to sujianIBM/llvm-project that referenced this pull request Mar 5, 2026
… IR (llvm#183945)

The SymbolTable::SymbolTable constructor asserted that all symbol names
in the region were unique. This could cause mlir-opt to crash instead of
producing a proper diagnostic when the IR contained both:

1. An IsolatedFromAbove op (e.g., irdl.dialect) with a symbol user that
looks up symbols in an ancestor symbol table, and
2. Duplicate symbols in that ancestor (e.g., two func.func @test).

The crash occurred because IsolatedFromAbove ops are verified in
verifyOnExit() before verifyRegionInvariants() runs the SymbolTable
trait's verifyRegionTrait (which produces the proper duplicate-symbol
diagnostic). When the isolated op's symbol use verification triggered
SymbolTableCollection::getSymbolTable() on the ancestor, the constructor
would assert instead of gracefully handling the invalid-but-not-yet-
reported duplicate symbols.

The fix removes the assertion and silently skips duplicate symbol
insertions (keeping the first definition). The proper diagnostic is
still produced by the SymbolTable trait's verifyRegionTrait, which runs
after all children have been verified.

Add a regression test in invalid.irdl.mlir using a self-referencing IRDL
parametric type combined with duplicate function symbols.

Fixes llvm#159673
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mlir:core MLIR Core Infrastructure mlir:irdl mlir

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MLIR][IRDL] Assertion crash with self-referencing IRDL types and duplicate function symbols

4 participants