[llvm] [InstCombine] Optimize redundant floating point comparisons in `or` inst (PR #158097)
Rajveer Singh Bharadwaj via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 08:27:55 PDT 2025
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/158097
>From 7a8a3b014ec45ba6cd397da4e93fa89c3f201134 Mon Sep 17 00:00:00 2001
From: Rajveer <rajveer.developer at icloud.com>
Date: Thu, 11 Sep 2025 20:52:21 +0530
Subject: [PATCH] [InstCombine] Optimize redundant floating point comparisons
in `or` inst
Resolves #157371
We can eliminate one of the `fcmp` when we have two same `olt` or `ogt`
instructions matched in `or` simplification.
---
.../InstCombine/InstCombineAndOrXor.cpp | 24 ++++++++
llvm/test/Transforms/InstCombine/or-fcmp.ll | 60 +++++++++++++++++++
.../Transforms/InstCombine/redundant-fcmp.ll | 54 +++++++++++++++++
3 files changed, 138 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/redundant-fcmp.ll
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 6e46898634070..93c6a65dab1cc 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4514,6 +4514,30 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
if (Value *V = SimplifyAddWithRemainder(I))
return replaceInstUsesWith(I, V);
+ Value *V0, *V1;
+ const APFloat *V0Op1, *V1Op1;
+ if (match(Op0, m_SpecificFCmp(FCmpInst::FCMP_OLT, m_Value(V0),
+ m_APFloat(V0Op1))) &&
+ match(Op1, m_SpecificFCmp(FCmpInst::FCMP_OLT, m_Value(V1),
+ m_APFloat(V1Op1)))) {
+ if (V0 == V1) {
+ if (V0Op1 > V1Op1)
+ replaceInstUsesWith(I, Op0);
+ else if (V1Op1 > V0Op1)
+ replaceInstUsesWith(I, Op1);
+ }
+ } else if (match(Op0, m_SpecificFCmp(FCmpInst::FCMP_OGT, m_Value(V0),
+ m_APFloat(V0Op1))) &&
+ match(Op1, m_SpecificFCmp(FCmpInst::FCMP_OGT, m_Value(V1),
+ m_APFloat(V1Op1)))) {
+ if (V0 == V1) {
+ if (V0Op1 < V1Op1)
+ replaceInstUsesWith(I, Op1);
+ else if (V1Op1 < V0Op1)
+ replaceInstUsesWith(I, Op0);
+ }
+ }
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/or-fcmp.ll b/llvm/test/Transforms/InstCombine/or-fcmp.ll
index 193fe4b5cc722..926f66f622914 100644
--- a/llvm/test/Transforms/InstCombine/or-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/or-fcmp.ll
@@ -4657,3 +4657,63 @@ define i1 @or_fcmp_reassoc4(i1 %x, double %a, double %b) {
%retval = or i1 %cmp1, %or
ret i1 %retval
}
+
+define i1 @or_fcmp_redundant1(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant1(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V1:%.*]] = fcmp nsz olt double [[V0]], 1.000000e-02
+; CHECK-NEXT: [[V2:%.*]] = fcmp nsz olt double [[V0]], 1.990000e+00
+; CHECK-NEXT: [[V3:%.*]] = or i1 [[V1]], [[V2]]
+; CHECK-NEXT: ret i1 [[V2]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz olt double %v0, 1.000000e-02
+ %v2 = fcmp nsz olt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
+
+define i1 @or_fcmp_redundant2(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant2(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V1:%.*]] = fcmp nsz olt double [[V0]], 2.300000e+00
+; CHECK-NEXT: [[V2:%.*]] = fcmp nsz olt double [[V0]], 1.990000e+00
+; CHECK-NEXT: [[V3:%.*]] = or i1 [[V1]], [[V2]]
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz olt double %v0, 2.300000e+00
+ %v2 = fcmp nsz olt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
+
+define i1 @or_fcmp_redundant3(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant3(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V1:%.*]] = fcmp nsz ogt double [[V0]], 1.000000e-02
+; CHECK-NEXT: [[V2:%.*]] = fcmp nsz olt double [[V0]], 1.990000e+00
+; CHECK-NEXT: [[V3:%.*]] = or i1 [[V1]], [[V2]]
+; CHECK-NEXT: ret i1 [[V3]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz ogt double %v0, 1.000000e-02
+ %v2 = fcmp nsz olt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
+
+define i1 @or_fcmp_redundant4(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant4(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V1:%.*]] = fcmp nsz ogt double [[V0]], 2.300000e+00
+; CHECK-NEXT: [[V2:%.*]] = fcmp nsz ogt double [[V0]], 1.990000e+00
+; CHECK-NEXT: [[V3:%.*]] = or i1 [[V1]], [[V2]]
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz ogt double %v0, 2.300000e+00
+ %v2 = fcmp nsz ogt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
diff --git a/llvm/test/Transforms/InstCombine/redundant-fcmp.ll b/llvm/test/Transforms/InstCombine/redundant-fcmp.ll
new file mode 100644
index 0000000000000..934d9e6c46507
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/redundant-fcmp.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -O3 -S | FileCheck %s
+
+define i1 @or_fcmp_redundant1(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant1(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V2:%.*]] = fcmp nsz olt double [[V0]], 1.990000e+00
+; CHECK-NEXT: ret i1 [[V2]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz olt double %v0, 1.000000e-02
+ %v2 = fcmp nsz olt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
+
+define i1 @or_fcmp_redundant2(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant2(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V1:%.*]] = fcmp nsz olt double [[V0]], 2.300000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz olt double %v0, 2.300000e+00
+ %v2 = fcmp nsz olt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
+
+define i1 @or_fcmp_redundant3(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant3(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V3:%.*]] = fcmp nsz ogt double [[V0]], 1.990000e+00
+; CHECK-NEXT: ret i1 [[V3]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz ogt double %v0, 1.000000e-02
+ %v2 = fcmp nsz ogt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
+
+define i1 @or_fcmp_redundant4(ptr %arg0) {
+; CHECK-LABEL: @or_fcmp_redundant4(
+; CHECK-NEXT: [[V0:%.*]] = load double, ptr [[ARG0:%.*]], align 8
+; CHECK-NEXT: [[V1:%.*]] = fcmp nsz ogt double [[V0]], 2.300000e+00
+; CHECK-NEXT: ret i1 [[V1]]
+;
+ %v0 = load double, ptr %arg0, align 8
+ %v1 = fcmp nsz ogt double %v0, 2.300000e+00
+ %v2 = fcmp nsz ogt double %v0, 1.990000e+00
+ %v3 = or i1 %v1, %v2
+ ret i1 %v3
+}
More information about the llvm-commits
mailing list