[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