[llvm] [InstSimplify] Generalize `simplifyAndOrOfFCmps` (PR #81027)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 7 11:11:35 PST 2024


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/81027

This patch generalizes `simplifyAndOrOfFCmps` to simplify patterns like:
```
define i1 @src(float %x, float %y) {
  %or.cond.i = fcmp ord float %x, 0.000000e+00
  %cmp.i.i34 = fcmp olt float %x, %y
  %cmp.i2.sink.i = and i1 %or.cond.i, %cmp.i.i34
  ret i1 %cmp.i2.sink.i
}

define i1 @tgt(float %x, float %y) {
  %cmp.i.i34 = fcmp olt float %x, %y
  ret i1 %cmp.i.i34
}
```
Alive2: https://alive2.llvm.org/ce/z/9rydcx

This patch and #80986 will fix the regression introduced by #80941.
See also the IR diff https://github.com/dtcxzyw/llvm-opt-benchmark/pull/199#discussion_r1480974120.



>From 6863b5bf9821418980555a2ca2c75817af5f608e Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 8 Feb 2024 02:50:08 +0800
Subject: [PATCH 1/2] [InstSimplify] Add pre-commit tests. NFC.

---
 .../Transforms/InstSimplify/logic-of-fcmps.ll | 185 ++++++++++++++++++
 1 file changed, 185 insertions(+)

diff --git a/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll b/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll
index d898df0b32f2b..76886b1c7a8bb 100644
--- a/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll
+++ b/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll
@@ -259,3 +259,188 @@ define <2 x i1> @uno8(<2 x double> %x, <2 x double> %y) {
   %r = or <2 x i1> %cmp1, %cmp2
   ret <2 x i1> %r
 }
+
+define i1 @olt_implies_ord(float %x, float %y) {
+; CHECK-LABEL: @olt_implies_ord(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[ORD]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %ord = fcmp ord float %x, 0.000000e+00
+  %olt = fcmp olt float %x, %y
+  %ret = and i1 %olt, %ord
+  ret i1 %ret
+}
+
+define i1 @olt_implies_ord_commuted1(float %x, float %y) {
+; CHECK-LABEL: @olt_implies_ord_commuted1(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[ORD]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %ord = fcmp ord float %x, 0.000000e+00
+  %olt = fcmp olt float %y, %x
+  %ret = and i1 %olt, %ord
+  ret i1 %ret
+}
+
+define i1 @olt_implies_ord_commuted2(float %x, float %y) {
+; CHECK-LABEL: @olt_implies_ord_commuted2(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ORD]], [[OLT]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %ord = fcmp ord float %x, 0.000000e+00
+  %olt = fcmp olt float %x, %y
+  %ret = and i1 %ord, %olt
+  ret i1 %ret
+}
+
+define i1 @olt_implies_ord_commuted3(float %x, float %y) {
+; CHECK-LABEL: @olt_implies_ord_commuted3(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ORD]], [[OLT]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %ord = fcmp ord float %x, 0.000000e+00
+  %olt = fcmp olt float %y, %x
+  %ret = and i1 %ord, %olt
+  ret i1 %ret
+}
+
+define <2 x i1> @olt_implies_ord_vec(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: @olt_implies_ord_vec(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord <2 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt <2 x float> [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = and <2 x i1> [[ORD]], [[OLT]]
+; CHECK-NEXT:    ret <2 x i1> [[RET]]
+;
+  %ord = fcmp ord <2 x float> %x, zeroinitializer
+  %olt = fcmp olt <2 x float> %x, %y
+  %ret = and <2 x i1> %ord, %olt
+  ret <2 x i1> %ret
+}
+
+define i1 @ord_implies_ord(float %x, float %y) {
+; CHECK-LABEL: @ord_implies_ord(
+; CHECK-NEXT:    [[ORD2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[ORD2]]
+;
+  %ord = fcmp ord float %x, 0.000000e+00
+  %ord2 = fcmp ord float %x, %y
+  %ret = and i1 %ord, %ord2
+  ret i1 %ret
+}
+
+define i1 @olt_implies_uno(float %x, float %y) {
+; CHECK-LABEL: @olt_implies_uno(
+; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[UNO]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %uno = fcmp uno float %x, 0.000000e+00
+  %olt = fcmp olt float %x, %y
+  %ret = and i1 %olt, %uno
+  ret i1 %ret
+}
+
+define i1 @ult_implies_uno(float %x, float %y) {
+; CHECK-LABEL: @ult_implies_uno(
+; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = or i1 [[ULT]], [[UNO]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %uno = fcmp uno float %x, 0.000000e+00
+  %ult = fcmp ult float %x, %y
+  %ret = or i1 %ult, %uno
+  ret i1 %ret
+}
+
+define i1 @uno_implies_uno(float %x, float %y) {
+; CHECK-LABEL: @uno_implies_uno(
+; CHECK-NEXT:    [[UNO2:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[UNO2]]
+;
+  %uno = fcmp uno float %x, 0.000000e+00
+  %uno2 = fcmp uno float %x, %y
+  %ret = or i1 %uno, %uno2
+  ret i1 %ret
+}
+
+define i1 @ult_implies_ord(float %x, float %y) {
+; CHECK-LABEL: @ult_implies_ord(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = or i1 [[ULT]], [[ORD]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %ord = fcmp ord float %x, 0.000000e+00
+  %ult = fcmp ult float %x, %y
+  %ret = or i1 %ult, %ord
+  ret i1 %ret
+}
+
+; TODO: %cmp1 is false implies %cmp3 is true
+define float @test_ord_implies_uno(float %x) {
+; CHECK-LABEL: @test_ord_implies_uno(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[CMP3:%.*]] = fcmp uno float [[X]], 0.000000e+00
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 [[CMP3]]
+; CHECK-NEXT:    [[RET:%.*]] = select i1 [[SEL]], float 0.000000e+00, float [[X]]
+; CHECK-NEXT:    ret float [[RET]]
+;
+  %cmp1 = fcmp ord float %x, 0.000000e+00
+  %cmp2 = fcmp olt float %x, 0.000000e+00
+  %cmp3 = fcmp uno float %x, 0.000000e+00
+  %sel = select i1 %cmp1, i1 %cmp2, i1 %cmp3
+  %ret = select i1 %sel, float 0.000000e+00, float %x
+  ret float %ret
+}
+
+; Negative tests
+
+define i1 @olt_implies_ord_fail(float %x, float %y, float %z) {
+; CHECK-LABEL: @olt_implies_ord_fail(
+; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[ORD]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %ord = fcmp ord float %x, %z
+  %olt = fcmp olt float %x, %y
+  %ret = and i1 %olt, %ord
+  ret i1 %ret
+}
+
+define i1 @ult_implies_uno_and(float %x, float %y) {
+; CHECK-LABEL: @ult_implies_uno_and(
+; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ULT]], [[UNO]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %uno = fcmp uno float %x, 0.000000e+00
+  %ult = fcmp ult float %x, %y
+  %ret = and i1 %ult, %uno
+  ret i1 %ret
+}
+
+define i1 @olt_implies_olt_fail(float %x, float %y) {
+; CHECK-LABEL: @olt_implies_olt_fail(
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[OLT2:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[OLT2]]
+; CHECK-NEXT:    ret i1 [[RET]]
+;
+  %olt = fcmp olt float %x, 0.000000e+00
+  %olt2 = fcmp olt float %x, %y
+  %ret = and i1 %olt, %olt2
+  ret i1 %ret
+}

>From dfdaf2f33a6dc4f768c3360afaed3680f63cd1e9 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 8 Feb 2024 02:59:08 +0800
Subject: [PATCH 2/2] [InstSimplify] Generalize `simplifyAndOrOfFCmps`

---
 llvm/lib/Analysis/InstructionSimplify.cpp     | 43 ++++++++---------
 .../create-class-from-logic-fcmp.ll           | 20 ++++----
 .../Transforms/InstSimplify/logic-of-fcmps.ll | 46 ++++++-------------
 3 files changed, 46 insertions(+), 63 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 01b017142cfcb..51e258d69e9e2 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1853,35 +1853,36 @@ static Value *simplifyAndOrOfFCmps(const SimplifyQuery &Q, FCmpInst *LHS,
     return nullptr;
 
   FCmpInst::Predicate PredL = LHS->getPredicate(), PredR = RHS->getPredicate();
-  if ((PredL == FCmpInst::FCMP_ORD && PredR == FCmpInst::FCMP_ORD && IsAnd) ||
-      (PredL == FCmpInst::FCMP_UNO && PredR == FCmpInst::FCMP_UNO && !IsAnd)) {
-    // (fcmp ord NNAN, X) & (fcmp ord X, Y) --> fcmp ord X, Y
-    // (fcmp ord NNAN, X) & (fcmp ord Y, X) --> fcmp ord Y, X
-    // (fcmp ord X, NNAN) & (fcmp ord X, Y) --> fcmp ord X, Y
-    // (fcmp ord X, NNAN) & (fcmp ord Y, X) --> fcmp ord Y, X
-    // (fcmp uno NNAN, X) | (fcmp uno X, Y) --> fcmp uno X, Y
-    // (fcmp uno NNAN, X) | (fcmp uno Y, X) --> fcmp uno Y, X
-    // (fcmp uno X, NNAN) | (fcmp uno X, Y) --> fcmp uno X, Y
-    // (fcmp uno X, NNAN) | (fcmp uno Y, X) --> fcmp uno Y, X
+  if ((PredL == FCmpInst::FCMP_ORD || PredL == FCmpInst::FCMP_UNO) &&
+      ((FCmpInst::isOrdered(PredR) && IsAnd) ||
+       (FCmpInst::isUnordered(PredR) && !IsAnd))) {
+    // (fcmp ord X, NNAN) & (fcmp o** X, Y) --> fcmp o** X, Y
+    // (fcmp uno X, NNAN) & (fcmp o** X, Y) --> false
+    // (fcmp uno X, NNAN) | (fcmp u** X, Y) --> fcmp u** X, Y
+    // (fcmp ord X, NNAN) | (fcmp u** X, Y) --> true
     if (((LHS1 == RHS0 || LHS1 == RHS1) &&
          isKnownNeverNaN(LHS0, /*Depth=*/0, Q)) ||
         ((LHS0 == RHS0 || LHS0 == RHS1) &&
          isKnownNeverNaN(LHS1, /*Depth=*/0, Q)))
-      return RHS;
-
-    // (fcmp ord X, Y) & (fcmp ord NNAN, X) --> fcmp ord X, Y
-    // (fcmp ord Y, X) & (fcmp ord NNAN, X) --> fcmp ord Y, X
-    // (fcmp ord X, Y) & (fcmp ord X, NNAN) --> fcmp ord X, Y
-    // (fcmp ord Y, X) & (fcmp ord X, NNAN) --> fcmp ord Y, X
-    // (fcmp uno X, Y) | (fcmp uno NNAN, X) --> fcmp uno X, Y
-    // (fcmp uno Y, X) | (fcmp uno NNAN, X) --> fcmp uno Y, X
-    // (fcmp uno X, Y) | (fcmp uno X, NNAN) --> fcmp uno X, Y
-    // (fcmp uno Y, X) | (fcmp uno X, NNAN) --> fcmp uno Y, X
+      return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
+                 ? static_cast<Value *>(RHS)
+                 : ConstantInt::getBool(LHS->getType(), !IsAnd);
+  }
+
+  if ((PredR == FCmpInst::FCMP_ORD || PredR == FCmpInst::FCMP_UNO) &&
+      ((FCmpInst::isOrdered(PredL) && IsAnd) ||
+       (FCmpInst::isUnordered(PredL) && !IsAnd))) {
+    // (fcmp o** X, Y) & (fcmp ord X, NNAN) --> fcmp o** X, Y
+    // (fcmp o** X, Y) & (fcmp uno X, NNAN) --> false
+    // (fcmp u** X, Y) | (fcmp uno X, NNAN) --> fcmp u** X, Y
+    // (fcmp u** X, Y) | (fcmp ord X, NNAN) --> true
     if (((RHS1 == LHS0 || RHS1 == LHS1) &&
          isKnownNeverNaN(RHS0, /*Depth=*/0, Q)) ||
         ((RHS0 == LHS0 || RHS0 == LHS1) &&
          isKnownNeverNaN(RHS1, /*Depth=*/0, Q)))
-      return LHS;
+      return FCmpInst::isOrdered(PredL) == FCmpInst::isOrdered(PredR)
+                 ? static_cast<Value *>(LHS)
+                 : ConstantInt::getBool(LHS->getType(), !IsAnd);
   }
 
   return nullptr;
diff --git a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
index 24dac97672f71..12c608cd6c2bb 100644
--- a/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/create-class-from-logic-fcmp.ll
@@ -1100,8 +1100,8 @@ define i1 @uge_smallest_normal_or_ord(half %x) #0 {
 ; -> nan | pnormal | pinf
 define i1 @uge_smallest_normal_or_uno(half %x) #0 {
 ; CHECK-LABEL: @uge_smallest_normal_or_uno(
-; CHECK-NEXT:    [[CLASS:%.*]] = call i1 @llvm.is.fpclass.f16(half [[X:%.*]], i32 771)
-; CHECK-NEXT:    ret i1 [[CLASS]]
+; CHECK-NEXT:    [[CMP_SMALLEST_NORMAL:%.*]] = fcmp uge half [[X:%.*]], 0xH0400
+; CHECK-NEXT:    ret i1 [[CMP_SMALLEST_NORMAL]]
 ;
   %uno = fcmp uno half %x, 0.0
   %cmp.smallest.normal = fcmp uge half %x, 0xH0400
@@ -1307,8 +1307,8 @@ define i1 @oge_fabs_eq_inf_and_ord(half %x) #0 {
 
 define i1 @oge_eq_inf_and_ord(half %x) #0 {
 ; CHECK-LABEL: @oge_eq_inf_and_ord(
-; CHECK-NEXT:    [[AND:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
-; CHECK-NEXT:    ret i1 [[AND]]
+; CHECK-NEXT:    [[OGE_FABS_INF:%.*]] = fcmp oeq half [[X:%.*]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[OGE_FABS_INF]]
 ;
   %oge.fabs.inf = fcmp oge half %x, 0xH7C00
   %ord = fcmp ord half %x, 0xH0000
@@ -1379,8 +1379,8 @@ define i1 @ult_fabs_eq_inf_or_uno(half %x) #0 {
 
 define i1 @ult_eq_inf_or_uno(half %x) #0 {
 ; CHECK-LABEL: @ult_eq_inf_or_uno(
-; CHECK-NEXT:    [[OR:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
-; CHECK-NEXT:    ret i1 [[OR]]
+; CHECK-NEXT:    [[ULT_FABS_INF:%.*]] = fcmp une half [[X:%.*]], 0xH7C00
+; CHECK-NEXT:    ret i1 [[ULT_FABS_INF]]
 ;
   %ult.fabs.inf = fcmp ult half %x, 0xH7C00
   %uno = fcmp uno half %x, 0xH0000
@@ -1465,8 +1465,8 @@ define i1 @oeq_neginfinity_or_ord(half %x) #0 {
 ; -> ninf
 define i1 @oeq_neginfinity_and_ord(half %x) #0 {
 ; CHECK-LABEL: @oeq_neginfinity_and_ord(
-; CHECK-NEXT:    [[CLASS:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
-; CHECK-NEXT:    ret i1 [[CLASS]]
+; CHECK-NEXT:    [[OEQ_NEG_INFINITY:%.*]] = fcmp oeq half [[X:%.*]], 0xHFC00
+; CHECK-NEXT:    ret i1 [[OEQ_NEG_INFINITY]]
 ;
   %oeq.neg.infinity = fcmp oeq half %x, 0xHFC00
   %ord = fcmp ord half %x, 0.0
@@ -1597,8 +1597,8 @@ define i1 @ueq_neginfinity_and_olt_smallest_normal(half %x) #0 {
 ; -> nan|ninf
 define i1 @ueq_neginfinity_or_uno(half %x) #0 {
 ; CHECK-LABEL: @ueq_neginfinity_or_uno(
-; CHECK-NEXT:    [[CLASS:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
-; CHECK-NEXT:    ret i1 [[CLASS]]
+; CHECK-NEXT:    [[UEQ_NEG_INFINITY:%.*]] = fcmp ueq half [[X:%.*]], 0xHFC00
+; CHECK-NEXT:    ret i1 [[UEQ_NEG_INFINITY]]
 ;
   %ueq.neg.infinity = fcmp ueq half %x, 0xHFC00
   %uno = fcmp uno half %x, 0.0
diff --git a/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll b/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll
index 76886b1c7a8bb..4b2ff1b3d050c 100644
--- a/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll
+++ b/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll
@@ -262,10 +262,8 @@ define <2 x i1> @uno8(<2 x double> %x, <2 x double> %y) {
 
 define i1 @olt_implies_ord(float %x, float %y) {
 ; CHECK-LABEL: @olt_implies_ord(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[OLT]]
 ;
   %ord = fcmp ord float %x, 0.000000e+00
   %olt = fcmp olt float %x, %y
@@ -275,10 +273,8 @@ define i1 @olt_implies_ord(float %x, float %y) {
 
 define i1 @olt_implies_ord_commuted1(float %x, float %y) {
 ; CHECK-LABEL: @olt_implies_ord_commuted1(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X]]
-; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[OLT]]
 ;
   %ord = fcmp ord float %x, 0.000000e+00
   %olt = fcmp olt float %y, %x
@@ -288,10 +284,8 @@ define i1 @olt_implies_ord_commuted1(float %x, float %y) {
 
 define i1 @olt_implies_ord_commuted2(float %x, float %y) {
 ; CHECK-LABEL: @olt_implies_ord_commuted2(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ORD]], [[OLT]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[OLT]]
 ;
   %ord = fcmp ord float %x, 0.000000e+00
   %olt = fcmp olt float %x, %y
@@ -301,10 +295,8 @@ define i1 @olt_implies_ord_commuted2(float %x, float %y) {
 
 define i1 @olt_implies_ord_commuted3(float %x, float %y) {
 ; CHECK-LABEL: @olt_implies_ord_commuted3(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X]]
-; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ORD]], [[OLT]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[OLT]]
 ;
   %ord = fcmp ord float %x, 0.000000e+00
   %olt = fcmp olt float %y, %x
@@ -314,10 +306,8 @@ define i1 @olt_implies_ord_commuted3(float %x, float %y) {
 
 define <2 x i1> @olt_implies_ord_vec(<2 x float> %x, <2 x float> %y) {
 ; CHECK-LABEL: @olt_implies_ord_vec(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord <2 x float> [[X:%.*]], zeroinitializer
-; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt <2 x float> [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = and <2 x i1> [[ORD]], [[OLT]]
-; CHECK-NEXT:    ret <2 x i1> [[RET]]
+; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt <2 x float> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <2 x i1> [[OLT]]
 ;
   %ord = fcmp ord <2 x float> %x, zeroinitializer
   %olt = fcmp olt <2 x float> %x, %y
@@ -338,10 +328,7 @@ define i1 @ord_implies_ord(float %x, float %y) {
 
 define i1 @olt_implies_uno(float %x, float %y) {
 ; CHECK-LABEL: @olt_implies_uno(
-; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[UNO]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    ret i1 false
 ;
   %uno = fcmp uno float %x, 0.000000e+00
   %olt = fcmp olt float %x, %y
@@ -351,10 +338,8 @@ define i1 @olt_implies_uno(float %x, float %y) {
 
 define i1 @ult_implies_uno(float %x, float %y) {
 ; CHECK-LABEL: @ult_implies_uno(
-; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = or i1 [[ULT]], [[UNO]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[ULT]]
 ;
   %uno = fcmp uno float %x, 0.000000e+00
   %ult = fcmp ult float %x, %y
@@ -375,10 +360,7 @@ define i1 @uno_implies_uno(float %x, float %y) {
 
 define i1 @ult_implies_ord(float %x, float %y) {
 ; CHECK-LABEL: @ult_implies_ord(
-; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X]], [[Y:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = or i1 [[ULT]], [[ORD]]
-; CHECK-NEXT:    ret i1 [[RET]]
+; CHECK-NEXT:    ret i1 true
 ;
   %ord = fcmp ord float %x, 0.000000e+00
   %ult = fcmp ult float %x, %y



More information about the llvm-commits mailing list