[llvm] [InstCombine] Fold `fcmp (fmul X, C1), C2` to `fcmp X, C2/C1` (PR #205003)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 2 08:11:58 PDT 2026


https://github.com/VachanVY updated https://github.com/llvm/llvm-project/pull/205003

>From b9574a355f1e3cbbad2d78e63ddd6234e9773aa8 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 21 Jun 2026 19:16:37 +0530
Subject: [PATCH 01/10] [InstCombine] Draft Implementation

fcmp (fmul X, C1), C2 --> fcmp X, C2/C1

fixes #153991
---
 .../InstCombine/InstCombineCompares.cpp       | 56 +++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 97e1a6555eac4..ac6861ada7822 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8840,6 +8840,58 @@ static Instruction *foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI,
   return nullptr;
 }
 
+/// Fold: fcmp (fmul X, C1), C2 --> fcmp X, C2/C1
+static Instruction *foldFCmpFmulIntoFCmp(FCmpInst &I, Instruction *LHSI,
+                                         Constant *RHSC) {
+  const CmpInst::Predicate Pred = I.getPredicate();
+  Value *X = LHSI->getOperand(0);
+  Value *Y = LHSI->getOperand(1);
+
+  ConstantFP *C1;
+  if (!match(Y, m_ConstantFP(C1)) || match(C1, m_AnyZeroFP()))
+    return nullptr;
+
+  CmpInst::Predicate NewPred;
+  bool C1IsNegative = C1->isNegative();
+  switch (Pred) {
+  default:
+    return nullptr;
+  case FCmpInst::FCMP_UEQ:
+  case FCmpInst::FCMP_UNE:
+  case FCmpInst::FCMP_OEQ:
+  case FCmpInst::FCMP_ONE:
+    NewPred = Pred;
+    break;
+  case FCmpInst::FCMP_OGE:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_OLE : FCmpInst::FCMP_OGE;
+    break;
+  case FCmpInst::FCMP_OGT:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_OLT : FCmpInst::FCMP_OGT;
+    break;
+  case FCmpInst::FCMP_OLE:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_OGE : FCmpInst::FCMP_OLE;
+    break;
+  case FCmpInst::FCMP_OLT:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_OGT : FCmpInst::FCMP_OLT;
+    break;
+  case FCmpInst::FCMP_ULT:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_UGT : FCmpInst::FCMP_ULT;
+    break;
+  case FCmpInst::FCMP_ULE:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_UGE : FCmpInst::FCMP_ULE;
+    break;
+  case FCmpInst::FCMP_UGE:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_ULE : FCmpInst::FCMP_UGE;
+    break;
+  case FCmpInst::FCMP_UGT:
+    NewPred = C1IsNegative ? FCmpInst::FCMP_ULT : FCmpInst::FCMP_UGT;
+    break;
+  }
+  Constant *NewRHSC = ConstantFoldBinaryOpOperands(Instruction::FDiv, RHSC, C1,
+                                                   I.getDataLayout());
+  return new FCmpInst(NewPred, X, NewRHSC);
+}
+
 /// Fold: fabs(uitofp(a) - uitofp(b)) pred C --> a == b
 /// where 'pred' is olt, ult, ogt, ugt, oge or uge and C is a positive, Non-NaN
 /// float when the uitofp casts are exact and C is in the valid range.
@@ -9201,6 +9253,10 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       if (Instruction *NV = foldFCmpIntToFPConst(I, LHSI, RHSC))
         return NV;
       break;
+    case Instruction::FMul:
+      if (Instruction *NV = foldFCmpFmulIntoFCmp(I, LHSI, RHSC))
+        return NV;
+      break;
     case Instruction::FDiv:
       if (Instruction *NV = foldFCmpReciprocalAndZero(I, LHSI, RHSC))
         return NV;

>From 6720954e9c2521c09b915626adac24fab21c3b1a Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 21 Jun 2026 22:20:05 +0530
Subject: [PATCH 02/10] [InstrCombine] Minor Fixes

