[Mlir-commits] [mlir] [mlir][IR] Fix `Block::without_terminator` for blocks without terminator (PR #154498)

Matthias Springer llvmlistbot at llvm.org
Wed Aug 20 05:20:24 PDT 2025


https://github.com/matthias-springer updated https://github.com/llvm/llvm-project/pull/154498

>From e301ac75434ee4beb660ed92ddc25fd9b058c142 Mon Sep 17 00:00:00 2001
From: Matthias Springer <me at m-sp.org>
Date: Wed, 20 Aug 2025 09:40:16 +0000
Subject: [PATCH] [mlir][IR] Fix `Block::without_terminator` for `NoTerminator`
 blocks

---
 mlir/include/mlir/IR/Block.h               | 15 +++++++++++++--
 mlir/lib/Analysis/TopologicalSortUtils.cpp |  5 +----
 mlir/lib/IR/Block.cpp                      |  5 +++++
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/mlir/include/mlir/IR/Block.h b/mlir/include/mlir/IR/Block.h
index e486bb627474d..d8cdb6feacb35 100644
--- a/mlir/include/mlir/IR/Block.h
+++ b/mlir/include/mlir/IR/Block.h
@@ -205,10 +205,15 @@ class alignas(8) Block : public IRObjectWithUseList<BlockOperand>,
   }
 
   /// Return an iterator range over the operation within this block excluding
-  /// the terminator operation at the end.
+  /// the terminator operation at the end. If the block has no terminator,
+  /// return an iterator range over the entire block. If it is unknown if the
+  /// block has a terminator (i.e., last block operation is unregistered), also
+  /// return an iterator range over the entire block.
   iterator_range<iterator> without_terminator() {
     if (begin() == end())
       return {begin(), end()};
+    if (!hasTerminator())
+      return {begin(), end()};
     auto endIt = --end();
     return {begin(), endIt};
   }
@@ -221,9 +226,15 @@ class alignas(8) Block : public IRObjectWithUseList<BlockOperand>,
   /// the block might have a valid terminator operation.
   Operation *getTerminator();
 
-  /// Check whether this block might have a terminator.
+  /// Return "true" if this block might have a terminator. Return "true" if
+  /// the last operation is unregistered.
   bool mightHaveTerminator();
 
+  /// Return "true" if this block has a terminator. Return "false" if the last
+  /// operation is unregistered. In that case, the presence of a terminator
+  /// cannot be determined.
+  bool hasTerminator();
+
   //===--------------------------------------------------------------------===//
   // Predecessors and successors.
   //===--------------------------------------------------------------------===//
diff --git a/mlir/lib/Analysis/TopologicalSortUtils.cpp b/mlir/lib/Analysis/TopologicalSortUtils.cpp
index a2fd14910892a..dc71e6a6daa4b 100644
--- a/mlir/lib/Analysis/TopologicalSortUtils.cpp
+++ b/mlir/lib/Analysis/TopologicalSortUtils.cpp
@@ -103,10 +103,7 @@ bool mlir::sortTopologically(
     Block *block, function_ref<bool(Value, Operation *)> isOperandReady) {
   if (block->empty())
     return true;
-  if (block->back().hasTrait<OpTrait::IsTerminator>())
-    return sortTopologically(block, block->without_terminator(),
-                             isOperandReady);
-  return sortTopologically(block, *block, isOperandReady);
+  return sortTopologically(block, block->without_terminator(), isOperandReady);
 }
 
 bool mlir::computeTopologicalSorting(
diff --git a/mlir/lib/IR/Block.cpp b/mlir/lib/IR/Block.cpp
index 57825d9b42178..cfda33e1b55c9 100644
--- a/mlir/lib/IR/Block.cpp
+++ b/mlir/lib/IR/Block.cpp
@@ -251,6 +251,11 @@ bool Block::mightHaveTerminator() {
   return !empty() && back().mightHaveTrait<OpTrait::IsTerminator>();
 }
 
+/// Check whether this block has a terminator.
+bool Block::hasTerminator() {
+  return !empty() && back().hasTrait<OpTrait::IsTerminator>();
+}
+
 // Indexed successor access.
 unsigned Block::getNumSuccessors() {
   return empty() ? 0 : back().getNumSuccessors();



More information about the Mlir-commits mailing list