[llvm] [InstCombine] Allow freezing multiple out-of-loop values (PR #155638)
Cullen Rhodes via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 08:27:31 PDT 2025
https://github.com/c-rhodes created https://github.com/llvm/llvm-project/pull/155638
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.
>From f330a2889f2b82bb2d1e267a86c820da8537dbca Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Wed, 27 Aug 2025 10:46:37 +0000
Subject: [PATCH] [InstCombine] Allow freezing multiple out-of-loop values
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.
---
.../InstCombine/InstructionCombining.cpp | 30 +++++++++----------
llvm/test/Transforms/InstCombine/freeze.ll | 7 +++--
2 files changed, 18 insertions(+), 19 deletions(-)
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]]:
More information about the llvm-commits
mailing list