[llvm] [InstCombine] Fold `fcmp ord/uno (fptrunc X), C` to `fcmp ord/uno X, C` (PR #185848)
Tirthankar Mazumder via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 11 06:13:39 PDT 2026
https://github.com/wermos updated https://github.com/llvm/llvm-project/pull/185848
>From a30fd37f4b5cc6ed49ff55c396547be43339da39 Mon Sep 17 00:00:00 2001
From: Tirthankar Mazumder <tmazumder.github at gmail.com>
Date: Wed, 11 Mar 2026 13:18:38 +0530
Subject: [PATCH 1/4] Pre-commit tests
---
.../Transforms/InstCombine/fold-fcmp-trunc.ll | 49 ++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
index 371f9b6807fe4..7bc5d7fb7a1c6 100644
--- a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
+++ b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
@@ -104,7 +104,7 @@ define i1 @fcmp_trunc_with_reassoc(double %0) {
define i1 @fcmp_trunc_with_fast(double %0) {
; CHECK-LABEL: define i1 @fcmp_trunc_with_fast(
; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT: [[RESULT:%.*]] = fcmp fast oge double [[TMP0]], 0x4058FFFFF0000000
+; CHECK-NEXT: [[RESULT:%.*]] = fcmp fast oge double [[TMP0]], 0x4058FFFFF0000000
; CHECK-NEXT: ret i1 [[RESULT]]
;
%trunc = fptrunc double %0 to float
@@ -672,3 +672,50 @@ define i1 @fcmp_trunc_mn_ppc_fp128(ppc_fp128 %0) {
ret i1 %result
}
+define i1 @fptrunc_uno_fcmp(double %arg0) {
+; CHECK-LABEL: define i1 @fptrunc_uno_fcmp(
+; CHECK-SAME: double [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
+; CHECK-NEXT: [[V1:%.*]] = fcmp uno float [[V0]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptrunc double %arg0 to float
+ %v1 = fcmp uno float %v0, 0.000000e+00
+ ret i1 %v1
+}
+
+define i1 @fptrunc_uno_fcmp_commuted(double %arg0) {
+; CHECK-LABEL: define i1 @fptrunc_uno_fcmp_commuted(
+; CHECK-SAME: double [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
+; CHECK-NEXT: [[V1:%.*]] = fcmp uno float [[V0]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptrunc double %arg0 to float
+ %v1 = fcmp uno float 7.000000e+00, %v0
+ ret i1 %v1
+}
+
+define i1 @fptrunc_ord_fcmp(double %arg0) {
+; CHECK-LABEL: define i1 @fptrunc_ord_fcmp(
+; CHECK-SAME: double [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
+; CHECK-NEXT: [[V1:%.*]] = fcmp ord float [[V0]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptrunc double %arg0 to float
+ %v1 = fcmp ord float %v0, 0.000000e+00
+ ret i1 %v1
+}
+
+define i1 @fptrunc_ord_fcmp_commuted(double %arg0) {
+; CHECK-LABEL: define i1 @fptrunc_ord_fcmp_commuted(
+; CHECK-SAME: double [[ARG0:%.*]]) {
+; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
+; CHECK-NEXT: [[V1:%.*]] = fcmp ord float [[V0]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = fptrunc double %arg0 to float
+ %v1 = fcmp ord float 7.000000e+00, %v0
+ ret i1 %v1
+}
>From 0b45b755eb6afb7c7e179ffd5d401ae3505611d6 Mon Sep 17 00:00:00 2001
From: Tirthankar Mazumder <tmazumder.github at gmail.com>
Date: Wed, 11 Mar 2026 15:28:26 +0530
Subject: [PATCH 2/4] Fold fcmp ord/uno (fptrunc X), C to fcmp ord/uno X, C.
---
.../InstCombine/InstCombineCompares.cpp | 52 +++++++++++--------
.../Transforms/InstCombine/fold-fcmp-trunc.ll | 15 ++----
2 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 10caf4ab78a5a..90e9fbb4ab583 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8359,26 +8359,15 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
// Transform 'fptrunc(x) cmp C' to 'x cmp ext(C)' if possible.
// Patterns include:
-// fptrunc(x) < C --> x < ext(C)
-// fptrunc(x) <= C --> x <= ext(C)
-// fptrunc(x) > C --> x > ext(C)
-// fptrunc(x) >= C --> x >= ext(C)
+// fptrunc(x) < C --> x < ext(C)
+// fptrunc(x) <= C --> x <= ext(C)
+// fptrunc(x) > C --> x > ext(C)
+// fptrunc(x) >= C --> x >= ext(C)
+// fptrunc(x) ord/uno C --> x ord/uno C
// where 'ext(C)' is the extension of 'C' to the type of 'x' with a small bias
// due to precision loss.
static Instruction *foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc,
const Constant &C) {
- FCmpInst::Predicate Pred = I.getPredicate();
- bool RoundDown = false;
-
- if (Pred == FCmpInst::FCMP_OGE || Pred == FCmpInst::FCMP_UGE ||
- Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_ULT)
- RoundDown = true;
- else if (Pred == FCmpInst::FCMP_OGT || Pred == FCmpInst::FCMP_UGT ||
- Pred == FCmpInst::FCMP_OLE || Pred == FCmpInst::FCMP_ULE)
- RoundDown = false;
- else
- return nullptr;
-
const APFloat *CValue;
if (!match(&C, m_APFloat(CValue)))
return nullptr;
@@ -8393,6 +8382,31 @@ static Instruction *foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc,
return Dest;
};
+ Type *DestType = FPTrunc.getOperand(0)->getType();
+ const fltSemantics &DestFltSema =
+ DestType->getScalarType()->getFltSemantics();
+
+ APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
+
+ FCmpInst::Predicate Pred = I.getPredicate();
+
+ // Fold fcmp ord/uno fptrunc X, C -> fcmp ord/uno X, C
+ if (Pred == FCmpInst::FCMP_ORD || Pred == FCmpInst::FCMP_UNO) {
+ return new FCmpInst(Pred, FPTrunc.getOperand(0),
+ ConstantFP::get(DestType, ExtCValue), "", &I);
+ }
+
+ bool RoundDown = false;
+
+ if (Pred == FCmpInst::FCMP_OGE || Pred == FCmpInst::FCMP_UGE ||
+ Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_ULT)
+ RoundDown = true;
+ else if (Pred == FCmpInst::FCMP_OGT || Pred == FCmpInst::FCMP_UGT ||
+ Pred == FCmpInst::FCMP_OLE || Pred == FCmpInst::FCMP_ULE)
+ RoundDown = false;
+ else
+ return nullptr;
+
auto NextValue = [](const APFloat &Value, bool RoundDown) {
APFloat NextValue = Value;
NextValue.next(RoundDown);
@@ -8400,12 +8414,6 @@ static Instruction *foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc,
};
APFloat NextCValue = NextValue(*CValue, RoundDown);
-
- Type *DestType = FPTrunc.getOperand(0)->getType();
- const fltSemantics &DestFltSema =
- DestType->getScalarType()->getFltSemantics();
-
- APFloat ExtCValue = ConvertFltSema(*CValue, DestFltSema);
APFloat ExtNextCValue = ConvertFltSema(NextCValue, DestFltSema);
// When 'NextCValue' is infinity, use an imaged 'NextCValue' that equals
diff --git a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
index 7bc5d7fb7a1c6..bca9be81dca16 100644
--- a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
+++ b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
@@ -327,8 +327,7 @@ define i1 @fcmp_trunc_literal_positive_inf(double %0) {
define i1 @fcmp_trunc_literal_negative_inf(double %0) {
; CHECK-LABEL: define i1 @fcmp_trunc_literal_negative_inf(
; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT: [[TRUNC:%.*]] = fptrunc double [[TMP0]] to float
-; CHECK-NEXT: [[RESULT:%.*]] = fcmp uno float [[TRUNC]], 0.000000e+00
+; CHECK-NEXT: [[RESULT:%.*]] = fcmp uno double [[TMP0]], 0.000000e+00
; CHECK-NEXT: ret i1 [[RESULT]]
;
%trunc = fptrunc double %0 to float
@@ -675,8 +674,7 @@ define i1 @fcmp_trunc_mn_ppc_fp128(ppc_fp128 %0) {
define i1 @fptrunc_uno_fcmp(double %arg0) {
; CHECK-LABEL: define i1 @fptrunc_uno_fcmp(
; CHECK-SAME: double [[ARG0:%.*]]) {
-; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
-; CHECK-NEXT: [[V1:%.*]] = fcmp uno float [[V0]], 0.000000e+00
+; CHECK-NEXT: [[V1:%.*]] = fcmp uno double [[ARG0]], 0.000000e+00
; CHECK-NEXT: ret i1 [[V1]]
;
%v0 = fptrunc double %arg0 to float
@@ -687,8 +685,7 @@ define i1 @fptrunc_uno_fcmp(double %arg0) {
define i1 @fptrunc_uno_fcmp_commuted(double %arg0) {
; CHECK-LABEL: define i1 @fptrunc_uno_fcmp_commuted(
; CHECK-SAME: double [[ARG0:%.*]]) {
-; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
-; CHECK-NEXT: [[V1:%.*]] = fcmp uno float [[V0]], 0.000000e+00
+; CHECK-NEXT: [[V1:%.*]] = fcmp uno double [[ARG0]], 0.000000e+00
; CHECK-NEXT: ret i1 [[V1]]
;
%v0 = fptrunc double %arg0 to float
@@ -699,8 +696,7 @@ define i1 @fptrunc_uno_fcmp_commuted(double %arg0) {
define i1 @fptrunc_ord_fcmp(double %arg0) {
; CHECK-LABEL: define i1 @fptrunc_ord_fcmp(
; CHECK-SAME: double [[ARG0:%.*]]) {
-; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
-; CHECK-NEXT: [[V1:%.*]] = fcmp ord float [[V0]], 0.000000e+00
+; CHECK-NEXT: [[V1:%.*]] = fcmp ord double [[ARG0]], 0.000000e+00
; CHECK-NEXT: ret i1 [[V1]]
;
%v0 = fptrunc double %arg0 to float
@@ -711,8 +707,7 @@ define i1 @fptrunc_ord_fcmp(double %arg0) {
define i1 @fptrunc_ord_fcmp_commuted(double %arg0) {
; CHECK-LABEL: define i1 @fptrunc_ord_fcmp_commuted(
; CHECK-SAME: double [[ARG0:%.*]]) {
-; CHECK-NEXT: [[V0:%.*]] = fptrunc double [[ARG0]] to float
-; CHECK-NEXT: [[V1:%.*]] = fcmp ord float [[V0]], 0.000000e+00
+; CHECK-NEXT: [[V1:%.*]] = fcmp ord double [[ARG0]], 0.000000e+00
; CHECK-NEXT: ret i1 [[V1]]
;
%v0 = fptrunc double %arg0 to float
>From 8720d1f4ab0cb503e3aa608e0a9fb53335092726 Mon Sep 17 00:00:00 2001
From: Tirthankar Mazumder <tmazumder.github at gmail.com>
Date: Wed, 11 Mar 2026 18:42:28 +0530
Subject: [PATCH 3/4] Update another test.
---
llvm/test/Transforms/InstCombine/known-never-nan.ll | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/known-never-nan.ll b/llvm/test/Transforms/InstCombine/known-never-nan.ll
index c4ce874029647..759cabae3d72f 100644
--- a/llvm/test/Transforms/InstCombine/known-never-nan.ll
+++ b/llvm/test/Transforms/InstCombine/known-never-nan.ll
@@ -150,8 +150,7 @@ define i1 @fpext_maybe_nan(float %arg0) {
define i1 @fptrunc_maybe_nan(double %arg0) {
; CHECK-LABEL: @fptrunc_maybe_nan(
-; CHECK-NEXT: [[OP:%.*]] = fptrunc double [[ARG0:%.*]] to float
-; CHECK-NEXT: [[TMP:%.*]] = fcmp ord float [[OP]], 0.000000e+00
+; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[ARG0:%.*]], 0.000000e+00
; CHECK-NEXT: ret i1 [[TMP]]
;
%op = fptrunc double %arg0 to float
>From 0b282d9d85ff9bc4dc329ab800b11338473f8293 Mon Sep 17 00:00:00 2001
From: Tirthankar Mazumder <tmazumder.github at gmail.com>
Date: Wed, 11 Mar 2026 18:43:23 +0530
Subject: [PATCH 4/4] Fix comment formatting.
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 90e9fbb4ab583..7716f6c190e3c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8363,7 +8363,7 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
// fptrunc(x) <= C --> x <= ext(C)
// fptrunc(x) > C --> x > ext(C)
// fptrunc(x) >= C --> x >= ext(C)
-// fptrunc(x) ord/uno C --> x ord/uno C
+// fptrunc(x) ord/uno C --> x ord/uno C
// where 'ext(C)' is the extension of 'C' to the type of 'x' with a small bias
// due to precision loss.
static Instruction *foldFCmpFpTrunc(FCmpInst &I, const Instruction &FPTrunc,
More information about the llvm-commits
mailing list