[llvm] d0e5d6f - [CodeGen][CodeLayout] Fix segfault on access to deleted block in MBP. (#142357)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 23 07:04:25 PDT 2025


Author: Afanasyev Ivan
Date: 2025-06-23T23:04:22+09:00
New Revision: d0e5d6fd6180b0f294a00cf48996219df97c9e78

URL: https://github.com/llvm/llvm-project/commit/d0e5d6fd6180b0f294a00cf48996219df97c9e78
DIFF: https://github.com/llvm/llvm-project/commit/d0e5d6fd6180b0f294a00cf48996219df97c9e78.diff

LOG: [CodeGen][CodeLayout] Fix segfault on access to deleted block in MBP. (#142357)

Problem 1: There is a typo which reassigns `BlockWorkList` to
`EHPadWorkList` on attempt to remove `RemBB` from work lists.

Problem 2: `Chain->UnscheduledPredecessors == 0` is an incorrect way to
check whether `RemBB` is enqueued or not. The root cause is a postponed
deletion of `WorkList` from already scheduled blocks in
`selectBestCandidateBlock`. Bug happens in the following scenario:

* `FunctionChain` is being processed with non-zero
`UnscheduledPredecessors`
* Block `B'` is added to the `BlockWorkList`
* Block `B'` is chosen as the best successor (`selectBestSuccessor`) for
some another block and added into `Chain`
* Block `B'` is removed by tail duplicator.

`RemovalCallback` erroneously won't erase `B'` from `BlockWorkList`,
because `UnscheduledPredecessors` value of `FunctionChain` is not zero
(and it is allowed to be non-zero).

Proposed solution is to always cleanup worklists on block deletion by
tail duplicator.

Added: 
    

Modified: 
    llvm/lib/CodeGen/MachineBlockPlacement.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index 2dbabfe345d5e..e9c75f0753f89 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -3228,13 +3228,9 @@ bool MachineBlockPlacement::maybeTailDuplicateBlock(
     // Signal to outer function
     Removed = true;
 
-    // Conservative default.
-    bool InWorkList = true;
     // Remove from the Chain and Chain Map
     if (auto It = BlockToChain.find(RemBB); It != BlockToChain.end()) {
-      BlockChain *Chain = It->second;
-      InWorkList = Chain->UnscheduledPredecessors == 0;
-      Chain->remove(RemBB);
+      It->second->remove(RemBB);
       BlockToChain.erase(It);
     }
 
@@ -3244,11 +3240,10 @@ bool MachineBlockPlacement::maybeTailDuplicateBlock(
     }
 
     // Handle the Work Lists
-    if (InWorkList) {
-      SmallVectorImpl<MachineBasicBlock *> &RemoveList = BlockWorkList;
-      if (RemBB->isEHPad())
-        RemoveList = EHPadWorkList;
-      llvm::erase(RemoveList, RemBB);
+    if (RemBB->isEHPad()) {
+      llvm::erase(EHPadWorkList, RemBB);
+    } else {
+      llvm::erase(BlockWorkList, RemBB);
     }
 
     // Handle the filter set


        


More information about the llvm-commits mailing list