[llvm] [InstCombine] Fold fcmp ogt (x - y), 0 into fcmp ogt x, y #85245 (PR #85506)

via llvm-commits llvm-commits at lists.llvm.org
Sun May 19 20:55:02 PDT 2024


https://github.com/SahilPatidar updated https://github.com/llvm/llvm-project/pull/85506

>From 181932d5c654a6e249e82ea739feaa50c628d537 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Mon, 18 Mar 2024 15:11:30 +0530
Subject: [PATCH 01/16] Added tests to verify fast math flag behavior

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

diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 4d907800219d6..9cdba4678b484 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1718,3 +1718,93 @@ define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2
   %icmp = fcmp nnan une <2 x float> %sel, <float 0.0, float -0.0>
   ret <2 x i1> %icmp
 }
+
+define <8 x i1> @fcmp_vec_ogt_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ogt_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_olt_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_olt_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp olt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_one_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_one_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp one <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_ogt_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ogt_fm_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_olt_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_olt_fm_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp olt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_one_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_one_fm_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp one <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @ffcmp_vec_ogt_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @ffcmp_vec_ogt_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp fast ogt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @ffcmp_vec_olt_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @ffcmp_vec_olt_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp fast olt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @ffcmp_vec_one_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @ffcmp_vec_one_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp fast one <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}

>From 4a7bbc49ecfc2efe2684395bb3ded6ca0d2be317 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Fri, 22 Mar 2024 22:23:05 +0530
Subject: [PATCH 02/16] Modifies code and updates relevant tests

---
 .../InstCombine/InstCombineCompares.cpp       |  31 +++
 llvm/test/Transforms/InstCombine/fcmp.ll      | 198 ++++++++++++++----
 2 files changed, 193 insertions(+), 36 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 7092fb5e509bb..46c656bebc5fc 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8036,6 +8036,37 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
         return replaceOperand(I, 0, X);
       if (Instruction *NV = FoldOpIntoSelect(I, cast<SelectInst>(LHSI)))
         return NV;
+    case Instruction::FSub:
+      switch (Pred) {
+      default:
+        break;
+      case FCmpInst::FCMP_UGT:
+      case FCmpInst::FCMP_ULT:
+      case FCmpInst::FCMP_UNE:
+      case FCmpInst::FCMP_OEQ:
+      case FCmpInst::FCMP_OGE:
+      case FCmpInst::FCMP_OLE: {
+        BinaryOperator *SubI = cast<BinaryOperator>(LHSI);
+        if (!computeKnownFPClass(SubI->getOperand(0), SubI->getFastMathFlags(),
+                                 fcInf, LHSI, 0)
+                 .isKnownNeverInfinity() &&
+            !computeKnownFPClass(SubI->getOperand(1), SubI->getFastMathFlags(),
+                                 fcInf, LHSI, 0)
+                 .isKnownNeverInfinity())
+          break;
+      }
+        LLVM_FALLTHROUGH;
+      case FCmpInst::FCMP_OGT:
+      case FCmpInst::FCMP_OLT:
+      case FCmpInst::FCMP_ONE:
+      case FCmpInst::FCMP_UEQ:
+      case FCmpInst::FCMP_UGE:
+      case FCmpInst::FCMP_ULE:
+        if (match(RHSC, m_AnyZeroFP()) &&
+            match(LHSI, m_FSub(m_Value(X), m_Value(Y))))
+          return new FCmpInst(Pred, X, Y);
+        break;
+      }
       break;
     case Instruction::PHI:
       if (Instruction *NV = foldOpIntoPhi(I, cast<PHINode>(LHSI)))
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 9cdba4678b484..b5093cba98083 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1719,38 +1719,164 @@ define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2
   ret <2 x i1> %icmp
 }
 
