[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