|
| 1 | +//===- ConstantFPRange.h - Represent a range for floating-point -*- C++ -*-===// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | +// |
| 9 | +// Represent a range of possible values that may occur when the program is run |
| 10 | +// for a floating-point value. This keeps track of a lower and upper bound for |
| 11 | +// the constant. |
| 12 | +// |
| 13 | +//===----------------------------------------------------------------------===// |
| 14 | + |
| 15 | +#ifndef LLVM_IR_CONSTANTFPRANGE_H |
| 16 | +#define LLVM_IR_CONSTANTFPRANGE_H |
| 17 | + |
| 18 | +#include "llvm/ADT/APFloat.h" |
| 19 | +#include "llvm/IR/InstrTypes.h" |
| 20 | +#include "llvm/IR/Instruction.h" |
| 21 | +#include "llvm/Support/Compiler.h" |
| 22 | +#include <optional> |
| 23 | + |
| 24 | +namespace llvm { |
| 25 | + |
| 26 | +class raw_ostream; |
| 27 | +struct KnownFPClass; |
| 28 | + |
| 29 | +/// This class represents a range of floating-point values. |
| 30 | +class [[nodiscard]] ConstantFPRange { |
| 31 | + APFloat Lower, Upper; |
| 32 | + bool MaybeQNaN : 1; |
| 33 | + bool MaybeSNaN : 1; |
| 34 | + bool SignBitMaybeZero : 1; |
| 35 | + bool SignBitMaybeOne : 1; |
| 36 | + |
| 37 | + /// Create empty constant range with same semantics. |
| 38 | + ConstantFPRange getEmpty() const { |
| 39 | + return ConstantFPRange(getSemantics(), /*IsFullSet=*/false); |
| 40 | + } |
| 41 | + |
| 42 | + /// Create full constant range with same semantics. |
| 43 | + ConstantFPRange getFull() const { |
| 44 | + return ConstantFPRange(getSemantics(), /*IsFullSet=*/true); |
| 45 | + } |
| 46 | + |
| 47 | +public: |
| 48 | + /// Initialize a full or empty set for the specified semantics. |
| 49 | + explicit ConstantFPRange(const fltSemantics &FloatSema, bool IsFullSet); |
| 50 | + |
| 51 | + /// Initialize a range to hold the single specified value. |
| 52 | + ConstantFPRange(const APFloat &Value); |
| 53 | + |
| 54 | + /// Initialize a range of values explicitly. |
| 55 | + ConstantFPRange(APFloat Lower, APFloat Upper, bool MaybeQNaN, bool MaybeSNaN, |
| 56 | + bool SignBitMaybeZero, bool SignBitMaybeOne); |
| 57 | + |
| 58 | + /// Create empty constant range with the given semantics. |
| 59 | + static ConstantFPRange getEmpty(const fltSemantics &FloatSema) { |
| 60 | + return ConstantFPRange(FloatSema, /*IsFullSet=*/false); |
| 61 | + } |
| 62 | + |
| 63 | + /// Create full constant range with the given semantics. |
| 64 | + static ConstantFPRange getFull(const fltSemantics &FloatSema) { |
| 65 | + return ConstantFPRange(FloatSema, /*IsFullSet=*/true); |
| 66 | + } |
| 67 | + |
| 68 | + /// Initialize a range based on a known floating-point classes constraint. |
| 69 | + static ConstantFPRange fromKnownFPClass(const KnownFPClass &Known); |
| 70 | + |
| 71 | + /// Produce the exact range such that all values in the returned range satisfy |
| 72 | + /// the given predicate with any value contained within Other. Formally, this |
| 73 | + /// returns the exact answer when the superset of 'union over all y in Other |
| 74 | + /// is exactly same as the subset of intersection over all y in Other. |
| 75 | + /// { x : fcmp op x y is true}'. |
| 76 | + /// |
| 77 | + /// Example: Pred = olt and Other = float 3 returns [-inf, 3) |
| 78 | + static ConstantFPRange makeExactFCmpRegion(FCmpInst::Predicate Pred, |
| 79 | + const APFloat &Other); |
| 80 | + |
| 81 | + /// Does the predicate \p Pred hold between ranges this and \p Other? |
| 82 | + /// NOTE: false does not mean that inverse predicate holds! |
| 83 | + bool fcmp(FCmpInst::Predicate Pred, const ConstantFPRange &Other) const; |
| 84 | + |
| 85 | + /// Return the lower value for this range. |
| 86 | + const APFloat &getLower() const { return Lower; } |
| 87 | + |
| 88 | + /// Return the upper value for this range. |
| 89 | + const APFloat &getUpper() const { return Upper; } |
| 90 | + |
| 91 | + /// Get the semantics of this ConstantFPRange. |
| 92 | + const fltSemantics &getSemantics() const { return Lower.getSemantics(); } |
| 93 | + |
| 94 | + /// Return true if this set contains all of the elements possible |
| 95 | + /// for this data-type. |
| 96 | + bool isFullSet() const; |
| 97 | + |
| 98 | + /// Return true if this set contains no members. |
| 99 | + bool isEmptySet() const; |
| 100 | + |
| 101 | + /// Return true if the specified value is in the set. |
| 102 | + bool contains(const APFloat &Val) const; |
| 103 | + |
| 104 | + /// Return true if the other range is a subset of this one. |
| 105 | + bool contains(const ConstantFPRange &CR) const; |
| 106 | + |
| 107 | + /// If this set contains a single element, return it, otherwise return null. |
| 108 | + const APFloat *getSingleElement() const; |
| 109 | + |
| 110 | + /// Return true if this set contains exactly one member. |
| 111 | + bool isSingleElement() const { return getSingleElement() != nullptr; } |
| 112 | + |
| 113 | + /// Return true if the sign bit of all values in this range is 1. |
| 114 | + /// Return false if the sign bit of all values in this range is 0. |
| 115 | + /// Otherwise, return std::nullopt. |
| 116 | + std::optional<bool> getSignBit(); |
| 117 | + |
| 118 | + /// Return true if this range is equal to another range. |
| 119 | + bool operator==(const ConstantFPRange &CR) const; |
| 120 | + bool operator!=(const ConstantFPRange &CR) const { return !operator==(CR); } |
| 121 | + |
| 122 | + /// Return known floating-point classes for values in this range. |
| 123 | + KnownFPClass toKnownFPClass(); |
| 124 | + |
| 125 | + /// Print out the bounds to a stream. |
| 126 | + void print(raw_ostream &OS) const; |
| 127 | + |
| 128 | + /// Allow printing from a debugger easily. |
| 129 | + void dump() const; |
| 130 | +}; |
| 131 | + |
| 132 | +inline raw_ostream &operator<<(raw_ostream &OS, const ConstantFPRange &CR) { |
| 133 | + CR.print(OS); |
| 134 | + return OS; |
| 135 | +} |
| 136 | + |
| 137 | +} // end namespace llvm |
| 138 | + |
| 139 | +#endif // LLVM_IR_CONSTANTFPRANGE_H |
0 commit comments