aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineBlockPlacement.cpp
diff options
context:
space:
mode:
authorAfanasyev Ivan <ivafanas@gmail.com>2025-06-23 21:04:22 +0700
committerGitHub <noreply@github.com>2025-06-23 23:04:22 +0900
commitd0e5d6fd6180b0f294a00cf48996219df97c9e78 (patch)
treee190d785b9133d3a0aceb44580baeedc05ddc90c /llvm/lib/CodeGen/MachineBlockPlacement.cpp
parentcd91d0fff9293a904704784c92c28637bfebef45 (diff)
downloadllvm-d0e5d6fd6180b0f294a00cf48996219df97c9e78.zip
llvm-d0e5d6fd6180b0f294a00cf48996219df97c9e78.tar.gz
llvm-d0e5d6fd6180b0f294a00cf48996219df97c9e78.tar.bz2
[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.
Diffstat (limited to 'llvm/lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineBlockPlacement.cpp15
1 files changed, 5 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index 2dbabfe..e9c75f0 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