aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorKunqiu Chen <camsyn@foxmail.com>2025-10-30 02:45:27 +0800
committerGitHub <noreply@github.com>2025-10-30 02:45:27 +0800
commitb2fe5d1482ebab36d75922c41e73b64ab157c98b (patch)
treea7f4a99420bbbd64cff9788d7a49c46ae285ce87 /llvm/lib/Transforms
parent7b98280b6b7cb89b141a5874ff9ee3ce72dab92a (diff)
downloadllvm-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.cpp15
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;