[llvm] [InstCombine] Treat identical operands as one in pushFreezeToPreventPoisonFromPropagating (PR #145348)

Cullen Rhodes via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 23 08:56:45 PDT 2025


https://github.com/c-rhodes created https://github.com/llvm/llvm-project/pull/145348

To push a freeze through an instruction, only one operand may produce
poison. However, this currently fails for identical operands which are
treated as separate. This patch fixes this by treating them as a single
operand.

Thanks to @david-arm for help with this.

>From e325b415636391e9340a86f1fc1607d31842c6ad Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Mon, 23 Jun 2025 14:30:29 +0000
Subject: [PATCH 1/2] [InstCombine] Precommit test

---
 llvm/test/Transforms/InstCombine/freeze.ll | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 8875ce1c566f3..c9f54a4f4d181 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -142,6 +142,17 @@ define i32 @early_freeze_test3(i32 %v1) {
   ret i32 %v4.fr
 }
 
+define i32 @early_freeze_test4(i32 %v1) {
+; CHECK-LABEL: @early_freeze_test4(
+; CHECK-NEXT:    [[V2:%.*]] = mul i32 [[V1_FR:%.*]], [[V1_FR]]
+; CHECK-NEXT:    [[V2_FR:%.*]] = freeze i32 [[V2]]
+; CHECK-NEXT:    ret i32 [[V2_FR]]
+;
+  %v2 = mul i32 %v1, %v1
+  %v2.fr = freeze i32 %v2
+  ret i32 %v2.fr
+}
+
 ; If replace all dominated uses of v to freeze(v).
 
 define void @freeze_dominated_uses_test1(i32 %v) {

>From 110cb6e48f766d4795e8131402166a73deb3ae5f Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Mon, 23 Jun 2025 14:34:18 +0000
Subject: [PATCH 2/2] [InstCombine] Treat identical operands as one in
 pushFreezeToPreventPoisonFromPropagating

To push a freeze through an instruction, only one operand may produce
poison. However, this currently fails for identical operands which are
treated as separate. This patch fixes this by treating them as a single
operand.
---
 llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 4 +++-
 llvm/test/Transforms/InstCombine/freeze.ll               | 6 +++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index ce42029261359..e33cf699395f0 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4774,7 +4774,9 @@ InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
   Use *MaybePoisonOperand = nullptr;
   for (Use &U : OrigOpInst->operands()) {
     if (isa<MetadataAsValue>(U.get()) ||
-        isGuaranteedNotToBeUndefOrPoison(U.get()))
+        isGuaranteedNotToBeUndefOrPoison(U.get()) ||
+        // Treat identical operands as a single operand.
+        (MaybePoisonOperand && MaybePoisonOperand->get() == U.get()))
       continue;
     if (!MaybePoisonOperand)
       MaybePoisonOperand = &U;
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index c9f54a4f4d181..abe7117b27f8c 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -144,9 +144,9 @@ define i32 @early_freeze_test3(i32 %v1) {
 
 define i32 @early_freeze_test4(i32 %v1) {
 ; CHECK-LABEL: @early_freeze_test4(
-; CHECK-NEXT:    [[V2:%.*]] = mul i32 [[V1_FR:%.*]], [[V1_FR]]
-; CHECK-NEXT:    [[V2_FR:%.*]] = freeze i32 [[V2]]
-; CHECK-NEXT:    ret i32 [[V2_FR]]
+; CHECK-NEXT:    [[V2_FR:%.*]] = freeze i32 [[V2:%.*]]
+; CHECK-NEXT:    [[V3:%.*]] = mul i32 [[V2_FR]], [[V2_FR]]
+; CHECK-NEXT:    ret i32 [[V3]]
 ;
   %v2 = mul i32 %v1, %v1
   %v2.fr = freeze i32 %v2



More information about the llvm-commits mailing list