fixes #153991
---
 llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index ac6861ada7822..c29bb41f57d39 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8889,7 +8889,9 @@ static Instruction *foldFCmpFmulIntoFCmp(FCmpInst &I, Instruction *LHSI,
   }
   Constant *NewRHSC = ConstantFoldBinaryOpOperands(Instruction::FDiv, RHSC, C1,
                                                    I.getDataLayout());
-  return new FCmpInst(NewPred, X, NewRHSC);
+  if (!NewRHSC || !cast<ConstantFP>(NewRHSC)->getValueAPF().isFinite())
+    return nullptr;
+  return new FCmpInst(NewPred, X, NewRHSC, "", &I);
 }
 
 /// Fold: fabs(uitofp(a) - uitofp(b)) pred C --> a == b

>From e8670a898a3eaee03fa40e57cf30333439b6fc22 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 21 Jun 2026 23:25:24 +0530
Subject: [PATCH 03/10] [InstCombine] Simplify code

fixes llvm#153991
---
 .../InstCombine/InstCombineCompares.cpp       | 60 ++++++-------------
 1 file changed, 17 insertions(+), 43 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index c29bb41f57d39..df07a76f8b425 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8843,55 +8843,29 @@ static Instruction *foldFCmpFSubIntoFCmp(FCmpInst &I, Instruction *LHSI,
 /// Fold: fcmp (fmul X, C1), C2 --> fcmp X, C2/C1
 static Instruction *foldFCmpFmulIntoFCmp(FCmpInst &I, Instruction *LHSI,
                                          Constant *RHSC) {
-  const CmpInst::Predicate Pred = I.getPredicate();
-  Value *X = LHSI->getOperand(0);
-  Value *Y = LHSI->getOperand(1);
+  FCmpInst::Predicate Pred = I.getPredicate();
 
-  ConstantFP *C1;
-  if (!match(Y, m_ConstantFP(C1)) || match(C1, m_AnyZeroFP()))
+  if ((Pred != FCmpInst::FCMP_OGE) && (Pred != FCmpInst::FCMP_OGT) &&
+      (Pred != FCmpInst::FCMP_OLE) && (Pred != FCmpInst::FCMP_OLT) &&
+      (Pred != FCmpInst::FCMP_ONE) && (Pred != FCmpInst::FCMP_OEQ) &&
+      (Pred != FCmpInst::FCMP_UGE) && (Pred != FCmpInst::FCMP_UGT) &&
+      (Pred != FCmpInst::FCMP_ULE) && (Pred != FCmpInst::FCMP_ULT) &&
+      (Pred != FCmpInst::FCMP_UNE) && (Pred != FCmpInst::FCMP_UEQ))
     return nullptr;
 
-  CmpInst::Predicate NewPred;
-  bool C1IsNegative = C1->isNegative();
-  switch (Pred) {
-  default:
+  ConstantFP *C;
+  if (!match(LHSI->getOperand(1), m_ConstantFP(C)) || match(C, m_AnyZeroFP()))
     return nullptr;
-  case FCmpInst::FCMP_UEQ:
-  case FCmpInst::FCMP_UNE:
-  case FCmpInst::FCMP_OEQ:
-  case FCmpInst::FCMP_ONE:
-    NewPred = Pred;
-    break;
-  case FCmpInst::FCMP_OGE:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_OLE : FCmpInst::FCMP_OGE;
-    break;
-  case FCmpInst::FCMP_OGT:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_OLT : FCmpInst::FCMP_OGT;
-    break;
-  case FCmpInst::FCMP_OLE:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_OGE : FCmpInst::FCMP_OLE;
-    break;
-  case FCmpInst::FCMP_OLT:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_OGT : FCmpInst::FCMP_OLT;
-    break;
-  case FCmpInst::FCMP_ULT:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_UGT : FCmpInst::FCMP_ULT;
-    break;
-  case FCmpInst::FCMP_ULE:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_UGE : FCmpInst::FCMP_ULE;
-    break;
-  case FCmpInst::FCMP_UGE:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_ULE : FCmpInst::FCMP_UGE;
-    break;
-  case FCmpInst::FCMP_UGT:
-    NewPred = C1IsNegative ? FCmpInst::FCMP_ULT : FCmpInst::FCMP_UGT;
-    break;
-  }
-  Constant *NewRHSC = ConstantFoldBinaryOpOperands(Instruction::FDiv, RHSC, C1,
+
+  if (C->isNegative())
+    Pred = I.getSwappedPredicate();
+
+  Constant *NewRHSC = ConstantFoldBinaryOpOperands(Instruction::FDiv, RHSC, C,
                                                    I.getDataLayout());
-  if (!NewRHSC || !cast<ConstantFP>(NewRHSC)->getValueAPF().isFinite())
+  if (!NewRHSC)
     return nullptr;
-  return new FCmpInst(NewPred, X, NewRHSC, "", &I);
+
+  return new FCmpInst(Pred, LHSI->getOperand(0), NewRHSC, "", &I);
 }
 
 /// Fold: fabs(uitofp(a) - uitofp(b)) pred C --> a == b

>From 5d05032854f73417b32e29ba03677ae2b70d8731 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 21 Jun 2026 23:29:09 +0530
Subject: [PATCH 04/10] [InstCombine] Add Tests;fixes llvm#153991

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

diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 6c3091afcacaa..619596a2f80df 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -2835,3 +2835,280 @@ define <2 x i1> @fabs_uitofp_sub_vec_bf16_no_fold(<2 x i16> %x, <2 x i16> %y) {
   %cmp = fcmp olt <2 x bfloat> %abs, splat (bfloat 0xR3F80)
   ret <2 x i1> %cmp
 }
+
+define i1 @fcmp_oeq_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_oeq_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp oeq float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_one_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_one_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp one float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ueq_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_ueq_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp ueq float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_une_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_une_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp une float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ogt_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_ogt_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp ogt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_oge_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_oge_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp oge float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_olt_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_olt_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp olt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ole_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_ole_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp ole float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ogt_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_ogt_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp ogt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_oge_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_oge_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp oge float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_olt_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_olt_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp olt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ole_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_ole_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp ole float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ugt_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_ugt_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp ugt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uge_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_uge_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp uge float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ult_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_ult_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp ult float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ule_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_ule_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp ule float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ugt_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_ugt_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp ugt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uge_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_uge_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp uge float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ult_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_ult_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp ult float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ule_fmul_neg_const(float %x) {
+; CHECK-LABEL: @fcmp_ule_fmul_neg_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, -2.0
+  %cmp = fcmp ule float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ogt_fmul_pos_const_extra_use(float %x) {
+; CHECK-LABEL: @fcmp_ogt_fmul_pos_const_extra_use(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    call void @use(float [[MUL]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  call void @use(float %mul)
+  %cmp = fcmp ogt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ogt_fmul_zero_const(float %x) {
+; CHECK-LABEL: @fcmp_ogt_fmul_zero_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 0.0
+  %cmp = fcmp ogt float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ord_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_ord_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[MUL]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp ord float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uno_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_uno_fmul_pos_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[MUL]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp uno float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ogt_fmul_no_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ogt_fmul_no_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, %y
+  %cmp = fcmp ogt float %mul, 6.0
+  ret i1 %cmp
+}

>From 9b020693942065122f42e4ca653b5511706d7de4 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 21 Jun 2026 23:59:16 +0530
Subject: [PATCH 05/10] [InstCombine] Check line diff; Optimization works

fixes llvm#153991
---
 llvm/test/Transforms/InstCombine/fcmp.ll | 62 ++++++++----------------
 1 file changed, 21 insertions(+), 41 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 619596a2f80df..37cf067f219a9 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -2838,8 +2838,7 @@ define <2 x i1> @fabs_uitofp_sub_vec_bf16_no_fold(<2 x i16> %x, <2 x i16> %y) {
 
 define i1 @fcmp_oeq_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_oeq_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2849,8 +2848,7 @@ define i1 @fcmp_oeq_fmul_pos_const(float %x) {
 
 define i1 @fcmp_one_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_one_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2860,8 +2858,7 @@ define i1 @fcmp_one_fmul_pos_const(float %x) {
 
 define i1 @fcmp_ueq_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_ueq_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2871,8 +2868,7 @@ define i1 @fcmp_ueq_fmul_pos_const(float %x) {
 
 define i1 @fcmp_une_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_une_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2882,8 +2878,7 @@ define i1 @fcmp_une_fmul_pos_const(float %x) {
 
 define i1 @fcmp_ogt_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_ogt_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2893,8 +2888,7 @@ define i1 @fcmp_ogt_fmul_pos_const(float %x) {
 
 define i1 @fcmp_oge_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_oge_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2904,8 +2898,7 @@ define i1 @fcmp_oge_fmul_pos_const(float %x) {
 
 define i1 @fcmp_olt_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_olt_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2915,8 +2908,7 @@ define i1 @fcmp_olt_fmul_pos_const(float %x) {
 
 define i1 @fcmp_ole_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_ole_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2926,8 +2918,7 @@ define i1 @fcmp_ole_fmul_pos_const(float %x) {
 
 define i1 @fcmp_ogt_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_ogt_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -2937,8 +2928,7 @@ define i1 @fcmp_ogt_fmul_neg_const(float %x) {
 
 define i1 @fcmp_oge_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_oge_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -2948,8 +2938,7 @@ define i1 @fcmp_oge_fmul_neg_const(float %x) {
 
 define i1 @fcmp_olt_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_olt_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -2959,8 +2948,7 @@ define i1 @fcmp_olt_fmul_neg_const(float %x) {
 
 define i1 @fcmp_ole_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_ole_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -2970,8 +2958,7 @@ define i1 @fcmp_ole_fmul_neg_const(float %x) {
 
 define i1 @fcmp_ugt_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_ugt_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2981,8 +2968,7 @@ define i1 @fcmp_ugt_fmul_pos_const(float %x) {
 
 define i1 @fcmp_uge_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_uge_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -2992,8 +2978,7 @@ define i1 @fcmp_uge_fmul_pos_const(float %x) {
 
 define i1 @fcmp_ult_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_ult_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -3003,8 +2988,7 @@ define i1 @fcmp_ult_fmul_pos_const(float %x) {
 
 define i1 @fcmp_ule_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_ule_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[X:%.*]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -3014,8 +2998,7 @@ define i1 @fcmp_ule_fmul_pos_const(float %x) {
 
 define i1 @fcmp_ugt_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_ugt_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -3025,8 +3008,7 @@ define i1 @fcmp_ugt_fmul_neg_const(float %x) {
 
 define i1 @fcmp_uge_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_uge_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -3036,8 +3018,7 @@ define i1 @fcmp_uge_fmul_neg_const(float %x) {
 
 define i1 @fcmp_ult_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_ult_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -3047,8 +3028,7 @@ define i1 @fcmp_ult_fmul_neg_const(float %x) {
 
 define i1 @fcmp_ule_fmul_neg_const(float %x) {
 ; CHECK-LABEL: @fcmp_ule_fmul_neg_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], -2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[X:%.*]], -3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, -2.0
@@ -3060,7 +3040,7 @@ define i1 @fcmp_ogt_fmul_pos_const_extra_use(float %x) {
 ; CHECK-LABEL: @fcmp_ogt_fmul_pos_const_extra_use(
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
 ; CHECK-NEXT:    call void @use(float [[MUL]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X]], 3.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0

>From ad50e96c1573871467f9d6a8e65b8640721700fd Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Tue, 23 Jun 2026 13:03:27 +0530
Subject: [PATCH 06/10] [InstCombine] fixed half type and denormals issue

---
 .../Transforms/InstCombine/InstCombineCompares.cpp    |  8 +++++++-
 llvm/test/Transforms/InstCombine/fcmp.ll              | 11 +++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index df07a76f8b425..52fc013c2ebbe 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8854,7 +8854,13 @@ static Instruction *foldFCmpFmulIntoFCmp(FCmpInst &I, Instruction *LHSI,
     return nullptr;
 
   ConstantFP *C;
-  if (!match(LHSI->getOperand(1), m_ConstantFP(C)) || match(C, m_AnyZeroFP()))
+  if (!match(LHSI->getOperand(1), m_ConstantFP(C)) || C->isZero())
+    return nullptr;
+
+  Type *FPTy = LHSI->getType()->getScalarType();
+  if (FPTy->isHalfTy() ||
+      I.getFunction()->getDenormalMode(FPTy->getFltSemantics()) !=
+          DenormalMode::getIEEE())
     return nullptr;
 
   if (C->isNegative())
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 37cf067f219a9..84fa5ad6ea0a7 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -3092,3 +3092,14 @@ define i1 @fcmp_ogt_fmul_no_const(float %x, float %y) {
   %cmp = fcmp ogt float %mul, 6.0
   ret i1 %cmp
 }
+
+define i1 @fcmp_oeq_fmul_half_const(half %x) {
+; CHECK-LABEL: @fcmp_oeq_fmul_half_const(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul half [[X:%.*]], 3.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq half [[MUL]], 1.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul half %x, 0xH4200
+  %cmp = fcmp oeq half %mul, 0xH3C00
+  ret i1 %cmp
+}

>From 2ac5b21140880968fa45ac05638618cd1321a226 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 28 Jun 2026 18:26:23 +0530
Subject: [PATCH 07/10] [InstCombine] Limit to IEEE denormal mode; Added
 negative test for that

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

diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 84fa5ad6ea0a7..ee12a55ccf187 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -3093,6 +3093,17 @@ define i1 @fcmp_ogt_fmul_no_const(float %x, float %y) {
   ret i1 %cmp
 }
 
+define i1 @fcmp_oeq_fmul_pos_const_daz(float %x) denormal_fpenv(ieee|preservesign) {
+; CHECK-LABEL: @fcmp_oeq_fmul_pos_const_daz(
+; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[MUL]], 6.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp oeq float %mul, 6.0
+  ret i1 %cmp
+}
+
 define i1 @fcmp_oeq_fmul_half_const(half %x) {
 ; CHECK-LABEL: @fcmp_oeq_fmul_half_const(
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul half [[X:%.*]], 3.000000e+00

>From a9635b3d7989a2b63e63e977ed1ac9e0528259a5 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sat, 11 Jul 2026 23:53:08 +0530
Subject: [PATCH 08/10] [InstCombine] APFloat now checks validity of float
 divide

---
 .../InstCombine/InstCombineCompares.cpp         | 17 ++++++++---------
 llvm/test/Transforms/InstCombine/fcmp.ll        |  4 ++--
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 52fc013c2ebbe..dbea7636c44ac 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8853,24 +8853,23 @@ static Instruction *foldFCmpFmulIntoFCmp(FCmpInst &I, Instruction *LHSI,
       (Pred != FCmpInst::FCMP_UNE) && (Pred != FCmpInst::FCMP_UEQ))
     return nullptr;
 
-  ConstantFP *C;
-  if (!match(LHSI->getOperand(1), m_ConstantFP(C)) || C->isZero())
+  const APFloat *C1, *C2;
+  if (!match(LHSI->getOperand(1), m_APFloat(C1)) || !match(RHSC, m_APFloat(C2)))
     return nullptr;
 
   Type *FPTy = LHSI->getType()->getScalarType();
-  if (FPTy->isHalfTy() ||
-      I.getFunction()->getDenormalMode(FPTy->getFltSemantics()) !=
-          DenormalMode::getIEEE())
+  if (I.getFunction()->getDenormalMode(FPTy->getFltSemantics()) !=
+      DenormalMode::getIEEE())
     return nullptr;
 
-  if (C->isNegative())
+  if (C1->isNegative())
     Pred = I.getSwappedPredicate();
 
-  Constant *NewRHSC = ConstantFoldBinaryOpOperands(Instruction::FDiv, RHSC, C,
-                                                   I.getDataLayout());
-  if (!NewRHSC)
+  APFloat C = *C2;
+  if (C.divide(*C1, RoundingMode::NearestTiesToEven) != APFloat::opOK)
     return nullptr;
 
+  Constant *NewRHSC = ConstantFP::get(RHSC->getType(), C);
   return new FCmpInst(Pred, LHSI->getOperand(0), NewRHSC, "", &I);
 }
 
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index ee12a55ccf187..3b3c10f716958 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -3110,7 +3110,7 @@ define i1 @fcmp_oeq_fmul_half_const(half %x) {
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq half [[MUL]], 1.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
-  %mul = fmul half %x, 0xH4200
-  %cmp = fcmp oeq half %mul, 0xH3C00
+  %mul = fmul half %x, 3.0
+  %cmp = fcmp oeq half %mul, 1.0
   ret i1 %cmp
 }

>From 8ddade2a3f81fcc86b0cf26dce2438b948815b22 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Tue, 14 Jul 2026 02:51:31 +0530
Subject: [PATCH 09/10] [InstCombine] Remove predicate specific exclusions

---
 .../InstCombine/InstCombineCompares.cpp       |  8 -------
 llvm/test/Transforms/InstCombine/fcmp.ll      | 24 +++++++++++++++----
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index dbea7636c44ac..12b04721d422f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8845,14 +8845,6 @@ static Instruction *foldFCmpFmulIntoFCmp(FCmpInst &I, Instruction *LHSI,
                                          Constant *RHSC) {
   FCmpInst::Predicate Pred = I.getPredicate();
 
-  if ((Pred != FCmpInst::FCMP_OGE) && (Pred != FCmpInst::FCMP_OGT) &&
-      (Pred != FCmpInst::FCMP_OLE) && (Pred != FCmpInst::FCMP_OLT) &&
-      (Pred != FCmpInst::FCMP_ONE) && (Pred != FCmpInst::FCMP_OEQ) &&
-      (Pred != FCmpInst::FCMP_UGE) && (Pred != FCmpInst::FCMP_UGT) &&
-      (Pred != FCmpInst::FCMP_ULE) && (Pred != FCmpInst::FCMP_ULT) &&
-      (Pred != FCmpInst::FCMP_UNE) && (Pred != FCmpInst::FCMP_UEQ))
-    return nullptr;
-
   const APFloat *C1, *C2;
   if (!match(LHSI->getOperand(1), m_APFloat(C1)) || !match(RHSC, m_APFloat(C2)))
     return nullptr;
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 3b3c10f716958..30f0aac247626 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -3062,8 +3062,7 @@ define i1 @fcmp_ogt_fmul_zero_const(float %x) {
 
 define i1 @fcmp_ord_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_ord_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[MUL]], 0.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[MUL:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -3073,8 +3072,7 @@ define i1 @fcmp_ord_fmul_pos_const(float %x) {
 
 define i1 @fcmp_uno_fmul_pos_const(float %x) {
 ; CHECK-LABEL: @fcmp_uno_fmul_pos_const(
-; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], 2.000000e+00
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[MUL]], 0.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[MUL:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = fmul float %x, 2.0
@@ -3082,6 +3080,24 @@ define i1 @fcmp_uno_fmul_pos_const(float %x) {
   ret i1 %cmp
 }
 
+define i1 @fcmp_false_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_false_fmul_pos_const(
+; CHECK-NEXT:    ret i1 false
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp false float %mul, 6.0
+  ret i1 %cmp
+}
+
+define i1 @fcmp_true_fmul_pos_const(float %x) {
+; CHECK-LABEL: @fcmp_true_fmul_pos_const(
+; CHECK-NEXT:    ret i1 true
+;
+  %mul = fmul float %x, 2.0
+  %cmp = fcmp true float %mul, 6.0
+  ret i1 %cmp
+}
+
 define i1 @fcmp_ogt_fmul_no_const(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_ogt_fmul_no_const(
 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]

>From 37421534d13583185ff5b5a42fac083c8e0d9b19 Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Sun, 2 Aug 2026 20:36:42 +0530
Subject: [PATCH 10/10] [InstCombine] Remove Denormal Check

---
 llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 12b04721d422f..6da79c9376220 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8849,11 +8849,6 @@ static Instruction *foldFCmpFmulIntoFCmp(FCmpInst &I, Instruction *LHSI,
   if (!match(LHSI->getOperand(1), m_APFloat(C1)) || !match(RHSC, m_APFloat(C2)))
     return nullptr;
 
-  Type *FPTy = LHSI->getType()->getScalarType();
-  if (I.getFunction()->getDenormalMode(FPTy->getFltSemantics()) !=
-      DenormalMode::getIEEE())
-    return nullptr;
-
   if (C1->isNegative())
     Pred = I.getSwappedPredicate();
 



More information about the llvm-commits mailing list