[llvm] [InstCombine] Push freeze through non-recurrence PHIs (PR #157678)
Cullen Rhodes via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 23 07:12:56 PDT 2025
================
@@ -5042,10 +5042,33 @@ InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
// Op1.fr = Freeze(Op1)
// ... = Inst(Op1.fr, NonPoisonOps...)
- auto CanPushFreeze = [](Value *V) {
- if (!isa<Instruction>(V) || isa<PHINode>(V))
+ auto CanPushFreeze = [this](Value *V) {
+ if (!isa<Instruction>(V))
return false;
+ if (auto *PN = dyn_cast<PHINode>(V)) {
+ BasicBlock *BB = PN->getParent();
+ SmallPtrSet<BasicBlock *, 8> VisitedBBs;
+ for (Use &U : PN->incoming_values()) {
+ BasicBlock *InBB = PN->getIncomingBlock(U);
+ // We can't move freeze if the start value is the result of a
+ // terminator (e.g. an invoke).
+ if (auto *OpI = dyn_cast<Instruction>(U)) {
+ if (OpI->isTerminator())
+ return false;
+ }
+
+ // If there's multiple incoming edges from the same predecessor we must
+ // ensure the freeze isn't pushed to a single one of the uses,
+ // invalidating the iterator. We simply don't support this case, but it
+ // could be handled if there's a use case.
+ if (isBackEdge(InBB, BB) || !VisitedBBs.insert(InBB).second ||
+ match(U.get(), m_Undef()))
----------------
c-rhodes wrote:
without this check freeze is pushed to `%x` in this test: https://github.com/llvm/llvm-project/blob/8f905c3e6f022ec6255d1e537eedcdbc029bf99d/llvm/test/Transforms/InstCombine/freeze-phi.ll#L116, which I don't think is right
https://github.com/llvm/llvm-project/pull/157678
More information about the llvm-commits
mailing list