[llvm] [InstCombine] fold `cond ? x : -x == 0` into `x == 0` (PR #85673)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 18 23:57:02 PDT 2024


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

>From 1f530c9d8e0453759b8846b3142afe47f7d3ab80 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Mon, 18 Mar 2024 09:32:59 +0530
Subject: [PATCH 1/6] [InstCombine] FP fold, cond ? x : -x == 0 into x == 0
 #85250

---
 .../InstCombine/InstCombineCompares.cpp       |   7 ++
 llvm/test/Transforms/InstCombine/fcmp.ll      | 107 ++++++++++++++++++
 2 files changed, 114 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index fdadf729fbd541..7dea1b490acce0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8045,6 +8045,13 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
   Constant *RHSC;
   if (match(Op0, m_Instruction(LHSI)) && match(Op1, m_Constant(RHSC))) {
     switch (LHSI->getOpcode()) {
+    case Instruction::Select:
+      if ((Pred == FCmpInst::FCMP_UEQ || Pred == FCmpInst::FCMP_OEQ ||
+           Pred == FCmpInst::FCMP_UNE || Pred == FCmpInst::FCMP_ONE) &&
+          match(LHSI, m_Select(m_Value(), m_Value(X), m_FNeg(m_Value(Y)))) &&
+          X == Y && match(RHSC, m_AnyZeroFP()))
+        return new FCmpInst(Pred, X, RHSC);
+      break;
     case Instruction::PHI:
       if (Instruction *NV = foldOpIntoPhi(I, cast<PHINode>(LHSI)))
         return NV;
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 389264e2f70759..9b91b1ec9b90e8 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1486,3 +1486,110 @@ define i1 @fcmp_fadd_fast_zero(float %x, float %y) {
   %cmp = fcmp ugt float %add, %y
   ret i1 %cmp
 }
+
+define i1 @fcmp_ueq_sel_x_negx(float %x) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp ueq float %x, 0.000000e+00
+  %neg = fneg fast float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp ueq float %sel, 0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_une_sel_x_negx(float %x) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp une float %x, 0.000000e+00
+  %neg = fneg fast float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp une float %sel, 0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_oeq_sel_x_negx(float %x) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp oeq float %x, 0.000000e+00
+  %neg = fneg fast float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp oeq float %sel, 0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_one_sel_x_negx(float %x) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp one float %x, 0.000000e+00
+  %neg = fneg fast float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp one float %sel, 0.000000e+00
+  ret i1 %res
+}
+
+define <8 x i1> @fcmp_ueq_sel_x_negx_vec(<8 x float> %x) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx_vec(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq <8 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[RES]]
+;
+  %f = fcmp ueq <8 x float> %x, zeroinitializer
+  %neg = fneg fast <8 x float> %x
+  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
+  %res = fcmp ueq <8 x float> %sel, zeroinitializer
+  ret <8 x i1> %res
+}
+
+define <8 x i1> @fcmp_une_sel_x_negx_vec(<8 x float> %x) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx_vec(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp une <8 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[RES]]
+;
+  %f = fcmp une <8 x float> %x, zeroinitializer
+  %neg = fneg fast <8 x float> %x
+  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
+  %res = fcmp une <8 x float> %sel, zeroinitializer
+  ret <8 x i1> %res
+}
+
+define <8 x i1> @fcmp_oeq_sel_x_negx_vec(<8 x float> %x) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx_vec(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq <8 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[RES]]
+;
+  %f = fcmp oeq <8 x float> %x, zeroinitializer
+  %neg = fneg fast <8 x float> %x
+  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
+  %res = fcmp oeq <8 x float> %sel, zeroinitializer
+  ret <8 x i1> %res
+}
+
+define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx_vec(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp one <8 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <8 x i1> [[RES]]
+;
+  %f = fcmp one <8 x float> %x, zeroinitializer
+  %neg = fneg fast <8 x float> %x
+  %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
+  %res = fcmp one <8 x float> %sel, zeroinitializer
+  ret <8 x i1> %res
+}
+
+define i1 @fcmp_sel_x_negx_with_any_cond(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_sel_x_negx_with_any_cond(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp ueq float %sel, 0.000000e+00
+  ret i1 %res
+}

>From dd50785ca6cd17ec749b6d64fd358c5ebc3ee8ec Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 23 Mar 2024 17:10:57 +0530
Subject: [PATCH 2/6] Fixes and updates tests

---
 .../InstCombine/InstCombineCompares.cpp       | 10 +--
 llvm/test/Transforms/InstCombine/fcmp.ll      | 64 ++++++++++++++++---
 2 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 7dea1b490acce0..22a6848e907278 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8046,11 +8046,11 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
   if (match(Op0, m_Instruction(LHSI)) && match(Op1, m_Constant(RHSC))) {
     switch (LHSI->getOpcode()) {
     case Instruction::Select:
-      if ((Pred == FCmpInst::FCMP_UEQ || Pred == FCmpInst::FCMP_OEQ ||
-           Pred == FCmpInst::FCMP_UNE || Pred == FCmpInst::FCMP_ONE) &&
-          match(LHSI, m_Select(m_Value(), m_Value(X), m_FNeg(m_Value(Y)))) &&
-          X == Y && match(RHSC, m_AnyZeroFP()))
-        return new FCmpInst(Pred, X, RHSC);
+      if (FCmpInst::isEquality(Pred) && match(RHSC, m_AnyZeroFP()) &&
+          (match(LHSI,
+                 m_Select(m_Value(), m_Value(X), m_FNeg(m_Deferred(X)))) ||
+           match(LHSI, m_Select(m_Value(), m_FNeg(m_Value(X)), m_Deferred(X)))))
+        return new FCmpInst(Pred, X, RHSC, "", &I);
       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 9b91b1ec9b90e8..88614700246533 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1493,7 +1493,7 @@ define i1 @fcmp_ueq_sel_x_negx(float %x) {
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %f = fcmp ueq float %x, 0.000000e+00
-  %neg = fneg fast float %x
+  %neg = fneg float %x
   %sel = select i1 %f, float %x, float %neg
   %res = fcmp ueq float %sel, 0.000000e+00
   ret i1 %res
@@ -1505,7 +1505,7 @@ define i1 @fcmp_une_sel_x_negx(float %x) {
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %f = fcmp une float %x, 0.000000e+00
-  %neg = fneg fast float %x
+  %neg = fneg float %x
   %sel = select i1 %f, float %x, float %neg
   %res = fcmp une float %sel, 0.000000e+00
   ret i1 %res
@@ -1517,7 +1517,7 @@ define i1 @fcmp_oeq_sel_x_negx(float %x) {
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %f = fcmp oeq float %x, 0.000000e+00
-  %neg = fneg fast float %x
+  %neg = fneg float %x
   %sel = select i1 %f, float %x, float %neg
   %res = fcmp oeq float %sel, 0.000000e+00
   ret i1 %res
@@ -1529,19 +1529,67 @@ define i1 @fcmp_one_sel_x_negx(float %x) {
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %f = fcmp one float %x, 0.000000e+00
-  %neg = fneg fast float %x
+  %neg = fneg float %x
   %sel = select i1 %f, float %x, float %neg
   %res = fcmp one float %sel, 0.000000e+00
   ret i1 %res
 }
 
+define i1 @fcmp_ueq_sel_x_negx_nzero(float %x) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx_nzero(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp ueq float %x, 0.000000e+00
+  %neg = fneg float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp ueq float %sel, -0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_une_sel_x_negx_nzero(float %x) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx_nzero(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp une float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp une float %x, 0.000000e+00
+  %neg = fneg float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp une float %sel, -0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_oeq_sel_x_negx_nzero(float %x) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx_nzero(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp oeq float %x, 0.000000e+00
+  %neg = fneg float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp oeq float %sel, -0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_one_sel_x_negx_nzero(float %x) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx_nzero(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp one float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %f = fcmp one float %x, 0.000000e+00
+  %neg = fneg float %x
+  %sel = select i1 %f, float %x, float %neg
+  %res = fcmp one float %sel, -0.000000e+00
+  ret i1 %res
+}
+
 define <8 x i1> @fcmp_ueq_sel_x_negx_vec(<8 x float> %x) {
 ; CHECK-LABEL: @fcmp_ueq_sel_x_negx_vec(
 ; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq <8 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
 ;
   %f = fcmp ueq <8 x float> %x, zeroinitializer
-  %neg = fneg fast <8 x float> %x
+  %neg = fneg <8 x float> %x
   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
   %res = fcmp ueq <8 x float> %sel, zeroinitializer
   ret <8 x i1> %res
@@ -1553,7 +1601,7 @@ define <8 x i1> @fcmp_une_sel_x_negx_vec(<8 x float> %x) {
 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
 ;
   %f = fcmp une <8 x float> %x, zeroinitializer
-  %neg = fneg fast <8 x float> %x
+  %neg = fneg <8 x float> %x
   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
   %res = fcmp une <8 x float> %sel, zeroinitializer
   ret <8 x i1> %res
@@ -1565,7 +1613,7 @@ define <8 x i1> @fcmp_oeq_sel_x_negx_vec(<8 x float> %x) {
 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
 ;
   %f = fcmp oeq <8 x float> %x, zeroinitializer
-  %neg = fneg fast <8 x float> %x
+  %neg = fneg <8 x float> %x
   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
   %res = fcmp oeq <8 x float> %sel, zeroinitializer
   ret <8 x i1> %res
@@ -1577,7 +1625,7 @@ define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) {
 ; CHECK-NEXT:    ret <8 x i1> [[RES]]
 ;
   %f = fcmp one <8 x float> %x, zeroinitializer
-  %neg = fneg fast <8 x float> %x
+  %neg = fneg <8 x float> %x
   %sel = select <8 x i1> %f, <8 x float> %x, <8 x float> %neg
   %res = fcmp one <8 x float> %sel, zeroinitializer
   ret <8 x i1> %res

>From a5d953d73104af724a2508544b19b78b7bc33811 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Tue, 26 Mar 2024 15:34:41 +0530
Subject: [PATCH 3/6] Add and update tests for any fp zero

---
 .../InstCombine/InstCombineCompares.cpp       |  1 +
 llvm/test/Transforms/InstCombine/fcmp.ll      | 85 ++++++++++++++++++-
 2 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 22a6848e907278..bdfc96fc20f44e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8046,6 +8046,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
   if (match(Op0, m_Instruction(LHSI)) && match(Op1, m_Constant(RHSC))) {
     switch (LHSI->getOpcode()) {
     case Instruction::Select:
+      // fcmp eq (cond ? x : -x), 0 --> fcmp eq x, 0
       if (FCmpInst::isEquality(Pred) && match(RHSC, m_AnyZeroFP()) &&
           (match(LHSI,
                  m_Select(m_Value(), m_Value(X), m_FNeg(m_Deferred(X)))) ||
diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 88614700246533..6d16be5ece53ce 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1631,13 +1631,90 @@ define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) {
   ret <8 x i1> %res
 }
 
-define i1 @fcmp_sel_x_negx_with_any_cond(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_sel_x_negx_with_any_cond(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp ueq float [[X:%.*]], 0.000000e+00
+define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
+;
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp oeq <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
+}
+
+define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp one <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
+;
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp one <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
+}
+
+define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ueq <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
+;
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp ueq <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
+}
+
+define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp une <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
+;
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp une <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
+}
+
+define i1 @fcmp_ueq_sel_x_negx_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast ueq float [[X:%.*]], 0.000000e+00
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %neg = fneg float %x
   %sel = select i1 %c, float %x, float %neg
-  %res = fcmp ueq float %sel, 0.000000e+00
+  %res = fcmp fast ueq float %sel, 0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_une_sel_x_negx_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast une float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp fast une float %sel, 0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_oeq_sel_x_negx_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp fast oeq float %sel, 0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_one_sel_x_negx_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast one float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp fast one float %sel, 0.000000e+00
   ret i1 %res
 }

>From e62038edbc6bb6c8d74e60814a42e8f5020a052a Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Tue, 9 Apr 2024 14:53:46 +0530
Subject: [PATCH 4/6] add and update fmf tests

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

diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 6d16be5ece53ce..0a2f13e1ae67e8 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1718,3 +1718,47 @@ define i1 @fcmp_one_sel_x_negx_with_fmf(float %x, i1 %c) {
   %res = fcmp fast one float %sel, 0.000000e+00
   ret i1 %res
 }
+
+define i1 @fcmp_ueq_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx_nzero_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast ueq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp fast ueq float %sel, -0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_une_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx_nzero_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast une float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp fast une float %sel, -0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_oeq_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx_nzero_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast oeq float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp fast oeq float %sel, -0.000000e+00
+  ret i1 %res
+}
+
+define i1 @fcmp_one_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx_nzero_with_fmf(
+; CHECK-NEXT:    [[RES:%.*]] = fcmp fast one float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %neg = fneg float %x
+  %sel = select i1 %c, float %x, float %neg
+  %res = fcmp fast one float %sel, -0.000000e+00
+  ret i1 %res
+}

>From 785fe715a9344e7facebb00dc67b10631a84a542 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Sat, 13 Apr 2024 14:11:09 +0530
Subject: [PATCH 5/6] update test with ninf and nnan flag

---
 llvm/test/Transforms/InstCombine/fcmp.ll | 140 ++++++++---------------
 1 file changed, 48 insertions(+), 92 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/fcmp.ll b/llvm/test/Transforms/InstCombine/fcmp.ll
index 0a2f13e1ae67e8..4d907800219d63 100644
--- a/llvm/test/Transforms/InstCombine/fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp.ll
@@ -1631,134 +1631,90 @@ define <8 x i1> @fcmp_one_sel_x_negx_vec(<8 x float> %x) {
   ret <8 x i1> %res
 }
 
-define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
-; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_vec(
-; CHECK-NEXT:    [[ICMP:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer
+define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_ninf_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf oeq <2 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
   %fneg = fneg <2 x float> %x
   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
-  %icmp = fcmp oeq <2 x float> %sel, <float 0.0, float -0.0>
+  %icmp = fcmp ninf oeq <2 x float> %sel, <float 0.0, float -0.0>
   ret <2 x i1> %icmp
 }
 
-define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
-; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_vec(
-; CHECK-NEXT:    [[ICMP:%.*]] = fcmp one <2 x float> [[X:%.*]], zeroinitializer
+define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_ninf_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf one <2 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
   %fneg = fneg <2 x float> %x
   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
-  %icmp = fcmp one <2 x float> %sel, <float 0.0, float -0.0>
+  %icmp = fcmp ninf one <2 x float> %sel, <float 0.0, float -0.0>
   ret <2 x i1> %icmp
 }
 
-define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
-; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_vec(
-; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ueq <2 x float> [[X:%.*]], zeroinitializer
+define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_ninf_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf ueq <2 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
   %fneg = fneg <2 x float> %x
   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
-  %icmp = fcmp ueq <2 x float> %sel, <float 0.0, float -0.0>
+  %icmp = fcmp ninf ueq <2 x float> %sel, <float 0.0, float -0.0>
   ret <2 x i1> %icmp
 }
 
-define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_vec(<2 x i1> %cond, <2 x float> %x) {
-; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_vec(
-; CHECK-NEXT:    [[ICMP:%.*]] = fcmp une <2 x float> [[X:%.*]], zeroinitializer
+define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_ninf_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp ninf une <2 x float> [[X:%.*]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
   %fneg = fneg <2 x float> %x
   %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
-  %icmp = fcmp une <2 x float> %sel, <float 0.0, float -0.0>
+  %icmp = fcmp ninf une <2 x float> %sel, <float 0.0, float -0.0>
   ret <2 x i1> %icmp
 }
 
-define i1 @fcmp_ueq_sel_x_negx_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast ueq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
-;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast ueq float %sel, 0.000000e+00
-  ret i1 %res
-}
-
-define i1 @fcmp_une_sel_x_negx_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_une_sel_x_negx_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast une float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
-;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast une float %sel, 0.000000e+00
-  ret i1 %res
-}
-
-define i1 @fcmp_oeq_sel_x_negx_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast oeq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
-;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast oeq float %sel, 0.000000e+00
-  ret i1 %res
-}
-
-define i1 @fcmp_one_sel_x_negx_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_one_sel_x_negx_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast one float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
-;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast one float %sel, 0.000000e+00
-  ret i1 %res
-}
-
-define i1 @fcmp_ueq_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_ueq_sel_x_negx_nzero_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast ueq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
+define <2 x i1> @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_oeq_sel_x_negx_with_any_fpzero_nnan_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan oeq <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast ueq float %sel, -0.000000e+00
-  ret i1 %res
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp nnan oeq <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
 }
 
-define i1 @fcmp_une_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_une_sel_x_negx_nzero_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast une float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
+define <2 x i1> @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_one_sel_x_negx_with_any_fpzero_nnan_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan one <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast une float %sel, -0.000000e+00
-  ret i1 %res
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp nnan one <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
 }
 
-define i1 @fcmp_oeq_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_oeq_sel_x_negx_nzero_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast oeq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
+define <2 x i1> @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_ueq_sel_x_negx_with_any_fpzero_nnan_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan ueq <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast oeq float %sel, -0.000000e+00
-  ret i1 %res
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp nnan ueq <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
 }
 
-define i1 @fcmp_one_sel_x_negx_nzero_with_fmf(float %x, i1 %c) {
-; CHECK-LABEL: @fcmp_one_sel_x_negx_nzero_with_fmf(
-; CHECK-NEXT:    [[RES:%.*]] = fcmp fast one float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    ret i1 [[RES]]
+define <2 x i1> @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(<2 x i1> %cond, <2 x float> %x) {
+; CHECK-LABEL: @fcmp_une_sel_x_negx_with_any_fpzero_nnan_vec(
+; CHECK-NEXT:    [[ICMP:%.*]] = fcmp nnan une <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[ICMP]]
 ;
-  %neg = fneg float %x
-  %sel = select i1 %c, float %x, float %neg
-  %res = fcmp fast one float %sel, -0.000000e+00
-  ret i1 %res
+  %fneg = fneg <2 x float> %x
+  %sel = select <2 x i1> %cond, <2 x float> %x, <2 x float> %fneg
+  %icmp = fcmp nnan une <2 x float> %sel, <float 0.0, float -0.0>
+  ret <2 x i1> %icmp
 }

>From 00973c3b4fe40f06344b672efe80b009f70c74ac Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Wed, 17 Apr 2024 14:29:49 +0530
Subject: [PATCH 6/6] add replaceOperand

---
 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 bdfc96fc20f44e..f0278f207549fa 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -8051,7 +8051,7 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
           (match(LHSI,
                  m_Select(m_Value(), m_Value(X), m_FNeg(m_Deferred(X)))) ||
            match(LHSI, m_Select(m_Value(), m_FNeg(m_Value(X)), m_Deferred(X)))))
-        return new FCmpInst(Pred, X, RHSC, "", &I);
+        return replaceOperand(I, 0, X);
       break;
     case Instruction::PHI:
       if (Instruction *NV = foldOpIntoPhi(I, cast<PHINode>(LHSI)))



More information about the llvm-commits mailing list