[llvm] [SimplifyCFG] Don't delete basic block if it is a partial cleanuppad (PR #157363)

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 8 13:53:21 PDT 2025


================
@@ -8340,8 +8340,9 @@ bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
 
   // Remove basic blocks that have no predecessors (except the entry block)...
   // or that just have themself as a predecessor.  These are unreachable.
-  if ((pred_empty(BB) && BB != &BB->getParent()->getEntryBlock()) ||
-      BB->getSinglePredecessor() == BB) {
+  if (((pred_empty(BB) && BB != &BB->getParent()->getEntryBlock()) ||
+       BB->getSinglePredecessor() == BB) &&
+      (!BB->isEHPad() || BB->isEHPadWithReturn())) {
----------------
efriedma-quic wrote:

We should handle `catchpad`/`catchret` the same way as `cleanuppad`/`cleaupret`.

`landingpad`/`resume` doesn't have the same constraints; you can pass an arbitrary pointer to `resume`.  So we shouldn't need to handle `landingpad` here.

----

An alternative approach here would be to find all the `cleanupret` instructions which use the `cleanuppad` we're erasing, and replace them with `unreachable`.  (The basic blocks containing those cleanuppads must be dead because the `cleanuppad` dominates the `cleanupret`.)  The advantage of this is mostly that you can fix the DeleteDeadBlock API, not just the one use of that API you're currently looking at.

In any case, removeUnreachableBlocks will eventually clean up all the dead blocks, so it's not that important what we do here as long as it doesn't crash.

https://github.com/llvm/llvm-project/pull/157363


More information about the llvm-commits mailing list