[llvm] Optimize fptrunc(x)>=C1 --> x>=C2 (PR #99475)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 3 23:24:37 PDT 2024


https://github.com/kissholic updated https://github.com/llvm/llvm-project/pull/99475

>From a1547d2230cd503a1e25752092409df3175f7a3d Mon Sep 17 00:00:00 2001
From: kissholicma <kissholicma at tencent.com>
Date: Thu, 18 Jul 2024 19:31:56 +0800
Subject: [PATCH 1/3] Optimize fptrunc(x)>=C1 -->  x>=C2

---
 .../InstCombine/InstCombineCompares.cpp       | 31 +++++++++++++++++++
 .../Transforms/InstCombine/fold-fcmp-trunc.ll | 11 +++++++
 2 files changed, 42 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index abadf54a96767..2af3e92213f13 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -22,10 +22,13 @@
 #include "llvm/Analysis/Utils/Local.h"
 #include "llvm/Analysis/VectorUtils.h"
 #include "llvm/IR/ConstantRange.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/Support/Casting.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Transforms/InstCombine/InstCombiner.h"
 #include <bitset>
@@ -7882,6 +7885,30 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
   return new FCmpInst(Pred, LHSI->getOperand(1), RHSC, "", &I);
 }
 
+// Fold trunc(x) < constant --> x < constant if possible.
+static Instruction *foldFCmpFpTrunc(FCmpInst &I, Instruction *LHSI,
+                                    Constant *RHSC) {
+  //
+  FCmpInst::Predicate Pred = I.getPredicate();
+
+  // Check that predicates are valid.
+  if ((Pred != FCmpInst::FCMP_OGT) && (Pred != FCmpInst::FCMP_OLT) &&
+      (Pred != FCmpInst::FCMP_OGE) && (Pred != FCmpInst::FCMP_OLE))
+    return nullptr;
+
+  auto *LType = LHSI->getOperand(0)->getType();
+  auto *RType = RHSC->getType();
+
+  if (!(LType->isFloatingPointTy() && RType->isFloatingPointTy() &&
+        LType->getTypeID() >= RType->getTypeID()))
+    return nullptr;
+
+  auto *ROperand = llvm::ConstantFP::get(
+      LType, dyn_cast<ConstantFP>(RHSC)->getValue().convertToDouble());
+
+  return new FCmpInst(Pred, LHSI->getOperand(0), ROperand, "", &I);
+}
+
 /// Optimize fabs(X) compared with zero.
 static Instruction *foldFabsWithFcmpZero(FCmpInst &I, InstCombinerImpl &IC) {
   Value *X;
@@ -8244,6 +8271,10 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
                   cast<LoadInst>(LHSI), GEP, GV, I))
             return Res;
       break;
+    case Instruction::FPTrunc:
+      if (Instruction *NV = foldFCmpFpTrunc(I, LHSI, RHSC))
+        return NV;
+      break;
   }
   }
 
