[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