[llvm] [InstCombine] Reuse existing freeze when pushing freeze through a binop (PR #202306)

Yuyang Zhang via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 12 00:08:38 PDT 2026


https://github.com/yuyzhang512 updated https://github.com/llvm/llvm-project/pull/202306

>From b9a2cfe325d49dab63173e9b746a704a0238cb4f Mon Sep 17 00:00:00 2001
From: yuyzhang512 <yuyzhang at amd.com>
Date: Fri, 12 Jun 2026 07:05:53 +0000
Subject: [PATCH] [InstCombine] Re-queue users after freezeOtherUses rewrites
 their operands

freezeOtherUses replaces dominated uses of a value with a frozen copy in
place, but never re-queued the affected users. A fold exposed on a user by
that rewrite (e.g. a freeze of the user that can now be pushed through it)
only fired on a later iteration, tripping the InstCombine fixpoint verifier.

Re-queue each modified user and its users, mirroring the run loop's handling
of an in-place modification, so the rewrite converges in a single iteration.
---
 .../InstCombine/InstructionCombining.cpp      |  7 +++++++
 llvm/test/Transforms/InstCombine/freeze.ll    | 20 +++++++++++++++++++
 llvm/test/Transforms/InstCombine/shift.ll     |  2 +-
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 89bf4bf713421..76c97514d0149 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -5392,6 +5392,13 @@ bool InstCombinerImpl::freezeOtherUses(FreezeInst &FI) {
   });
 
   for (auto *U : Users) {
+    // Re-queue U and its users: freezing U's operand can expose a fold on a
+    // user of U (e.g. a freeze of U can now be pushed through it) that would
+    // otherwise only fire on a later iteration, tripping the fixpoint verifier.
+    auto *UI = cast<Instruction>(U);
+    Worklist.pushUsersToWorkList(*UI);
+    Worklist.push(UI);
+
     for (auto &AssumeVH : AC.assumptionsFor(U)) {
       if (!AssumeVH)
         continue;
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 3a401acb6d3ee..7a542dc5cb67a 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -1733,6 +1733,26 @@ define float @freeze_fabs_nofpclass(float %a) {
   ret float %x.fr
 }
 
+; freezeOtherUses rewrites %m's operand to the existing freeze %fb; the freeze
+; of the user %p must then be pushed through within the same iteration.
+define i1 @freeze_other_uses_requeues_user(i32 %a, i32 %b) {
+; CHECK-LABEL: define i1 @freeze_other_uses_requeues_user(
+; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:    [[FB:%.*]] = freeze i32 [[B]]
+; CHECK-NEXT:    [[A_FR:%.*]] = freeze i32 [[A]]
+; CHECK-NEXT:    [[M:%.*]] = mul i32 [[A_FR]], [[FB]]
+; CHECK-NEXT:    [[P:%.*]] = mul i32 [[M]], [[FB]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[P]], 0
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %m  = mul i32 %a, %b
+  %fm = freeze i32 %m
+  %fb = freeze i32 %b
+  %p  = mul i32 %fm, %fb
+  %r  = icmp eq i32 %p, 0
+  ret i1 %r
+}
+
 !0 = !{}
 !1 = !{i64 4}
 !2 = !{i32 0, i32 100}
diff --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll
index 3a9e756bafc36..61e3e000758f8 100644
--- a/llvm/test/Transforms/InstCombine/shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift.ll
@@ -1747,7 +1747,7 @@ define void @ashr_out_of_range(ptr %A) "instcombine-no-verify-fixpoint" {
 ; CHECK-NEXT:    [[L7:%.*]] = load i177, ptr [[G11]], align 4
 ; CHECK-NEXT:    [[L7_FROZEN:%.*]] = freeze i177 [[L7]]
 ; CHECK-NEXT:    [[C171:%.*]] = icmp slt i177 [[L7_FROZEN]], 0
-; CHECK-NEXT:    [[C17:%.*]] = select i1 [[TMP1]], i1 [[C171]], i1 false
+; CHECK-NEXT:    [[C17:%.*]] = and i1 [[TMP1]], [[C171]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = sext i1 [[C17]] to i64
 ; CHECK-NEXT:    [[G62:%.*]] = getelementptr [24 x i8], ptr [[G11]], i64 [[TMP3]]
 ; CHECK-NEXT:    [[TMP4:%.*]] = icmp eq i177 [[L7_FROZEN]], -1



More information about the llvm-commits mailing list