[llvm] [InstCombine] Allow freezing multiple out-of-loop values (PR #155638)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 08:28:06 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Cullen Rhodes (c-rhodes)
<details>
<summary>Changes</summary>
Extend foldFreezeIntoRecurrence to allow freezing multiple out-of-loop values. This is following on from #<!-- -->154336, which recently made the same change for a wider set of ops.
---
Full diff: https://github.com/llvm/llvm-project/pull/155638.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+14-16)
- (modified) llvm/test/Transforms/InstCombine/freeze.ll (+4-3)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 1c512ec1e21bb..e524839e2876e 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -5032,32 +5032,28 @@ Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI,
// backedge values (possibly dropping poison flags along the way) until we
// reach the phi again. In that case, we can move the freeze to the start
// value.
- Use *StartU = nullptr;
+ SmallVector<Use *> StartUses;
SmallVector<Value *> Worklist;
for (Use &U : PN->incoming_values()) {
- if (DT.dominates(PN->getParent(), PN->getIncomingBlock(U))) {
+ BasicBlock *StartBB = PN->getIncomingBlock(U);
+ Value *StartV = U.get();
+ if (DT.dominates(PN->getParent(), StartBB)) {
// Add backedge value to worklist.
- Worklist.push_back(U.get());
+ Worklist.push_back(StartV);
continue;
}
- // Don't bother handling multiple start values.
- if (StartU)
+ bool StartNeedsFreeze = !isGuaranteedNotToBeUndefOrPoison(StartV);
+ // We can't insert freeze if a start value is the result of the
+ // terminator (e.g. an invoke).
+ if (StartNeedsFreeze && StartBB->getTerminator() == StartV)
return nullptr;
- StartU = &U;
+ StartUses.push_back(&U);
}
- if (!StartU || Worklist.empty())
+ if (StartUses.empty() || Worklist.empty())
return nullptr; // Not a recurrence.
- Value *StartV = StartU->get();
- BasicBlock *StartBB = PN->getIncomingBlock(*StartU);
- bool StartNeedsFreeze = !isGuaranteedNotToBeUndefOrPoison(StartV);
- // We can't insert freeze if the start value is the result of the
- // terminator (e.g. an invoke).
- if (StartNeedsFreeze && StartBB->getTerminator() == StartV)
- return nullptr;
-
SmallPtrSet<Value *, 32> Visited;
SmallVector<Instruction *> DropFlags;
while (!Worklist.empty()) {
@@ -5084,7 +5080,9 @@ Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI,
for (Instruction *I : DropFlags)
I->dropPoisonGeneratingAnnotations();
- if (StartNeedsFreeze) {
+ for (Use *StartU : StartUses) {
+ Value *StartV = StartU->get();
+ BasicBlock *StartBB = PN->getIncomingBlock(*StartU);
Builder.SetInsertPoint(StartBB->getTerminator());
Value *FrozenStartV = Builder.CreateFreeze(StartV,
StartV->getName() + ".fr");
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index b29421a655fa8..09fb2dc19912c 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -1106,13 +1106,14 @@ define void @fold_phi_multiple_start_values(i1 %c, i32 %init, i32 %init2, i32 %n
; CHECK-LABEL: define void @fold_phi_multiple_start_values(
; CHECK-SAME: i1 [[C:%.*]], i32 [[INIT:%.*]], i32 [[INIT2:%.*]], i32 [[N:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[INIT_FR:%.*]] = freeze i32 [[INIT]]
; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[LOOP:.*]]
; CHECK: [[IF]]:
+; CHECK-NEXT: [[INIT2_FR:%.*]] = freeze i32 [[INIT2]]
; CHECK-NEXT: br label %[[LOOP]]
; CHECK: [[LOOP]]:
-; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT]], %[[ENTRY]] ], [ [[INIT2]], %[[IF]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
-; CHECK-NEXT: [[I_FR:%.*]] = freeze i32 [[I]]
-; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I_FR]], 1
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FR]], %[[ENTRY]] ], [ [[INIT2_FR]], %[[IF]] ], [ [[I_NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]
; CHECK-NEXT: br i1 [[COND]], label %[[LOOP]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
``````````
</details>
https://github.com/llvm/llvm-project/pull/155638
More information about the llvm-commits
mailing list