Skip to content

Conversation

@nataliakokoromyti
Copy link
Contributor

The RemoveDeadValues pass was using cast which asserts that the terminator implements this interface. However, some dialects (like CIR) have region terminators that don't implement this interface, causing crashes.

This patch changes cast to dyn_cast and skips processing for terminators that don't implement RegionBranchTerminatorOpInterface.

Fixes #174502

…chTerminatorOpInterface

The RemoveDeadValues pass was using cast<RegionBranchTerminatorOpInterface>
which asserts that the terminator implements this interface. However, some
dialects (like CIR) have region terminators that don't implement this
interface, causing crashes.

This patch changes cast to dyn_cast and skips processing for terminators
that don't implement RegionBranchTerminatorOpInterface.

Fixes llvm#174502
@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir labels Jan 10, 2026
@llvmbot
Copy link
Member

llvmbot commented Jan 10, 2026

@llvm/pr-subscribers-mlir-core

Author: None (nataliakokoromyti)

Changes

The RemoveDeadValues pass was using cast<RegionBranchTerminatorOpInterface> which asserts that the terminator implements this interface. However, some dialects (like CIR) have region terminators that don't implement this interface, causing crashes.

This patch changes cast to dyn_cast and skips processing for terminators that don't implement RegionBranchTerminatorOpInterface.

Fixes #174502


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

1 Files Affected:

  • (modified) mlir/lib/Transforms/RemoveDeadValues.cpp (+16-6)
diff --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp
index fc2c2acf8afd3..4d20abb415229 100644
--- a/mlir/lib/Transforms/RemoveDeadValues.cpp
+++ b/mlir/lib/Transforms/RemoveDeadValues.cpp
@@ -477,8 +477,10 @@ static void processRegionBranchOp(RegionBranchOpInterface regionBranchOp,
           if (region.empty())
             continue;
           // TODO: this isn't correct in face of multiple terminators.
-          auto terminator = cast<RegionBranchTerminatorOpInterface>(
+          auto terminator = dyn_cast<RegionBranchTerminatorOpInterface>(
               region.front().getTerminator());
+          if (!terminator)
+            continue;
           nonForwardedRets[terminator] =
               BitVector(terminator->getNumOperands(), true);
           for (const RegionSuccessor &successor : getSuccessors(terminator)) {
@@ -498,11 +500,17 @@ static void processRegionBranchOp(RegionBranchOpInterface regionBranchOp,
           DenseMap<Region *, BitVector> &argsToKeep, Region *region = nullptr) {
         Operation *terminator =
             region ? region->front().getTerminator() : nullptr;
-        RegionBranchPoint point =
+        auto terminatorIface =
             terminator
-                ? RegionBranchPoint(
-                      cast<RegionBranchTerminatorOpInterface>(terminator))
-                : RegionBranchPoint::parent();
+                ? dyn_cast<RegionBranchTerminatorOpInterface>(terminator)
+                : nullptr;
+        // If terminator doesn't implement RegionBranchTerminatorOpInterface,
+        // we can't analyze it, so skip.
+        if (terminator && !terminatorIface)
+          return;
+        RegionBranchPoint point =
+            terminatorIface ? RegionBranchPoint(terminatorIface)
+                            : RegionBranchPoint::parent();
 
         for (const RegionSuccessor &successor : getSuccessors(point)) {
           Region *successorRegion = successor.getSuccessor();
@@ -566,8 +574,10 @@ static void processRegionBranchOp(RegionBranchOpInterface regionBranchOp,
         for (Region &region : regionBranchOp->getRegions()) {
           if (region.empty())
             continue;
-          auto terminator = cast<RegionBranchTerminatorOpInterface>(
+          auto terminator = dyn_cast<RegionBranchTerminatorOpInterface>(
               region.front().getTerminator());
+          if (!terminator)
+            continue;
           for (const RegionSuccessor &successor : getSuccessors(terminator)) {
             Region *successorRegion = successor.getSuccessor();
             for (auto [opOperand, input] :

@llvmbot
Copy link
Member

llvmbot commented Jan 10, 2026

@llvm/pr-subscribers-mlir

Author: None (nataliakokoromyti)

Changes

The RemoveDeadValues pass was using cast<RegionBranchTerminatorOpInterface> which asserts that the terminator implements this interface. However, some dialects (like CIR) have region terminators that don't implement this interface, causing crashes.

This patch changes cast to dyn_cast and skips processing for terminators that don't implement RegionBranchTerminatorOpInterface.

Fixes #174502


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

1 Files Affected:

  • (modified) mlir/lib/Transforms/RemoveDeadValues.cpp (+16-6)
diff --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp
index fc2c2acf8afd3..4d20abb415229 100644
--- a/mlir/lib/Transforms/RemoveDeadValues.cpp
+++ b/mlir/lib/Transforms/RemoveDeadValues.cpp
@@ -477,8 +477,10 @@ static void processRegionBranchOp(RegionBranchOpInterface regionBranchOp,
           if (region.empty())
             continue;
           // TODO: this isn't correct in face of multiple terminators.
-          auto terminator = cast<RegionBranchTerminatorOpInterface>(
+          auto terminator = dyn_cast<RegionBranchTerminatorOpInterface>(
               region.front().getTerminator());
+          if (!terminator)
+            continue;
           nonForwardedRets[terminator] =
               BitVector(terminator->getNumOperands(), true);
           for (const RegionSuccessor &successor : getSuccessors(terminator)) {
@@ -498,11 +500,17 @@ static void processRegionBranchOp(RegionBranchOpInterface regionBranchOp,
           DenseMap<Region *, BitVector> &argsToKeep, Region *region = nullptr) {
         Operation *terminator =
             region ? region->front().getTerminator() : nullptr;
-        RegionBranchPoint point =
+        auto terminatorIface =
             terminator
-                ? RegionBranchPoint(
-                      cast<RegionBranchTerminatorOpInterface>(terminator))
-                : RegionBranchPoint::parent();
+                ? dyn_cast<RegionBranchTerminatorOpInterface>(terminator)
+                : nullptr;
+        // If terminator doesn't implement RegionBranchTerminatorOpInterface,
+        // we can't analyze it, so skip.
+        if (terminator && !terminatorIface)
+          return;
+        RegionBranchPoint point =
+            terminatorIface ? RegionBranchPoint(terminatorIface)
+                            : RegionBranchPoint::parent();
 
         for (const RegionSuccessor &successor : getSuccessors(point)) {
           Region *successorRegion = successor.getSuccessor();
@@ -566,8 +574,10 @@ static void processRegionBranchOp(RegionBranchOpInterface regionBranchOp,
         for (Region &region : regionBranchOp->getRegions()) {
           if (region.empty())
             continue;
-          auto terminator = cast<RegionBranchTerminatorOpInterface>(
+          auto terminator = dyn_cast<RegionBranchTerminatorOpInterface>(
               region.front().getTerminator());
+          if (!terminator)
+            continue;
           for (const RegionSuccessor &successor : getSuccessors(terminator)) {
             Region *successorRegion = successor.getSuccessor();
             for (auto [opOperand, input] :

@matthias-springer
Copy link
Member

Can you rebase to main? This crash may have been fixed by #173505. The code that this PR is modifying doesn't exist anymore.

You may also be interested in #174978: the MLIR code base assumes that region branch terminators implement the RegionBranchTerminatorOpInterface.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MLIR] DCE crashes on CIR

3 participants