[BOLT] removeAllSuccessors: handle multiple edges between basic blocks
Summary: If `addUnknownControlFlow` in `BinaryFunction::postProcessIndirectBranches` is invoked with a basic block that has multiple edges to the same successor, it leads to an assertion in `BinaryBasicBlock::removePredecessor`. For basic blocks with multiple edges to the same successor, the default behavior of removePredecessor is to remove all occurrences of the predecessor block in its predecessor list (Multiple=true). Example: ```A -> B (two edges) A->removeAllSuccessors() for each successor of block A: // B twice // this removes both occurrences of A in B's predecessors list B->removePredecessor(A); // this invocation triggers an assert as A is no longer in B's // predecessor list B->removePredecessor(A); ``` This issue is not fixed by NormalizeCFG as `removeAllSuccessor` is called earlier (from `buildCFG` -> `postProcessIndirectBranches`). Solve this issue by collecting the successors into a set (`SmallPtrSet`) first, before invoking `SuccessorBB->removePredecessor(this)`. GitHub issue: https://github.com/facebookincubator/BOLT/issues/187 (cherry picked from FBD30796979)
Loading
Please sign in to comment