diff options
author | Afanasyev Ivan <ivafanas@gmail.com> | 2025-06-23 21:04:22 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-23 23:04:22 +0900 |
commit | d0e5d6fd6180b0f294a00cf48996219df97c9e78 (patch) | |
tree | e190d785b9133d3a0aceb44580baeedc05ddc90c /llvm/lib/CodeGen/MachineBlockPlacement.cpp | |
parent | cd91d0fff9293a904704784c92c28637bfebef45 (diff) | |
download | llvm-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.cpp | 15 |
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 |