18void ConstantFPRange::makeEmpty() {
 
   19  auto &Sem = Lower.getSemantics();
 
   26void ConstantFPRange::makeFull() {
 
   27  auto &Sem = Lower.getSemantics();
 
   35  return Lower.isPosInfinity() && Upper.isNegInfinity();
 
 
   38ConstantFPRange::ConstantFPRange(
const fltSemantics &Sem, 
bool IsFullSet)
 
   42  MayBeQNaN = IsFullSet;
 
   43  MayBeSNaN = IsFullSet;
 
   51    bool IsSNaN = Value.isSignaling();
 
   55    Lower = Upper = Value;
 
   56    MayBeQNaN = MayBeSNaN = false;
 
 
   63  assert(!
LHS.isNaN() && !
RHS.isNaN() && 
"Unordered compare");
 
   64  if (
LHS.isZero() && 
RHS.isZero()) {
 
   65    if (
LHS.isNegative() == 
RHS.isNegative())
 
 
   85                                 bool MayBeQNaNVal, 
bool MayBeSNaNVal)
 
   87      MayBeQNaN(MayBeQNaNVal), MayBeSNaN(MayBeSNaNVal) {
 
   88  assert(&Lower.getSemantics() == &Upper.getSemantics() &&
 
   89         "Should only use the same semantics");
 
 
  100                                            bool MayBeQNaN, 
bool MayBeSNaN) {
 
 
  121    if (V.isNegInfinity())
 
  122      return ConstantFPRange::getEmpty(Sem);
 
 
  133    if (V.isPosInfinity())
 
  134      return ConstantFPRange::getEmpty(Sem);
 
 
  149  if (
Lower.isPosZero())
 
  151  if (
Upper.isNegZero())
 
 
  161                         ContainsNaN, ContainsNaN);
 
 
  166                                       const ConstantFPRange &
Other) {
 
  167  if (
Other.isEmptySet())
 
  170    return getFull(
Other.getSemantics());
 
  172    return getEmpty(
Other.getSemantics());
 
  176    return getFull(
Other.getSemantics());
 
  178    return getEmpty(
Other.getSemantics());
 
  189    if (
const APFloat *SingleElement =
 
  190            Other.getSingleElement(
true)) {
 
  191      const fltSemantics &Sem = SingleElement->getSemantics();
 
  192      if (SingleElement->isPosInfinity())
 
  197      if (SingleElement->isNegInfinity())
 
  204                                      : getFull(
Other.getSemantics());
 
 
  224                                          const ConstantFPRange &
Other) {
 
  225  if (
Other.isEmptySet())
 
  226    return getFull(
Other.getSemantics());
 
  228    return getEmpty(
Other.getSemantics());
 
  230    return getFull(
Other.getSemantics());
 
  234    return getFull(
Other.getSemantics());
 
  236    return getEmpty(
Other.getSemantics());
 
  247                           : getEmpty(
Other.getSemantics()),
 
  251    return getEmpty(
Other.getSemantics());
 
 
  269std::optional<ConstantFPRange>
 
  279                           const ConstantFPRange &
Other)
 const {
 
 
  284  return Lower.isNegInfinity() && Upper.isPosInfinity() && MayBeQNaN &&
 
 
  289  return Lower.isPosInfinity() && Upper.isNegInfinity() && !MayBeQNaN &&
 
 
  295         "Should only use the same semantics");
 
 
  305         "Should only use the same semantics");
 
  307  if (CR.MayBeQNaN && !MayBeQNaN)
 
  310  if (CR.MayBeSNaN && !MayBeSNaN)
 
 
  318  if (!ExcludesNaN && (MayBeSNaN || MayBeQNaN))
 
 
  324  if (!MayBeSNaN && !MayBeQNaN && Lower.isNegative() == Upper.isNegative())
 
  325    return Lower.isNegative();
 
 
  331         "Should only use the same semantics");
 
  332  if (MayBeSNaN != CR.MayBeSNaN || MayBeQNaN != CR.MayBeQNaN)
 
  334  return Lower.bitwiseIsEqual(CR.Lower) && Upper.bitwiseIsEqual(CR.Upper);
 
 
  346    assert(LowerMask <= UpperMask && 
"Range is nan-only.");
 
  348    Mask |= (UpperMask << 1) - LowerMask;
 
 
  361      OS << 
