10
10
// for a floating-point value. This keeps track of a lower and upper bound for
11
11
// the constant.
12
12
//
13
+ // Range = [Lower, Upper] U (MayBeQNaN ? QNaN : {}) U (MayBeSNaN ? SNaN : {})
14
+ // Specifically, [inf, -inf] represents an empty set.
15
+ // Note: -0 is considered to be less than 0. That is, range [0, 0] doesn't
16
+ // contain -0.
17
+ //
13
18
// ===----------------------------------------------------------------------===//
14
19
15
20
#ifndef LLVM_IR_CONSTANTFPRANGE_H
16
21
#define LLVM_IR_CONSTANTFPRANGE_H
17
22
18
23
#include " llvm/ADT/APFloat.h"
19
- #include " llvm/IR/InstrTypes.h"
20
- #include " llvm/IR/Instruction.h"
21
- #include " llvm/Support/Compiler.h"
24
+ #include " llvm/IR/Instructions.h"
22
25
#include < optional>
23
26
24
27
namespace llvm {
@@ -29,10 +32,8 @@ struct KnownFPClass;
29
32
// / This class represents a range of floating-point values.
30
33
class [[nodiscard]] ConstantFPRange {
31
34
APFloat Lower, Upper;
32
- bool MaybeQNaN : 1 ;
33
- bool MaybeSNaN : 1 ;
34
- bool SignBitMaybeZero : 1 ;
35
- bool SignBitMaybeOne : 1 ;
35
+ bool MayBeQNaN : 1 ;
36
+ bool MayBeSNaN : 1 ;
36
37
37
38
// / Create empty constant range with same semantics.
38
39
ConstantFPRange getEmpty () const {
@@ -44,29 +45,55 @@ class [[nodiscard]] ConstantFPRange {
44
45
return ConstantFPRange (getSemantics (), /* IsFullSet=*/ true );
45
46
}
46
47
48
+ void makeEmpty ();
49
+ void makeFull ();
50
+ bool isNaNOnly () const ;
51
+
47
52
public:
53
+ // / Return true if the floating point format is supported.
54
+ static bool isSupportedSemantics (const fltSemantics &Sem);
55
+
48
56
// / Initialize a full or empty set for the specified semantics.
49
- explicit ConstantFPRange (const fltSemantics &FloatSema , bool IsFullSet);
57
+ explicit ConstantFPRange (const fltSemantics &Sem , bool IsFullSet);
50
58
51
59
// / Initialize a range to hold the single specified value.
52
60
ConstantFPRange (const APFloat &Value);
53
61
54
62
// / Initialize a range of values explicitly.
55
- ConstantFPRange (APFloat Lower , APFloat Upper , bool MaybeQNaN, bool MaybeSNaN ,
56
- bool SignBitMaybeZero, bool SignBitMaybeOne );
63
+ ConstantFPRange (APFloat LowerVal , APFloat UpperVal , bool MayBeQNaN = true ,
64
+ bool MaybeSNaN = true );
57
65
58
66
// / Create empty constant range with the given semantics.
59
- static ConstantFPRange getEmpty (const fltSemantics &FloatSema ) {
60
- return ConstantFPRange (FloatSema , /* IsFullSet=*/ false );
67
+ static ConstantFPRange getEmpty (const fltSemantics &Sem ) {
68
+ return ConstantFPRange (Sem , /* IsFullSet=*/ false );
61
69
}
62
70
63
71
// / Create full constant range with the given semantics.
64
- static ConstantFPRange getFull (const fltSemantics &FloatSema ) {
65
- return ConstantFPRange (FloatSema , /* IsFullSet=*/ true );
72
+ static ConstantFPRange getFull (const fltSemantics &Sem ) {
73
+ return ConstantFPRange (Sem , /* IsFullSet=*/ true );
66
74
}
67
75
68
- // / Initialize a range based on a known floating-point classes constraint.
69
- static ConstantFPRange fromKnownFPClass (const KnownFPClass &Known);
76
+ // / Produce the smallest range such that all values that may satisfy the given
77
+ // / predicate with any value contained within Other is contained in the
78
+ // / returned range. Formally, this returns a superset of
79
+ // / 'union over all y in Other . { x : fcmp op x y is true }'. If the exact
80
+ // / answer is not representable as a ConstantRange, the return value will be a
81
+ // / proper superset of the above.
82
+ // /
83
+ // / Example: Pred = ole and Other = float [2, 5] returns Result = [-inf, 5]
84
+ static ConstantFPRange makeAllowedFCmpRegion (FCmpInst::Predicate Pred,
85
+ const ConstantFPRange &Other);
86
+
87
+ // / Produce the largest range such that all values in the returned range
88
+ // / satisfy the given predicate with all values contained within Other.
89
+ // / Formally, this returns a subset of
90
+ // / 'intersection over all y in Other . { x : fcmp op x y is true }'. If the
91
+ // / exact answer is not representable as a ConstantRange, the return value
92
+ // / will be a proper subset of the above.
93
+ // /
94
+ // / Example: Pred = ole and Other = float [2, 5] returns [-inf, 2]
95
+ static ConstantFPRange makeSatisfyingFCmpRegion (FCmpInst::Predicate Pred,
96
+ const ConstantFPRange &Other);
70
97
71
98
// / Produce the exact range such that all values in the returned range satisfy
72
99
// / the given predicate with any value contained within Other. Formally, this
@@ -113,20 +140,36 @@ class [[nodiscard]] ConstantFPRange {
113
140
// / Return true if the sign bit of all values in this range is 1.
114
141
// / Return false if the sign bit of all values in this range is 0.
115
142
// / Otherwise, return std::nullopt.
116
- std::optional<bool > getSignBit ();
143
+ std::optional<bool > getSignBit () const ;
117
144
118
145
// / Return true if this range is equal to another range.
119
146
bool operator ==(const ConstantFPRange &CR) const ;
147
+ // / Return true if this range is not equal to another range.
120
148
bool operator !=(const ConstantFPRange &CR) const { return !operator ==(CR); }
121
149
150
+ // / Return the FPClassTest which will return true for the value.
151
+ FPClassTest classify () const ;
152
+
122
153
// / Return known floating-point classes for values in this range.
123
- KnownFPClass toKnownFPClass ();
154
+ KnownFPClass toKnownFPClass () const ;
124
155
125
156
// / Print out the bounds to a stream.
126
157
void print (raw_ostream &OS) const ;
127
158
128
159
// / Allow printing from a debugger easily.
129
160
void dump () const ;
161
+
162
+ // / Return the range that results from the intersection of this range with
163
+ // / another range.
164
+ ConstantFPRange intersectWith (const ConstantFPRange &CR) const ;
165
+
166
+ // / Return the range that results from the union of this range
167
+ // / with another range. The resultant range is guaranteed to include the
168
+ // / elements of both sets, but may contain more.
169
+ ConstantFPRange unionWith (const ConstantFPRange &CR) const ;
170
+
171
+ // / Return a new range that is the logical not of the current set.
172
+ ConstantFPRange inverse () const ;
130
173
};
131
174
132
175
inline raw_ostream &operator <<(raw_ostream &OS, const ConstantFPRange &CR) {
0 commit comments