[llvm] [InstCombine] Optimize fcmp ord/uno logical select operations using freeze (PR #205076)
SUBASH BOOPATHI via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 22 21:46:38 PDT 2026
https://github.com/SubashBoopathi1605 updated https://github.com/llvm/llvm-project/pull/205076
>From 0f8dd78635eed64dec611d6de32ea1a8abd4eddf Mon Sep 17 00:00:00 2001
From: Subash Boopathi <subashofficial7 at gmail.com>
Date: Mon, 22 Jun 2026 15:56:02 +0530
Subject: [PATCH] [InstCombine] Optimize fcmp ord/uno logical select operations
using freeze
---
.../InstCombine/InstCombineAndOrXor.cpp | 11 ++++++-----
llvm/test/Transforms/InstCombine/and-fcmp.ll | 18 ++++++------------
llvm/test/Transforms/InstCombine/or-fcmp.ll | 12 ++++--------
3 files changed, 16 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b4686a6a63e86..8a98f2a479c0d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1472,11 +1472,9 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
FMFSource::intersect(LHS, RHS));
}
- // This transform is not valid for a logical select.
- if (!IsLogicalSelect &&
- ((PredL == FCmpInst::FCMP_ORD && PredR == FCmpInst::FCMP_ORD && IsAnd) ||
+ if ((PredL == FCmpInst::FCMP_ORD && PredR == FCmpInst::FCMP_ORD && IsAnd) ||
(PredL == FCmpInst::FCMP_UNO && PredR == FCmpInst::FCMP_UNO &&
- !IsAnd))) {
+ !IsAnd)) {
if (LHS0->getType() != RHS0->getType())
return nullptr;
@@ -1486,7 +1484,10 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
// Ignore the constants because they are obviously not NANs:
// (fcmp ord x, 0.0) & (fcmp ord y, 0.0) -> (fcmp ord x, y)
// (fcmp uno x, 0.0) | (fcmp uno y, 0.0) -> (fcmp uno x, y)
- return Builder.CreateFCmpFMF(PredL, LHS0, RHS0,
+ Value *Y = RHS0;
+ if (IsLogicalSelect)
+ Y = Builder.CreateFreeze(Y, Y->getName() + ".fr");
+ return Builder.CreateFCmpFMF(PredL, LHS0, Y,
FMFSource::intersect(LHS, RHS));
}
}
diff --git a/llvm/test/Transforms/InstCombine/and-fcmp.ll b/llvm/test/Transforms/InstCombine/and-fcmp.ll
index 99adb49a579ec..64b12bada377d 100644
--- a/llvm/test/Transforms/InstCombine/and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/and-fcmp.ll
@@ -12,12 +12,10 @@ define i1 @PR1738(double %x, double %y) {
ret i1 %and
}
-; TODO: this can be supported by freezing %y
define i1 @PR1738_logical(double %x, double %y) {
; CHECK-LABEL: @PR1738_logical(
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord double [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord double [[Y:%.*]], 0.000000e+00
-; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
+; CHECK-NEXT: [[Y_FR:%.*]] = freeze double [[Y:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = fcmp ord double [[X:%.*]], [[Y_FR]]
; CHECK-NEXT: ret i1 [[AND]]
;
%cmp1 = fcmp ord double %x, 0.0
@@ -103,12 +101,10 @@ define i1 @PR41069_commute(i1 %z, float %c, float %d) {
ret i1 %r
}
-; TODO: this should be fixed using freeze
define i1 @PR41069_commute_logical(i1 %z, float %c, float %d) {
; CHECK-LABEL: @PR41069_commute_logical(
-; CHECK-NEXT: [[ORD1:%.*]] = fcmp ninf ord float [[C:%.*]], 0.000000e+00
-; CHECK-NEXT: [[ORD2:%.*]] = fcmp reassoc ninf ord float [[D:%.*]], 0.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ORD2]], i1 [[ORD1]], i1 false
+; CHECK-NEXT: [[C_FR:%.*]] = freeze float [[C:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = fcmp ninf ord float [[D:%.*]], [[C_FR]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i1 [[Z:%.*]], i1 false
; CHECK-NEXT: ret i1 [[R]]
;
@@ -205,12 +201,10 @@ define i1 @fcmp_ord_nonzero(float %x, float %y) {
ret i1 %and
}
-; TODO: this can be supported by freezing %y
define i1 @fcmp_ord_nonzero_logical(float %x, float %y) {
; CHECK-LABEL: @fcmp_ord_nonzero_logical(
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[CMP2:%.*]] = fcmp ord float [[Y:%.*]], 0.000000e+00
-; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
+; CHECK-NEXT: [[Y_FR:%.*]] = freeze float [[Y:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = fcmp ord float [[X:%.*]], [[Y_FR]]
; CHECK-NEXT: ret i1 [[AND]]
;
%cmp1 = fcmp ord float %x, 1.0
diff --git a/llvm/test/Transforms/InstCombine/or-fcmp.ll b/llvm/test/Transforms/InstCombine/or-fcmp.ll
index 193fe4b5cc722..99f8b687fd603 100644
--- a/llvm/test/Transforms/InstCombine/or-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/or-fcmp.ll
@@ -12,12 +12,10 @@ define i1 @PR1738(double %x, double %y) {
ret i1 %or
}
-; TODO: this can be fixed by freezing %y
define i1 @PR1738_logical(double %x, double %y) {
; CHECK-LABEL: @PR1738_logical(
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno double [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[CMP2:%.*]] = fcmp uno double [[Y:%.*]], 0.000000e+00
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
+; CHECK-NEXT: [[Y_FR:%.*]] = freeze double [[Y:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = fcmp uno double [[X:%.*]], [[Y_FR]]
; CHECK-NEXT: ret i1 [[OR]]
;
%cmp1 = fcmp uno double %x, 0.0
@@ -183,12 +181,10 @@ define i1 @fcmp_uno_nonzero(float %x, float %y) {
ret i1 %or
}
-; TODO: this can be fixed by freezing %y
define i1 @fcmp_uno_nonzero_logical(float %x, float %y) {
; CHECK-LABEL: @fcmp_uno_nonzero_logical(
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[CMP2:%.*]] = fcmp uno float [[Y:%.*]], 0.000000e+00
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
+; CHECK-NEXT: [[Y_FR:%.*]] = freeze float [[Y:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = fcmp uno float [[X:%.*]], [[Y_FR]]
; CHECK-NEXT: ret i1 [[OR]]
;
%cmp1 = fcmp uno float %x, 1.0
More information about the llvm-commits
mailing list