diff --git a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
new file mode 100644
index 0000000000000..446111a60dd6c
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
@@ -0,0 +1,11 @@
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+
+;CHECK-LABEL: @src(
+;CHECK: %result = fcmp oge double %0, 1.000000e+02
+;CHECK-NEXT: ret i1 %result
+define i1 @src(double %0) {
+    %trunc = fptrunc double %0 to float
+    %result = fcmp oge float %trunc, 1.000000e+02
+    ret i1 %result
+}
\ No newline at end of file

>From 73b1f0b57b45534187103ccc8bb935708179ebf3 Mon Sep 17 00:00:00 2001
From: kissholic <kissholicovo at outlook.com>
Date: Wed, 24 Jul 2024 19:42:55 +0800
Subject: [PATCH 2/3] Optimize fptrunc(x)>=C1 --> x>=C2. Add check cases and
 support for vector types.

---
 .../InstCombine/InstCombineCompares.cpp       |  47 +++++--
 .../Transforms/InstCombine/fold-fcmp-trunc.ll | 130 ++++++++++++++++--
 2 files changed, 160 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 2af3e92213f13..37053a95638c0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -11,9 +11,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "InstCombineInternal.h"
+#include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/CaptureTracking.h"
 #include "llvm/Analysis/CmpInstAnalysis.h"
@@ -24,14 +26,18 @@
 #include "llvm/IR/ConstantRange.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Value.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Transforms/InstCombine/InstCombiner.h"
 #include <bitset>
+#include <cstdint>
 
 using namespace llvm;
 using namespace PatternMatch;
@@ -7888,7 +7894,6 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
 // Fold trunc(x) < constant --> x < constant if possible.
 static Instruction *foldFCmpFpTrunc(FCmpInst &I, Instruction *LHSI,
                                     Constant *RHSC) {
-  //
   FCmpInst::Predicate Pred = I.getPredicate();
 
   // Check that predicates are valid.
@@ -7896,17 +7901,41 @@ static Instruction *foldFCmpFpTrunc(FCmpInst &I, Instruction *LHSI,
       (Pred != FCmpInst::FCMP_OGE) && (Pred != FCmpInst::FCMP_OLE))
     return nullptr;
 
-  auto *LType = LHSI->getOperand(0)->getType();
-  auto *RType = RHSC->getType();
+  if (ConstantFP *ConstRFp = dyn_cast<ConstantFP>(RHSC)) {
+    Type *LType = LHSI->getOperand(0)->getType();
+    bool lossInfo;
+    APFloat RValue = ConstRFp->getValue();
+    RValue.convert(LType->getFltSemantics(), APFloat::rmNearestTiesToEven,
+                   &lossInfo);
 
-  if (!(LType->isFloatingPointTy() && RType->isFloatingPointTy() &&
-        LType->getTypeID() >= RType->getTypeID()))
-    return nullptr;
+    return new FCmpInst(Pred, LHSI->getOperand(0),
+                        ConstantFP::get(LType, RValue), "", &I);
+  }
+
+  if (RHSC->getType()->isVectorTy()) {
+    Type *LVecType = LHSI->getOperand(0)->getType();
+    Type *LEleType = dyn_cast<VectorType>(LVecType)->getElementType();
+
+    FixedVectorType *VecType = dyn_cast<FixedVectorType>(RHSC->getType());
+    uint64_t EleNum = VecType->getNumElements();
 
-  auto *ROperand = llvm::ConstantFP::get(
-      LType, dyn_cast<ConstantFP>(RHSC)->getValue().convertToDouble());
+    std::vector<Constant *> EleVec(EleNum);
+    for (uint64_t Idx = 0; Idx < EleNum; ++Idx) {
+      bool lossInfo;
+      APFloat EleValue =
+          dyn_cast<ConstantFP>(RHSC->getAggregateElement(Idx))->getValueAPF();
+      EleValue.convert(LEleType->getFltSemantics(),
+                       APFloat::rmNearestTiesToEven, &lossInfo);
+      EleVec[Idx] = ConstantFP::get(LEleType, EleValue);
+    }
+
+    ArrayRef<Constant *> EleArr(EleVec);
 
-  return new FCmpInst(Pred, LHSI->getOperand(0), ROperand, "", &I);
+    return new FCmpInst(Pred, LHSI->getOperand(0), ConstantVector::get(EleArr),
+                        "", &I);
+  }
+
+  return nullptr;
 }
 
 /// Optimize fabs(X) compared with zero.
diff --git a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
index 446111a60dd6c..3fdf35f0e0db2 100644
--- a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
+++ b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
@@ -1,11 +1,125 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
 
 
-;CHECK-LABEL: @src(
-;CHECK: %result = fcmp oge double %0, 1.000000e+02
-;CHECK-NEXT: ret i1 %result
-define i1 @src(double %0) {
-    %trunc = fptrunc double %0 to float
-    %result = fcmp oge float %trunc, 1.000000e+02
-    ret i1 %result
-}
\ No newline at end of file
+define i1 @fcmp_trunc(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_with_nnan(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_with_nnan(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp nnan oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp nnan oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_with_ninf(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_with_ninf(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp ninf oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp ninf oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_with_nsz(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_with_nsz(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp nsz oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp nsz oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_with_reassoc(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_with_reassoc(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp reassoc oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp reassoc oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_with_fast(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_with_fast(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp fast oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define <4 x i1> @fcmp_vec_trunc(<4 x double> %0) {
+; CHECK-LABEL: define <4 x i1> @fcmp_vec_trunc(
+; CHECK-SAME: <4 x double> [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <4 x double> [[TMP0]], <double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00>
+; CHECK-NEXT:    ret <4 x i1> [[CMP]]
+;
+  %vec = fptrunc <4 x double> %0 to <4 x float>
+  %cmp = fcmp olt <4 x float> %vec, <float 1.0, float 2.0, float 3.0, float 4.0>
+  ret <4 x i1> %cmp
+}
+
+define <4 x i1> @fcmp_vec_trunc_with_flag(<4 x double> %0) {
+; CHECK-LABEL: define <4 x i1> @fcmp_vec_trunc_with_flag(
+; CHECK-SAME: <4 x double> [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt <4 x double> [[TMP0]], <double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00>
+; CHECK-NEXT:    ret <4 x i1> [[CMP]]
+;
+  %vec = fptrunc <4 x double> %0 to <4 x float>
+  %cmp = fcmp fast olt <4 x float> %vec, <float 1.0, float 2.0, float 3.0, float 4.0>
+  ret <4 x i1> %cmp
+}
+
+define i1 @fcmp_trunc_fp128(fp128 %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_fp128(
+; CHECK-SAME: fp128 [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge fp128 [[TMP0]], 0xL00000000000000004005900000000000
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc fp128 %0 to float
+  %result = fcmp fast oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_x86_fp80(x86_fp80 %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_x86_fp80(
+; CHECK-SAME: x86_fp80 [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge x86_fp80 [[TMP0]], 0xK4005C800000000000000
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc x86_fp80 %0 to float
+  %result = fcmp fast oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_ppc_fp128(ppc_fp128 %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_ppc_fp128(
+; CHECK-SAME: ppc_fp128 [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge ppc_fp128 [[TMP0]], 0xM40590000000000000000000000000000
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc ppc_fp128 %0 to float
+  %result = fcmp fast oge float %trunc, 1.000000e+02
+  ret i1 %result
+}
+

>From 7804fb159092a451f7b74c489b498070a7e769f0 Mon Sep 17 00:00:00 2001
From: kissholic <kissholicovo at outlook.com>
Date: Sun, 4 Aug 2024 14:23:21 +0800
Subject: [PATCH 3/3] Optimize fptrunc(x)>=C1 --> x>=C2 Fix round value & add
 scalable vector test

---
 .../InstCombine/InstCombineCompares.cpp       | 87 ++++++++++++-------
 .../Transforms/InstCombine/fold-fcmp-trunc.ll | 82 +++++++++++++----
 2 files changed, 120 insertions(+), 49 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 37053a95638c0..5e6e2e8a02dd5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -32,6 +32,7 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/Type.h"
 #include "llvm/IR/Value.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/KnownBits.h"
@@ -7895,47 +7896,73 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
 static Instruction *foldFCmpFpTrunc(FCmpInst &I, Instruction *LHSI,
                                     Constant *RHSC) {
   FCmpInst::Predicate Pred = I.getPredicate();
+  bool RoundDown = false;
+
+  if ((Pred == FCmpInst::FCMP_OGE) || (Pred == FCmpInst::FCMP_UGE) ||
+      (Pred == FCmpInst::FCMP_OLT) || (Pred == FCmpInst::FCMP_ULT))
+    RoundDown = true;
+  else if ((Pred == FCmpInst::FCMP_OGT) || (Pred == FCmpInst::FCMP_UGT) ||
+           (Pred == FCmpInst::FCMP_OLE) || (Pred == FCmpInst::FCMP_ULE))
+    RoundDown = false;
+  else
+    return nullptr;
 
-  // Check that predicates are valid.
-  if ((Pred != FCmpInst::FCMP_OGT) && (Pred != FCmpInst::FCMP_OLT) &&
-      (Pred != FCmpInst::FCMP_OGE) && (Pred != FCmpInst::FCMP_OLE))
+  const APFloat *RValue;
+  if (!match(RHSC, m_APFloat(RValue)))
     return nullptr;
 
-  if (ConstantFP *ConstRFp = dyn_cast<ConstantFP>(RHSC)) {
-    Type *LType = LHSI->getOperand(0)->getType();
-    bool lossInfo;
-    APFloat RValue = ConstRFp->getValue();
-    RValue.convert(LType->getFltSemantics(), APFloat::rmNearestTiesToEven,
-                   &lossInfo);
+  Type *LType = LHSI->getOperand(0)->getType();
+  Type *RType = RHSC->getType();
+  Type *LEleType = LType->getScalarType();
+  Type *REleType = RType->getScalarType();
 
-    return new FCmpInst(Pred, LHSI->getOperand(0),
-                        ConstantFP::get(LType, RValue), "", &I);
-  }
+  APFloat NextRValue = *RValue;
+  NextRValue.next(RoundDown);
 
-  if (RHSC->getType()->isVectorTy()) {
-    Type *LVecType = LHSI->getOperand(0)->getType();
-    Type *LEleType = dyn_cast<VectorType>(LVecType)->getElementType();
+  // Round RValue to suitable value
+  APFloat ExtRValue = *RValue;
+  APFloat ExtNextRValue = NextRValue;
+  bool lossInfo;
+  ExtRValue.convert(LEleType->getFltSemantics(), APFloat::rmNearestTiesToEven,
+                    &lossInfo);
+  ExtNextRValue.convert(LEleType->getFltSemantics(),
+                        APFloat::rmNearestTiesToEven, &lossInfo);
 
-    FixedVectorType *VecType = dyn_cast<FixedVectorType>(RHSC->getType());
-    uint64_t EleNum = VecType->getNumElements();
+  APFloat RoundValue{LEleType->getFltSemantics()};
+  {
+    APFloat Two{LEleType->getFltSemantics(), 2};
+    APFloat LowBound = RoundDown ? ExtNextRValue : ExtRValue;
+    APFloat UpBound = RoundDown ? ExtRValue : ExtNextRValue;
+
+    while (true) {
+      APFloat DupUpBound = UpBound;
+      DupUpBound.next(true);
+      if (DupUpBound == LowBound) {
+        RoundValue = RoundDown ? UpBound : LowBound;
+        break;
+      }
 
-    std::vector<Constant *> EleVec(EleNum);
-    for (uint64_t Idx = 0; Idx < EleNum; ++Idx) {
-      bool lossInfo;
-      APFloat EleValue =
-          dyn_cast<ConstantFP>(RHSC->getAggregateElement(Idx))->getValueAPF();
-      EleValue.convert(LEleType->getFltSemantics(),
+      APFloat Mid = (LowBound + UpBound) / Two;
+      APFloat TruncMid = Mid;
+      TruncMid.convert(REleType->getFltSemantics(),
                        APFloat::rmNearestTiesToEven, &lossInfo);
-      EleVec[Idx] = ConstantFP::get(LEleType, EleValue);
-    }
-
-    ArrayRef<Constant *> EleArr(EleVec);
 
-    return new FCmpInst(Pred, LHSI->getOperand(0), ConstantVector::get(EleArr),
-                        "", &I);
+      if (TruncMid == *RValue) {
+        if (RoundDown)
+          UpBound = Mid;
+        else
+          LowBound = Mid;
+      } else {
+        if (RoundDown)
+          LowBound = Mid;
+        else
+          UpBound = Mid;
+      }
+    }
   }
 
-  return nullptr;
+  return new FCmpInst(Pred, LHSI->getOperand(0),
+                      ConstantFP::get(LType, RoundValue), "", &I);
 }
 
 /// Optimize fabs(X) compared with zero.
diff --git a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
index 3fdf35f0e0db2..59b5903ed330b 100644
--- a/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
+++ b/llvm/test/Transforms/InstCombine/fold-fcmp-trunc.ll
@@ -5,7 +5,7 @@
 define i1 @fcmp_trunc(double %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc(
 ; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp oge double [[TMP0]], 0x4058FFFFF0000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc double %0 to float
@@ -13,10 +13,54 @@ define i1 @fcmp_trunc(double %0) {
   ret i1 %result
 }
 
+define i1 @fcmp_trunc_ult(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_ult(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp ult double [[TMP0]], 0x4068FFFFF0000000
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp ult float %trunc, 2.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_ole(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_ole(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp ole double [[TMP0]], 0x4072C00010000000
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp ole float %trunc, 3.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_ogt(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_ogt(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp ogt double [[TMP0]], 0x4079000010000000
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp ogt float %trunc, 4.000000e+02
+  ret i1 %result
+}
+
+define i1 @fcmp_trunc_zero(double %0) {
+; CHECK-LABEL: define i1 @fcmp_trunc_zero(
+; CHECK-SAME: double [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp oge double [[TMP0]], 0xB690000000000000
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+  %trunc = fptrunc double %0 to float
+  %result = fcmp oge float %trunc, 0.000000
+  ret i1 %result
+}
+
 define i1 @fcmp_trunc_with_nnan(double %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_with_nnan(
 ; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp nnan oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp nnan oge double [[TMP0]], 0x4058FFFFF0000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc double %0 to float
@@ -27,7 +71,7 @@ define i1 @fcmp_trunc_with_nnan(double %0) {
 define i1 @fcmp_trunc_with_ninf(double %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_with_ninf(
 ; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp ninf oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp ninf oge double [[TMP0]], 0x4058FFFFF0000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc double %0 to float
@@ -38,7 +82,7 @@ define i1 @fcmp_trunc_with_ninf(double %0) {
 define i1 @fcmp_trunc_with_nsz(double %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_with_nsz(
 ; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp nsz oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp nsz oge double [[TMP0]], 0x4058FFFFF0000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc double %0 to float
@@ -49,7 +93,7 @@ define i1 @fcmp_trunc_with_nsz(double %0) {
 define i1 @fcmp_trunc_with_reassoc(double %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_with_reassoc(
 ; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp reassoc oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp reassoc oge double [[TMP0]], 0x4058FFFFF0000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc double %0 to float
@@ -60,7 +104,7 @@ define i1 @fcmp_trunc_with_reassoc(double %0) {
 define i1 @fcmp_trunc_with_fast(double %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_with_fast(
 ; CHECK-SAME: double [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge double [[TMP0]], 1.000000e+02
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge double [[TMP0]], 0x4058FFFFF0000000 
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc double %0 to float
@@ -71,29 +115,29 @@ define i1 @fcmp_trunc_with_fast(double %0) {
 define <4 x i1> @fcmp_vec_trunc(<4 x double> %0) {
 ; CHECK-LABEL: define <4 x i1> @fcmp_vec_trunc(
 ; CHECK-SAME: <4 x double> [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <4 x double> [[TMP0]], <double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00>
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt <4 x double> [[TMP0]], <double 0x3FEFFFFFF0000000, double 0x3FEFFFFFF0000000, double 0x3FEFFFFFF0000000, double 0x3FEFFFFFF0000000>
 ; CHECK-NEXT:    ret <4 x i1> [[CMP]]
 ;
   %vec = fptrunc <4 x double> %0 to <4 x float>
-  %cmp = fcmp olt <4 x float> %vec, <float 1.0, float 2.0, float 3.0, float 4.0>
+  %cmp = fcmp olt <4 x float> %vec, <float 1.0, float 1.0, float 1.0, float 1.0>
   ret <4 x i1> %cmp
 }
 
-define <4 x i1> @fcmp_vec_trunc_with_flag(<4 x double> %0) {
-; CHECK-LABEL: define <4 x i1> @fcmp_vec_trunc_with_flag(
-; CHECK-SAME: <4 x double> [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt <4 x double> [[TMP0]], <double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00>
-; CHECK-NEXT:    ret <4 x i1> [[CMP]]
+define <1 x i1> @fcmp_vec_trunc_scalar(<1 x double> %0) {
+; CHECK-LABEL: define <1 x i1> @fcmp_vec_trunc_scalar(
+; CHECK-SAME: <1 x double> [[TMP0:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp fast olt <1 x double> [[TMP0]], <double 0x3FEFFFFFF0000000>
+; CHECK-NEXT:    ret <1 x i1> [[CMP]]
 ;
-  %vec = fptrunc <4 x double> %0 to <4 x float>
-  %cmp = fcmp fast olt <4 x float> %vec, <float 1.0, float 2.0, float 3.0, float 4.0>
-  ret <4 x i1> %cmp
+  %vec = fptrunc <1 x double> %0 to <1 x float>
+  %cmp = fcmp fast olt <1 x float> %vec, <float 1.0>
+  ret <1 x i1> %cmp
 }
 
 define i1 @fcmp_trunc_fp128(fp128 %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_fp128(
 ; CHECK-SAME: fp128 [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge fp128 [[TMP0]], 0xL00000000000000004005900000000000
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge fp128 [[TMP0]], 0xL000000000000000040058FFFFF000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc fp128 %0 to float
@@ -104,7 +148,7 @@ define i1 @fcmp_trunc_fp128(fp128 %0) {
 define i1 @fcmp_trunc_x86_fp80(x86_fp80 %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_x86_fp80(
 ; CHECK-SAME: x86_fp80 [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge x86_fp80 [[TMP0]], 0xK4005C800000000000000
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge x86_fp80 [[TMP0]], 0xK4005C7FFFF8000000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc x86_fp80 %0 to float
@@ -115,7 +159,7 @@ define i1 @fcmp_trunc_x86_fp80(x86_fp80 %0) {
 define i1 @fcmp_trunc_ppc_fp128(ppc_fp128 %0) {
 ; CHECK-LABEL: define i1 @fcmp_trunc_ppc_fp128(
 ; CHECK-SAME: ppc_fp128 [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge ppc_fp128 [[TMP0]], 0xM40590000000000000000000000000000
+; CHECK-NEXT:    [[RESULT:%.*]] = fcmp fast oge ppc_fp128 [[TMP0]], 0xM4058FFFFF0000000BD00000000000000
 ; CHECK-NEXT:    ret i1 [[RESULT]]
 ;
   %trunc = fptrunc ppc_fp128 %0 to float



More information about the llvm-commits mailing list