'[' << Lower << 
", " << Upper << 
']';
 
  363    if (MayBeSNaN || MayBeQNaN) {
 
  366      if (MayBeSNaN && MayBeQNaN)
 
 
  376#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 
  383         "Should only use the same semantics");
 
  387  return ConstantFPRange(std::move(NewLower), std::move(NewUpper),
 
  388                         MayBeQNaN & CR.MayBeQNaN, MayBeSNaN & CR.MayBeSNaN);
 
 
  393         "Should only use the same semantics");
 
  394  return ConstantFPRange(
minnum(Lower, CR.Lower), 
maxnum(Upper, CR.Upper),
 
  395                         MayBeQNaN | CR.MayBeQNaN, MayBeSNaN | CR.MayBeSNaN);
 
 
  402  if (Lower.isNegative() == Upper.isNegative()) {
 
  403    if (Lower.isNegative())
 
  410  return ConstantFPRange(std::move(NewLower), std::move(NewUpper), MayBeQNaN,
 
 
  415  return ConstantFPRange(-Upper, -Lower, MayBeQNaN, MayBeSNaN);
 
 
  422         "Non-NaN part is empty.");
 
  423  auto &Sem = 
Lower.getSemantics();
 
  424  if (
Lower.isNegInfinity()) {
 
  428  if (
Upper.isPosInfinity()) {
 
 
  441  removeInf(NewLower, NewUpper, UnusedFlag,
 
  444  return ConstantFPRange(std::move(NewLower), std::move(NewUpper), MayBeQNaN,
 
 
  456    return getFull(DstSem);
 
  459    return getFull(DstSem);
 
  460  return ConstantFPRange(std::move(NewLower), std::move(NewUpper),
 
  461                         MayBeQNaN || MayBeSNaN,
 
 
  466  bool ResMayBeQNaN = ((MayBeQNaN || MayBeSNaN) && !
Other.isEmptySet()) ||
 
  471  bool LHSHasNegInf = 
false, LHSHasPosInf = 
false;
 
  472  APFloat LHSLower = Lower, LHSUpper = Upper;
 
  473  bool LHSFiniteIsNonEmpty =
 
  474      removeInf(LHSLower, LHSUpper, LHSHasPosInf, LHSHasNegInf);
 
  475  bool RHSHasNegInf = 
false, RHSHasPosInf = 
false;
 
  477  bool RHSFiniteIsNonEmpty =
 
  478      removeInf(RHSLower, RHSUpper, RHSHasPosInf, RHSHasNegInf);
 
  481      (LHSHasNegInf && RHSHasPosInf) || (LHSHasPosInf && RHSHasNegInf);
 
  483  bool HasNegInf = (LHSHasNegInf && (RHSFiniteIsNonEmpty || RHSHasNegInf)) ||
 
  484                   (RHSHasNegInf && (LHSFiniteIsNonEmpty || LHSHasNegInf));
 
  485  bool HasPosInf = (LHSHasPosInf && (RHSFiniteIsNonEmpty || RHSHasPosInf)) ||
 
  486                   (RHSHasPosInf && (LHSFiniteIsNonEmpty || LHSHasPosInf));
 
  487  if (LHSFiniteIsNonEmpty && RHSFiniteIsNonEmpty) {
 
  490                  : LHSLower + RHSLower;
 
  493                  : LHSUpper + RHSUpper;
 
  494    return ConstantFPRange(NewLower, NewUpper, ResMayBeQNaN,
 
  499  return ConstantFPRange(
 
 
  522  bool ZeroLowerNegative =
 
  524  bool ZeroUpperNegative =
 
  526  assert((ZeroLowerNegative || !ZeroUpperNegative) &&
 
  527         "ZeroLower is greater than ZeroUpper.");
 
 
  545           "The sign should be dropped.");
 
  548    if (!
Lower.isInfinity())
 
 
 
  556                        std::optional<SameSignRange> &NegPart,
 
  557                        std::optional<SameSignRange> &PosPart) {
 
  559         "Non-NaN part is empty.");
 
  560  if (
Lower.isNegative() == 
Upper.isNegative()) {
 
  561    if (
Lower.isNegative())
 
  567  auto &Sem = 
Lower.getSemantics();
 
 
  574  bool ResMayBeQNaN = ((MayBeQNaN || MayBeSNaN) && !
Other.isEmptySet()) ||
 
  579  std::optional<SameSignRange> LHSNeg, LHSPos, RHSNeg, RHSPos;
 
  584  auto Update = [&](std::optional<SameSignRange> &LHS,
 
  585                    std::optional<SameSignRange> &RHS, 
bool Negative) {
 
  589    ResMayBeQNaN |= LHS->HasZero && RHS->HasInf;
 
  590    ResMayBeQNaN |= RHS->HasZero && LHS->HasInf;
 
  592    if ((LHS->HasInf && RHS->HasNonZero) || (RHS->HasInf && LHS->HasNonZero))
 
  595    if (LHS->FinitePart && RHS->FinitePart) {
 
  596      APFloat NewLower = LHS->FinitePart->first * RHS->FinitePart->first;
 
  597      APFloat NewUpper = LHS->FinitePart->second * RHS->FinitePart->second;
 
  599        ResLower = 
minnum(ResLower, -NewUpper);
 
  600        ResUpper = 
maxnum(ResUpper, -NewLower);
 
  602        ResLower = 
minnum(ResLower, NewLower);
 
  603        ResUpper = 
maxnum(ResUpper, NewUpper);
 
  607  Update(LHSNeg, RHSNeg, 
false);
 
  608  Update(LHSNeg, RHSPos, 
true);
 
  609  Update(LHSPos, RHSNeg, 
true);
 
  610  Update(LHSPos, RHSPos, 
false);
 
  611  return ConstantFPRange(ResLower, ResUpper, ResMayBeQNaN, 
false);
 
 
  616  bool ResMayBeQNaN = ((MayBeQNaN || MayBeSNaN) && !
Other.isEmptySet()) ||
 
  621  std::optional<SameSignRange> LHSNeg, LHSPos, RHSNeg, RHSPos;
 
  626  auto Update = [&](std::optional<SameSignRange> &LHS,
 
  627                    std::optional<SameSignRange> &RHS, 
bool Negative) {
 
  631    ResMayBeQNaN |= LHS->HasInf && RHS->HasInf;
 
  632    ResMayBeQNaN |= LHS->HasZero && RHS->HasZero;
 
  639    bool LHSHasNonZeroFinite = LHS->FinitePart && LHS->HasNonZero;
 
  640    bool RHSHasNonZeroFinite = RHS->FinitePart && RHS->HasNonZero;
 
  642    if ((LHS->HasInf && RHS->FinitePart) ||
 
  643        (LHSHasNonZeroFinite && RHS->HasZero))
 
  646    if (LHS->FinitePart && RHS->HasInf) {
 
  648      ResLower = 
minnum(ResLower, Zero);
 
  649      ResUpper = 
maxnum(ResUpper, Zero);
 
  652    if (LHS->FinitePart && RHSHasNonZeroFinite) {
 
  653      assert(!RHS->FinitePart->second.isZero() &&
 
  654             "Divisor should be non-zero.");
 
  655      APFloat NewLower = LHS->FinitePart->first / RHS->FinitePart->second;
 
  656      APFloat NewUpper = LHS->FinitePart->second /
 
  657                         (RHS->FinitePart->first.isZero()
 
  659                              : RHS->FinitePart->first);
 
  661        ResLower = 
minnum(ResLower, -NewUpper);
 
  662        ResUpper = 
maxnum(ResUpper, -NewLower);
 
  664        ResLower = 
minnum(ResLower, NewLower);
 
  665        ResUpper = 
maxnum(ResUpper, NewUpper);
 
  669  Update(LHSNeg, RHSNeg, 
false);
 
  670  Update(LHSNeg, RHSPos, 
true);
 
  671  Update(LHSPos, RHSNeg, 
true);
 
  672  Update(LHSPos, RHSPos, 
false);
 
  673  return ConstantFPRange(ResLower, ResUpper, ResMayBeQNaN, 
false);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static APFloat::cmpResult strictCompare(const APFloat &LHS, const APFloat &RHS)
static ConstantFPRange extendZeroIfEqual(const ConstantFPRange &CR, FCmpInst::Predicate Pred)
Make sure that +0/-0 are both included in the range.
static bool fcmpPredExcludesEqual(FCmpInst::Predicate Pred)
Return true for ULT/UGT/OLT/OGT.
static void splitPosNeg(const APFloat &Lower, const APFloat &Upper, std::optional< SameSignRange > &NegPart, std::optional< SameSignRange > &PosPart)
Split the range into positive and negative components.
static bool removeInf(APFloat &Lower, APFloat &Upper, bool &HasPosInf, bool &HasNegInf)
Return true if the finite part is not empty after removing infinities.
static ConstantFPRange makeLessThan(APFloat V, FCmpInst::Predicate Pred)
Return [-inf, V) or [-inf, V].
static void canonicalizeRange(APFloat &Lower, APFloat &Upper)
static ConstantFPRange makeGreaterThan(APFloat V, FCmpInst::Predicate Pred)
Return (V, +inf] or [V, +inf].
static bool isNonCanonicalEmptySet(const APFloat &Lower, const APFloat &Upper)
static ConstantFPRange setNaNField(const ConstantFPRange &CR, FCmpInst::Predicate Pred)
Utilities for dealing with flags related to floating point properties and mode controls.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
cmpResult
IEEE-754R 5.11: Floating Point Comparison Relations.
llvm::RoundingMode roundingMode
IEEE-754R 4.3: Rounding-direction attributes.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
bool bitwiseIsEqual(const APFloat &RHS) const
const fltSemantics & getSemantics() const
static APFloat getLargest(const fltSemantics &Sem, bool Negative=false)
Returns the largest finite number in the given semantics.
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
static APFloat getSmallest(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) finite number in the given semantics.
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
static LLVM_ABI bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
static LLVM_ABI bool isOrdered(Predicate predicate)
Determine if the predicate is an ordered operation.
This class represents a range of floating-point values.
LLVM_ABI ConstantFPRange add(const ConstantFPRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
LLVM_ABI ConstantFPRange abs() const
Calculate absolute value range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
bool containsQNaN() const
static LLVM_ABI ConstantFPRange getNonNaN(const fltSemantics &Sem)
Helper for [-inf, inf] to represent all non-NaN values.
bool containsSNaN() const
LLVM_ABI const APFloat * getSingleElement(bool ExcludesNaN=false) const
If this set contains a single element, return it, otherwise return null.
static LLVM_ABI ConstantFPRange makeSatisfyingFCmpRegion(FCmpInst::Predicate Pred, const ConstantFPRange &Other)
Produce the largest range such that all values in the returned range satisfy the given predicate with...
LLVM_ABI bool operator==(const ConstantFPRange &CR) const
Return true if this range is equal to another range.
static LLVM_ABI ConstantFPRange getNaNOnly(const fltSemantics &Sem, bool MayBeQNaN, bool MayBeSNaN)
Create a range which only contains NaNs.
LLVM_ABI ConstantFPRange unionWith(const ConstantFPRange &CR) const
Return the smallest range that results from the union of this range with another range.
LLVM_ABI void flushDenormals(DenormalMode::DenormalModeKind Mode)
Flush denormal values to zero according to the specified mode.
LLVM_ABI ConstantFPRange sub(const ConstantFPRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
LLVM_ABI std::optional< bool > getSignBit() const
Return true if the sign bit of all values in this range is 1.
static LLVM_ABI ConstantFPRange makeAllowedFCmpRegion(FCmpInst::Predicate Pred, const ConstantFPRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
LLVM_ABI bool isNaNOnly() const
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI ConstantFPRange mul(const ConstantFPRange &Other) const
Return a new range representing the possible values resulting from a multiplication of a value in thi...
static LLVM_ABI ConstantFPRange getFinite(const fltSemantics &Sem)
Helper for (-inf, inf) to represent all finite values.
LLVM_ABI void print(raw_ostream &OS) const
Print out the bounds to a stream.
LLVM_ABI ConstantFPRange cast(const fltSemantics &DstSem, APFloat::roundingMode RM=APFloat::rmNearestTiesToEven) const
Return a new range in the specified format with the specified rounding mode.
LLVM_ABI ConstantFPRange intersectWith(const ConstantFPRange &CR) const
Return the range that results from the intersection of this range with another range.
LLVM_ABI ConstantFPRange div(const ConstantFPRange &Other) const
Return a new range representing the possible values resulting from a division of a value in this rang...
LLVM_ABI void dump() const
Allow printing from a debugger easily.
LLVM_ABI ConstantFPRange negate() const
Calculate range of negated values.
LLVM_ABI FPClassTest classify() const
Return the FPClassTest which will return true for the value.
LLVM_ABI ConstantFPRange getWithoutInf() const
Get the range without infinities.
LLVM_ABI bool fcmp(FCmpInst::Predicate Pred, const ConstantFPRange &Other) const
Does the predicate Pred hold between ranges this and Other?
LLVM_ABI bool contains(const APFloat &Val) const
Return true if the specified value is in the set.
const APFloat & getUpper() const
Return the upper value for this range.
const APFloat & getLower() const
Return the lower value for this range.
static LLVM_ABI std::optional< ConstantFPRange > makeExactFCmpRegion(FCmpInst::Predicate Pred, const APFloat &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
const fltSemantics & getSemantics() const
Get the semantics of this ConstantFPRange.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2008 maxNum semantics.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2008 minNum semantics.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
Represent a contiguous range of values sharing the same sign.
SameSignRange(const APFloat &Lower, const APFloat &Upper)
std::optional< std::pair< APFloat, APFloat > > FinitePart
DenormalModeKind
Represent handled modes for denormal (aka subnormal) modes in the floating point environment.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
@ IEEE
IEEE-754 denormal numbers preserved.