-define <8 x i1> @fcmp_vec_ogt_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ogt_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+define i1 @fcmp_oeq_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_oeq_fsub_const(
+; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp oeq float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_oge_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_oge_fsub_const(
+; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp oge float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ole_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ole_fsub_const(
+; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp ole float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ueq_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ueq_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp ueq float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_uge_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_uge_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp uge float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ule_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ule_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp ule float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ugt_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ugt_fsub_const(
+; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp ugt float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_ult_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ult_fsub_const(
+; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp ult float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define i1 @fcmp_une_fsub_const(float %x, float %y) {
+; CHECK-LABEL: @fcmp_une_fsub_const(
+; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  %cmp = fcmp une float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+define <8 x i1> @fcmp_vec_uge_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_uge_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub <8 x float> %x, %y
-  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp uge <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_olt_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_olt_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ule_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ule_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub <8 x float> %x, %y
-  %cmp = fcmp olt <8 x float> %fs, zeroinitializer
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp ule <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_one_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_one_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp one <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ueq_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ueq_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub <8 x float> %x, %y
-  %cmp = fcmp one <8 x float> %fs, zeroinitializer
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp ueq <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ogt_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ogt_fm_fsub_const(
+define <8 x i1> @fcmp_vec_oge_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_oge_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp oge <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_ole_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ole_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp ole <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_oeq_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_oeq_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp oeq <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_vec_ogt_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ogt_fast_fsub_const(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
@@ -1759,8 +1885,8 @@ define <8 x i1> @fcmp_vec_ogt_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_olt_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_olt_fm_fsub_const(
+define <8 x i1> @fcmp_vec_olt_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_olt_fast_fsub_const(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
@@ -1769,8 +1895,8 @@ define <8 x i1> @fcmp_vec_olt_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_one_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_one_fm_fsub_const(
+define <8 x i1> @fcmp_vec_one_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_one_fast_fsub_const(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp one <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
@@ -1779,32 +1905,32 @@ define <8 x i1> @fcmp_vec_one_fm_fsub_const(<8 x float> %x, <8 x float> %y) {
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @ffcmp_vec_ogt_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @ffcmp_vec_ogt_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ugt_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ugt_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub <8 x float> %x, %y
-  %cmp = fcmp fast ogt <8 x float> %fs, zeroinitializer
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp ugt <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @ffcmp_vec_olt_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @ffcmp_vec_olt_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ult_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ult_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub <8 x float> %x, %y
-  %cmp = fcmp fast olt <8 x float> %fs, zeroinitializer
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp ult <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @ffcmp_vec_one_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @ffcmp_vec_one_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp one <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_une_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_une_fast_fsub_const(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp une <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub <8 x float> %x, %y
-  %cmp = fcmp fast one <8 x float> %fs, zeroinitializer
+  %fs = fsub fast <8 x float> %x, %y
+  %cmp = fcmp une <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }

>From 289253bef56af463ccdc8c534fe7008f4350e113 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Wed, 27 Mar 2024 16:18:22 +0530
Subject: [PATCH 03/16] added fmf flag to fcmp

---
 .../InstCombine/InstCombineCompares.cpp       |  2 +-
 llvm/test/Transforms/InstCombine/fcmp.ll      | 96 +++++++++----------
 2 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 46c656bebc5fc..fcba3b72052de 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8064,7 +8064,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_ULE:
         if (match(RHSC, m_AnyZeroFP()) &&
             match(LHSI, m_FSub(m_Value(X), m_Value(Y))))
-          return new FCmpInst(Pred, X, Y);
+          return new FCmpInst(Pred, X, Y, "", &I);
         break;
       }
       break;
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index b5093cba98083..85ca56f687126 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1815,122 +1815,122 @@ define i1 @fcmp_une_fsub_const(float %x, float %y) {
   ret i1 %cmp
 }
 
-define <8 x i1> @fcmp_vec_uge_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_uge_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_uge_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_uge_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast uge <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp uge <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast uge <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ule_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ule_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ule_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ule_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ule <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp ule <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast ule <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ueq_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ueq_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ueq_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ueq_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp ueq <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast ueq <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_oge_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_oge_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_oge_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_oge_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast oge <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp oge <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast oge <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ole_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ole_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ole_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ole_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ole <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp ole <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast ole <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_oeq_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_oeq_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_oeq_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_oeq_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast oeq <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp oeq <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast oeq <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ogt_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ogt_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ogt_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ogt_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ogt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast ogt <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_olt_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_olt_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_olt_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_olt_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp olt <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast olt <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_one_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_one_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp one <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_one_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_one_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast one <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp one <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast one <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ugt_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ugt_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ugt_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ugt_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ugt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp ugt <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast ugt <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ult_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ult_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_ult_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_ult_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ult <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp ult <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast ult <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_une_fast_fsub_const(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_une_fast_fsub_const(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_vec_une_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_vec_une_fsub_const_fmf(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast une <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp une <8 x float> %fs, zeroinitializer
+  %cmp = fcmp fast une <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }

>From 54de4473a5efa08d1332c95ff5424e0fa6cd984e Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 13 Apr 2024 15:10:25 +0530
Subject: [PATCH 04/16] Fix code to handle ninf and nnan

---
 .../InstCombine/InstCombineCompares.cpp       |   8 +-
 llvm/test/Transforms/InstCombine/fcmp.ll      | 244 ++++++++++++++----
 2 files changed, 190 insertions(+), 62 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index fcba3b72052de..b2b0f449ba187 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8047,12 +8047,8 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE: {
         BinaryOperator *SubI = cast<BinaryOperator>(LHSI);
-        if (!computeKnownFPClass(SubI->getOperand(0), SubI->getFastMathFlags(),
-                                 fcInf, LHSI, 0)
-                 .isKnownNeverInfinity() &&
-            !computeKnownFPClass(SubI->getOperand(1), SubI->getFastMathFlags(),
-                                 fcInf, LHSI, 0)
-                 .isKnownNeverInfinity())
+        if (!isKnownNeverInfOrNaN(SubI->getOperand(0), 0, SQ) &&
+            !isKnownNeverInfOrNaN(SubI->getOperand(1), 0, SQ))
           break;
       }
         LLVM_FALLTHROUGH;
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 85ca56f687126..cdaa1e2775f56 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1815,109 +1815,240 @@ define i1 @fcmp_une_fsub_const(float %x, float %y) {
   ret i1 %cmp
 }
 
-define <8 x i1> @fcmp_vec_uge_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_uge_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast uge <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_uge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_uge_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf uge <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast uge <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf uge <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ule_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ule_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ule <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_ule_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ule_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ule <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast ule <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf ule <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ueq_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ueq_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ueq <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_ueq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ueq_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ueq <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast ueq <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf ueq <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_oge_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_oge_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast oge <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_oge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_oge_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oge <8 x float> [[FS]], zeroinitializer
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast oge <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf oge <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ole_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ole_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ole <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_ole_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ole_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ole <8 x float> [[FS]], zeroinitializer
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast ole <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf ole <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_oeq_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_oeq_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast oeq <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_oeq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_oeq_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq <8 x float> [[FS]], zeroinitializer
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast oeq <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf oeq <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ogt_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ogt_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_ogt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ogt_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ogt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast ogt <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf ogt <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_olt_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_olt_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_olt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_olt_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf olt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast olt <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf olt <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_one_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_one_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast one <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_one_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_one_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf one <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast one <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf one <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ugt_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ugt_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ugt <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_ugt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ugt_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ugt <8 x float> [[FS]], zeroinitializer
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast ugt <8 x float> %fs, zeroinitializer
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf ugt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ult_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ult_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ult <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf ult <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_une_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_une_fsub_const_ninf_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub ninf <8 x float> %x, %y
+  %cmp = fcmp ninf une <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_uge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_uge_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan uge <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan uge <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ule_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ule_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ule <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan ule <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ueq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ueq_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ueq <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan ueq <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_oge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_oge_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oge <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan oge <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ole_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ole_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ole <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan ole <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_oeq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_oeq_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oeq <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan oeq <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ogt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ogt_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ogt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan ogt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_olt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_olt_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan olt <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan olt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_one_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_one_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan one <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan one <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ugt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ugt_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ugt <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan ugt <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_ult_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_ult_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ult <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_ult_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_ult_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub fast <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ult <8 x float> [[FS]], zeroinitializer
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y
@@ -1925,9 +2056,10 @@ define <8 x i1> @fcmp_vec_ult_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_vec_une_fsub_const_fmf(<8 x float> %x, <8 x float> %y) {
-; CHECK-LABEL: @fcmp_vec_une_fsub_const_fmf(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast une <8 x float> [[X:%.*]], [[Y:%.*]]
+define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
+; CHECK-LABEL: @fcmp_une_fsub_const_nnan_vec(
+; CHECK-NEXT:    [[FS:%.*]] = fsub fast <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast une <8 x float> [[FS]], zeroinitializer
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub fast <8 x float> %x, %y

>From bf21f858fbddc8457bde60bec78bc8beac439caf Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Wed, 17 Apr 2024 15:06:58 +0530
Subject: [PATCH 05/16] fix: Handle ninf values (update test)

---
 .../InstCombine/InstCombineCompares.cpp       | 15 ++++---
 llvm/test/Transforms/InstCombine/fcmp.ll      | 44 +++++++------------
 2 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index b2b0f449ba187..639151c0f9984 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8046,9 +8046,11 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE: {
-        BinaryOperator *SubI = cast<BinaryOperator>(LHSI);
-        if (!isKnownNeverInfOrNaN(SubI->getOperand(0), 0, SQ) &&
-            !isKnownNeverInfOrNaN(SubI->getOperand(1), 0, SQ))
+        if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
+            !isKnownNeverInfinity(LHSI->getOperand(0), /*Depth=*/0,
+                                  getSimplifyQuery().getWithInstruction(&I)) &&
+            !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
+                                  getSimplifyQuery().getWithInstruction(&I)))
           break;
       }
         LLVM_FALLTHROUGH;
@@ -8059,8 +8061,11 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_UGE:
       case FCmpInst::FCMP_ULE:
         if (match(RHSC, m_AnyZeroFP()) &&
-            match(LHSI, m_FSub(m_Value(X), m_Value(Y))))
-          return new FCmpInst(Pred, X, Y, "", &I);
+            match(LHSI, m_FSub(m_Value(X), m_Value(Y)))) {
+          replaceOperand(I, 0, X);
+          replaceOperand(I, 1, Y);
+          return &I;
+        }
         break;
       }
       break;
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index cdaa1e2775f56..bd4f8a56069d7 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1847,8 +1847,7 @@ define <8 x i1> @fcmp_ueq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_oge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_oge_fsub_const_ninf_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oge <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oge <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub ninf <8 x float> %x, %y
@@ -1858,8 +1857,7 @@ define <8 x i1> @fcmp_oge_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_ole_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_ole_fsub_const_ninf_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ole <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ole <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub ninf <8 x float> %x, %y
@@ -1869,8 +1867,7 @@ define <8 x i1> @fcmp_ole_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_oeq_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_oeq_fsub_const_ninf_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub ninf <8 x float> %x, %y
@@ -1910,8 +1907,7 @@ define <8 x i1> @fcmp_one_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_ugt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_ugt_fsub_const_ninf_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ugt <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ugt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub ninf <8 x float> %x, %y
@@ -1921,8 +1917,7 @@ define <8 x i1> @fcmp_ugt_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_ult_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_ult_fsub_const_ninf_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ult <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf ult <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub ninf <8 x float> %x, %y
@@ -1932,8 +1927,7 @@ define <8 x i1> @fcmp_ult_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_une_fsub_const_ninf_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_une_fsub_const_ninf_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub ninf <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf une <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub ninf <8 x float> %x, %y
@@ -1973,8 +1967,7 @@ define <8 x i1> @fcmp_ueq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_oge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_oge_fsub_const_nnan_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oge <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oge <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub nnan <8 x float> %x, %y
@@ -1984,8 +1977,7 @@ define <8 x i1> @fcmp_oge_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_ole_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_ole_fsub_const_nnan_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ole <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ole <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub nnan <8 x float> %x, %y
@@ -1995,8 +1987,7 @@ define <8 x i1> @fcmp_ole_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_oeq_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_oeq_fsub_const_nnan_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oeq <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan oeq <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub nnan <8 x float> %x, %y
@@ -2036,8 +2027,7 @@ define <8 x i1> @fcmp_one_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_ugt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_ugt_fsub_const_nnan_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub nnan <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ugt <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ugt <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
   %fs = fsub nnan <8 x float> %x, %y
@@ -2047,22 +2037,20 @@ define <8 x i1> @fcmp_ugt_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 
 define <8 x i1> @fcmp_ult_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_ult_fsub_const_nnan_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub fast <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast ult <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ult <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast ult <8 x float> %fs, zeroinitializer
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan ult <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
 
 define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
 ; CHECK-LABEL: @fcmp_une_fsub_const_nnan_vec(
-; CHECK-NEXT:    [[FS:%.*]] = fsub fast <8 x float> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast une <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan une <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret <8 x i1> [[CMP]]
 ;
-  %fs = fsub fast <8 x float> %x, %y
-  %cmp = fcmp fast une <8 x float> %fs, zeroinitializer
+  %fs = fsub nnan <8 x float> %x, %y
+  %cmp = fcmp nnan une <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }

>From 386e7c8e2941a39dd7ea8d11e3b8362e59116686 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Thu, 25 Apr 2024 11:47:03 +0530
Subject: [PATCH 06/16] adds test and update to check denormals being flushed

---
 .../InstCombine/InstCombineCompares.cpp       |  9 ++-
 llvm/test/Transforms/InstCombine/fcmp.ll      | 61 ++++++++++++++-----
 2 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 639151c0f9984..df5cc8636f777 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8047,9 +8047,9 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE: {
         if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
-            !isKnownNeverInfinity(LHSI->getOperand(0), /*Depth=*/0,
-                                  getSimplifyQuery().getWithInstruction(&I)) &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
+                                  getSimplifyQuery().getWithInstruction(&I)) &&
+            !isKnownNeverInfinity(LHSI->getOperand(0), /*Depth=*/0,
                                   getSimplifyQuery().getWithInstruction(&I)))
           break;
       }
@@ -8061,7 +8061,10 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_UGE:
       case FCmpInst::FCMP_ULE:
         if (match(RHSC, m_AnyZeroFP()) &&
-            match(LHSI, m_FSub(m_Value(X), m_Value(Y)))) {
+            match(LHSI, m_FSub(m_Value(X), m_Value(Y))) &&
+            I.getFunction()->getDenormalMode(
+                LHSI->getType()->getScalarType()->getFltSemantics()) ==
+                DenormalMode::getIEEE()) {
           replaceOperand(I, 0, X);
           replaceOperand(I, 1, Y);
           return &I;
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index bd4f8a56069d7..cffa31e0afbe0 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1289,7 +1289,7 @@ define <1 x i1> @bitcast_1vec_eq0(i32 %x) {
 
 define i1 @fcmp_fadd_zero_ugt(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_ugt(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1299,7 +1299,7 @@ define i1 @fcmp_fadd_zero_ugt(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_uge(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_uge(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1309,7 +1309,7 @@ define i1 @fcmp_fadd_zero_uge(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_ogt(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_ogt(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1319,7 +1319,7 @@ define i1 @fcmp_fadd_zero_ogt(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_oge(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_oge(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1329,7 +1329,7 @@ define i1 @fcmp_fadd_zero_oge(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_ult(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_ult(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1339,7 +1339,7 @@ define i1 @fcmp_fadd_zero_ult(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_ule(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_ule(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1349,7 +1349,7 @@ define i1 @fcmp_fadd_zero_ule(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_olt(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_olt(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1359,7 +1359,7 @@ define i1 @fcmp_fadd_zero_olt(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_ole(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_ole(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1369,7 +1369,7 @@ define i1 @fcmp_fadd_zero_ole(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_oeq(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_oeq(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1379,7 +1379,7 @@ define i1 @fcmp_fadd_zero_oeq(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_one(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_one(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1389,7 +1389,7 @@ define i1 @fcmp_fadd_zero_one(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_ueq(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_ueq(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1399,7 +1399,7 @@ define i1 @fcmp_fadd_zero_ueq(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_une(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_une(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1409,7 +1409,7 @@ define i1 @fcmp_fadd_zero_une(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_ord(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_ord(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -1419,7 +1419,7 @@ define i1 @fcmp_fadd_zero_ord(float %x, float %y) {
 
 define i1 @fcmp_fadd_zero_uno(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_fadd_zero_uno(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[ADD:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %add = fadd float %x, 0.000000e+00
@@ -2054,3 +2054,36 @@ define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
   %cmp = fcmp nnan une <8 x float> %fs, zeroinitializer
   ret <8 x i1> %cmp
 }
+
+define <8 x i1> @fcmp_ugt_fsub_const_vec_denormal_positive-zero(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="positive-zero" {
+; CHECK-LABEL: @fcmp_ugt_fsub_const_vec_denormal_positive-zero(
+; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_dynamic(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="dynamic,dynamic" {
+; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_dynamic(
+; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}
+
+define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="preserve-sign" {
+; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(
+; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[CMP]]
+;
+  %fs = fsub <8 x float> %x, %y
+  %cmp = fcmp ogt <8 x float> %fs, zeroinitializer
+  ret <8 x i1> %cmp
+}

>From 366187752e3af7d0a11c56ac92c221d0408f6685 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Thu, 9 May 2024 09:45:53 +0530
Subject: [PATCH 07/16] minor fixes

---
 llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 9 ++++++---
 llvm/test/Transforms/InstCombine/fcmp.ll                | 4 ++--
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index df5cc8636f777..baf8c35f94fba 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8036,6 +8036,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
         return replaceOperand(I, 0, X);
       if (Instruction *NV = FoldOpIntoSelect(I, cast<SelectInst>(LHSI)))
         return NV;
+      break;
     case Instruction::FSub:
       switch (Pred) {
       default:
@@ -8045,21 +8046,23 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_UNE:
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OGE:
-      case FCmpInst::FCMP_OLE: {
+      case FCmpInst::FCMP_OLE:
+        // fsub x, y --> isnnan(x, y) && isninf(x, y)
         if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
                                   getSimplifyQuery().getWithInstruction(&I)) &&
             !isKnownNeverInfinity(LHSI->getOperand(0), /*Depth=*/0,
                                   getSimplifyQuery().getWithInstruction(&I)))
           break;
-      }
-        LLVM_FALLTHROUGH;
+
+        [[fallthrough]];
       case FCmpInst::FCMP_OGT:
       case FCmpInst::FCMP_OLT:
       case FCmpInst::FCMP_ONE:
       case FCmpInst::FCMP_UEQ:
       case FCmpInst::FCMP_UGE:
       case FCmpInst::FCMP_ULE:
+        // fcmp pred (x - y), 0 --> fcmp pred x, y
         if (match(RHSC, m_AnyZeroFP()) &&
             match(LHSI, m_FSub(m_Value(X), m_Value(Y))) &&
             I.getFunction()->getDenormalMode(
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index cffa31e0afbe0..1f7b3fca0b00e 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -2055,7 +2055,7 @@ define <8 x i1> @fcmp_une_fsub_const_nnan_vec(<8 x float> %x, <8 x float> %y) {
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_ugt_fsub_const_vec_denormal_positive-zero(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="positive-zero" {
+define <8 x i1> @fcmp_ugt_fsub_const_vec_denormal_positive-zero(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="positive-zero,positive-zero" {
 ; CHECK-LABEL: @fcmp_ugt_fsub_const_vec_denormal_positive-zero(
 ; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer
@@ -2077,7 +2077,7 @@ define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_dynamic(<8 x float> %x, <8 x f
   ret <8 x i1> %cmp
 }
 
-define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="preserve-sign" {
+define <8 x i1> @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(<8 x float> %x, <8 x float> %y) "denormal-fp-math"="preserve-sign,preserve-sign" {
 ; CHECK-LABEL: @fcmp_ogt_fsub_const_vec_denormal_preserve-sign(
 ; CHECK-NEXT:    [[FS:%.*]] = fsub <8 x float> [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt <8 x float> [[FS]], zeroinitializer

>From 148d7898368513ea8a83316c4e414c0e96737d38 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 11 May 2024 11:11:10 +0530
Subject: [PATCH 08/16] fixes comment

---
 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 baf8c35f94fba..8f0c1b3b2dd33 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8047,7 +8047,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE:
-        // fsub x, y --> isnnan(x, y) && isninf(x, y)
+        // Skip optimization: fsub x, y guaranteed isInf(x, y).
         if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
                                   getSimplifyQuery().getWithInstruction(&I)) &&

>From cc551c0f3bed7f7d1dce78276eb9d73d7a9bfec0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <arsenm2 at gmail.com>
Date: Mon, 13 May 2024 11:48:33 +0200
Subject: [PATCH 09/16] Comment touchup

---
 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 8f0c1b3b2dd33..b946eaaa7d2f3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8047,7 +8047,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE:
-        // Skip optimization: fsub x, y guaranteed isInf(x, y).
+        // Skip optimization: fsub x, y unless guaranteed !isinf(x) && !isinf(y).
         if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
                                   getSimplifyQuery().getWithInstruction(&I)) &&

>From 285ccde1fc1b0649b94448c8c3920f57db6895c2 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <arsenm2 at gmail.com>
Date: Mon, 13 May 2024 11:53:59 +0200
Subject: [PATCH 10/16] Fix clang-format error

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

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index b946eaaa7d2f3..ae994aae2a72f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8047,7 +8047,8 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE:
-        // Skip optimization: fsub x, y unless guaranteed !isinf(x) && !isinf(y).
+        // Skip optimization: fsub x, y unless guaranteed !isinf(x) && 
+        // !isinf(y).
         if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
                                   getSimplifyQuery().getWithInstruction(&I)) &&

>From 6df144fd73e3c747a07071eb7c063f4009b7b040 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <arsenm2 at gmail.com>
Date: Mon, 13 May 2024 12:00:54 +0200
Subject: [PATCH 11/16] or not and

Co-authored-by: Jay Foad <jay.foad at gmail.com>
---
 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 ae994aae2a72f..2ef1bc2fae671 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8047,7 +8047,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE:
-        // Skip optimization: fsub x, y unless guaranteed !isinf(x) && 
+        // Skip optimization: fsub x, y unless guaranteed !isinf(x) || 
         // !isinf(y).
         if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,

>From b41b8cac0c8e4c1526a1a35de38ff4760f38b1b9 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <arsenm2 at gmail.com>
Date: Mon, 13 May 2024 12:05:13 +0200
Subject: [PATCH 12/16] whitespace

---
 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 2ef1bc2fae671..df6bd688f3bbb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8047,7 +8047,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OEQ:
       case FCmpInst::FCMP_OGE:
       case FCmpInst::FCMP_OLE:
-        // Skip optimization: fsub x, y unless guaranteed !isinf(x) || 
+        // Skip optimization: fsub x, y unless guaranteed !isinf(x) ||
         // !isinf(y).
         if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,

>From 4ae679a0eb05289c3d2e0f60b79aada1dd8d2ef7 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Thu, 16 May 2024 14:25:23 +0530
Subject: [PATCH 13/16] add one use check

---
 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 df6bd688f3bbb..46f2222ed7244 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8065,7 +8065,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_ULE:
         // fcmp pred (x - y), 0 --> fcmp pred x, y
         if (match(RHSC, m_AnyZeroFP()) &&
-            match(LHSI, m_FSub(m_Value(X), m_Value(Y))) &&
+            match(LHSI, m_OneUse(m_FSub(m_Value(X), m_Value(Y)))) &&
             I.getFunction()->getDenormalMode(
                 LHSI->getType()->getScalarType()->getFltSemantics()) ==
                 DenormalMode::getIEEE()) {

>From 2166030412d3d6d34eb81b957278cecda54c6cff Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Thu, 16 May 2024 14:35:31 +0530
Subject: [PATCH 14/16] adds negative test

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

diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 1f7b3fca0b00e..b43479010062e 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1719,6 +1719,21 @@ define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2
   ret <2 x i1> %icmp
 }
 
+; negative test - extra use
+
+define i1 @fcmp_ueq_fsub_const_extra_use(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ueq_fsub_const_extra_use(
+; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use(float [[FS]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub float %x, %y
+  call void @use(float %fs)
+  %cmp = fcmp ueq float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
 define i1 @fcmp_oeq_fsub_const(float %x, float %y) {
 ; CHECK-LABEL: @fcmp_oeq_fsub_const(
 ; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]

>From ba8cbcb4bc2fa32910449d1ade26752d94e8d864 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Fri, 17 May 2024 11:21:17 +0530
Subject: [PATCH 15/16] adds negative tests

---
 .../InstCombine/InstCombineCompares.cpp       |  4 +--
 llvm/test/Transforms/InstCombine/fcmp.ll      | 27 ++++++++++++++-----
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 46f2222ed7244..1a87baaf27aad 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8049,11 +8049,11 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OLE:
         // Skip optimization: fsub x, y unless guaranteed !isinf(x) ||
         // !isinf(y).
-        if (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
+        if (!LHSI->hasOneUse() || (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
                                   getSimplifyQuery().getWithInstruction(&I)) &&
             !isKnownNeverInfinity(LHSI->getOperand(0), /*Depth=*/0,
-                                  getSimplifyQuery().getWithInstruction(&I)))
+                                  getSimplifyQuery().getWithInstruction(&I))))
           break;
 
         [[fallthrough]];
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index b43479010062e..656b3d2c49206 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1721,16 +1721,31 @@ define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2
 
 ; negative test - extra use
 
-define i1 @fcmp_ueq_fsub_const_extra_use(float %x, float %y) {
-; CHECK-LABEL: @fcmp_ueq_fsub_const_extra_use(
-; CHECK-NEXT:    [[FS:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
+define i1 @fcmp_ueq_fsub_nnan_const_extra_use(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ueq_fsub_nnan_const_extra_use(
+; CHECK-NEXT:    [[FS:%.*]] = fsub nnan float [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(float [[FS]])
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[FS]], 0.000000e+00
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ueq float [[FS]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
-  %fs = fsub float %x, %y
+  %fs = fsub nnan float %x, %y
   call void @use(float %fs)
-  %cmp = fcmp ueq float %fs, 0.000000e+00
+  %cmp = fcmp nnan ueq float %fs, 0.000000e+00
+  ret i1 %cmp
+}
+
+; negative test - extra use
+
+define i1 @fcmp_oeq_fsub_ninf_const_extra_use(float %x, float %y) {
+; CHECK-LABEL: @fcmp_oeq_fsub_ninf_const_extra_use(
+; CHECK-NEXT:    [[FS:%.*]] = fsub ninf float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use(float [[FS]])
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ninf oeq float [[FS]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %fs = fsub ninf float %x, %y
+  call void @use(float %fs)
+  %cmp = fcmp ninf oeq float %fs, 0.000000e+00
   ret i1 %cmp
 }
 

>From fb137e486cbec4c392e7a2ff5b93bd498c923076 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Mon, 20 May 2024 09:23:38 +0530
Subject: [PATCH 16/16] Fixes clang-format

---
 .../Transforms/InstCombine/InstCombineCompares.cpp    | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 1a87baaf27aad..0c697f461eb4c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8049,11 +8049,12 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
       case FCmpInst::FCMP_OLE:
         // Skip optimization: fsub x, y unless guaranteed !isinf(x) ||
         // !isinf(y).
-        if (!LHSI->hasOneUse() || (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
-            !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
-                                  getSimplifyQuery().getWithInstruction(&I)) &&
-            !isKnownNeverInfinity(LHSI->getOperand(0), /*Depth=*/0,
-                                  getSimplifyQuery().getWithInstruction(&I))))
+        if (!LHSI->hasOneUse() ||
+            (!LHSI->hasNoNaNs() && !LHSI->hasNoInfs() &&
+             !isKnownNeverInfinity(LHSI->getOperand(1), /*Depth=*/0,
+                                   getSimplifyQuery().getWithInstruction(&I)) &&
+             !isKnownNeverInfinity(LHSI->getOperand(0), /*Depth=*/0,
+                                   getSimplifyQuery().getWithInstruction(&I))))
           break;
 
         [[fallthrough]];



More information about the llvm-commits mailing list