diff options
| author | Kunqiu Chen <camsyn@foxmail.com> | 2025-10-30 02:45:27 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-30 02:45:27 +0800 |
| commit | b2fe5d1482ebab36d75922c41e73b64ab157c98b (patch) | |
| tree | a7f4a99420bbbd64cff9788d7a49c46ae285ce87 /llvm/lib/Transforms | |
| parent | 7b98280b6b7cb89b141a5874ff9ee3ce72dab92a (diff) | |
| download | llvm-b2fe5d1482ebab36d75922c41e73b64ab157c98b.zip llvm-b2fe5d1482ebab36d75922c41e73b64ab157c98b.tar.gz llvm-b2fe5d1482ebab36d75922c41e73b64ab157c98b.tar.bz2 | |
[SimplifyCFG] Hoist common code when succ is unreachable block (#165570)
Previously, `hoistCommonCodeFromSuccessors` returned early if one of the
succ of BB has >1 predecessors.
However, if the succ is an unreachable BB, we can relax the condition to
perform `hoistCommonCodeFromSuccessors` based on the assumption of not
reaching UB.
See discussion https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2989
for details.
Alive2 proof: https://alive2.llvm.org/ce/z/OJOw0s
Promising optimization impact:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2995
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 90423d3..b03fb62 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1866,10 +1866,19 @@ bool SimplifyCFGOpt::hoistCommonCodeFromSuccessors(Instruction *TI, // If either of the blocks has it's address taken, then we can't do this fold, // because the code we'd hoist would no longer run when we jump into the block // by it's address. - for (auto *Succ : successors(BB)) - if (Succ->hasAddressTaken() || !Succ->getSinglePredecessor()) + for (auto *Succ : successors(BB)) { + if (Succ->hasAddressTaken()) return false; - + if (Succ->getSinglePredecessor()) + continue; + // If Succ has >1 predecessors, continue to check if the Succ contains only + // one `unreachable` inst. Since executing `unreachable` inst is an UB, we + // can relax the condition based on the assumptiom that the program would + // never enter Succ and trigger such an UB. + if (isa<UnreachableInst>(*Succ->begin())) + continue; + return false; + } // The second of pair is a SkipFlags bitmask. using SuccIterPair = std::pair<BasicBlock::iterator, unsigned>; SmallVector<SuccIterPair, 8> SuccIterPairs; |
