LLVM 20.0.0git
ConstantFPRange.h
Go to the documentation of this file.
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// Range = [Lower, Upper] U (MayBeQNaN ? QNaN : {}) U (MayBeSNaN ? SNaN : {})
14// Specifically, [inf, -inf] represents an empty set.
15// Note:
16// 1. Bounds are inclusive.
17// 2. -0 is considered to be less than 0. That is, range [0, 0] doesn't contain
18// -0.
19// 3. Currently wrapping ranges are not supported.
20//
21//===----------------------------------------------------------------------===//
22
23#ifndef LLVM_IR_CONSTANTFPRANGE_H
24#define LLVM_IR_CONSTANTFPRANGE_H
25
26#include "llvm/ADT/APFloat.h"
28#include <optional>
29
30namespace llvm {
31
32class raw_ostream;
33struct KnownFPClass;
34
35/// This class represents a range of floating-point values.
36class [[nodiscard]] ConstantFPRange {
37 APFloat Lower, Upper;
38 bool MayBeQNaN : 1;
39 bool MayBeSNaN : 1;
40
41 /// Create empty constant range with same semantics.
42 ConstantFPRange getEmpty() const {
43 return ConstantFPRange(getSemantics(), /*IsFullSet=*/false);
44 }
45
46 /// Create full constant range with same semantics.
47 ConstantFPRange getFull() const {
48 return ConstantFPRange(getSemantics(), /*IsFullSet=*/true);
49 }
50
51 void makeEmpty();
52 void makeFull();
53
54 /// Initialize a full or empty set for the specified semantics.
55 explicit ConstantFPRange(const fltSemantics &Sem, bool IsFullSet);
56
57public:
58 /// Initialize a range to hold the single specified value.
59 explicit ConstantFPRange(const APFloat &Value);
60
61 /// Initialize a range of values explicitly.
62 /// Note: If \p LowerVal is greater than \p UpperVal, please use the canonical
63 /// form [Inf, -Inf].
64 ConstantFPRange(APFloat LowerVal, APFloat UpperVal, bool MayBeQNaN,
65 bool MayBeSNaN);
66
67 /// Create empty constant range with the given semantics.
69 return ConstantFPRange(Sem, /*IsFullSet=*/false);
70 }
71
72 /// Create full constant range with the given semantics.
74 return ConstantFPRange(Sem, /*IsFullSet=*/true);
75 }
76
77 /// Helper for (-inf, inf) to represent all finite values.
78 static ConstantFPRange getFinite(const fltSemantics &Sem);
79
80 /// Helper for [-inf, inf] to represent all non-NaN values.
81 static ConstantFPRange getNonNaN(const fltSemantics &Sem);
82
83 /// Create a range which doesn't contain NaNs.
84 static ConstantFPRange getNonNaN(APFloat LowerVal, APFloat UpperVal) {
85 return ConstantFPRange(std::move(LowerVal), std::move(UpperVal),
86 /*MayBeQNaN=*/false, /*MayBeSNaN=*/false);
87 }
88
89 /// Create a range which may contain NaNs.
90 static ConstantFPRange getMayBeNaN(APFloat LowerVal, APFloat UpperVal) {
91 return ConstantFPRange(std::move(LowerVal), std::move(UpperVal),
92 /*MayBeQNaN=*/true, /*MayBeSNaN=*/true);
93 }
94
95 /// Create a range which only contains NaNs.
96 static ConstantFPRange getNaNOnly(const fltSemantics &Sem, bool MayBeQNaN,
97 bool MayBeSNaN);
98
99 /// Produce the smallest range such that all values that may satisfy the given
100 /// predicate with any value contained within Other is contained in the
101 /// returned range. Formally, this returns a superset of
102 /// 'union over all y in Other . { x : fcmp op x y is true }'. If the exact
103 /// answer is not representable as a ConstantFPRange, the return value will be
104 /// a proper superset of the above.
105 ///
106 /// Example: Pred = ole and Other = float [2, 5] returns Result = [-inf, 5]
107 static ConstantFPRange makeAllowedFCmpRegion(FCmpInst::Predicate Pred,
108 const ConstantFPRange &Other);
109
110 /// Produce the largest range such that all values in the returned range
111 /// satisfy the given predicate with all values contained within Other.
112 /// Formally, this returns a subset of
113 /// 'intersection over all y in Other . { x : fcmp op x y is true }'. If the
114 /// exact answer is not representable as a ConstantFPRange, the return value
115 /// will be a proper subset of the above.
116 ///
117 /// Example: Pred = ole and Other = float [2, 5] returns [-inf, 2]
118 static ConstantFPRange makeSatisfyingFCmpRegion(FCmpInst::Predicate Pred,
119 const ConstantFPRange &Other);
120
121 /// Produce the exact range such that all values in the returned range satisfy
122 /// the given predicate with any value contained within Other. Formally, this
123 /// returns { x : fcmp op x Other is true }.
124 ///
125 /// Example: Pred = olt and Other = float 3 returns [-inf, 3)
126 /// If the exact answer is not representable as a ConstantFPRange, returns
127 /// std::nullopt.
128 static std::optional<ConstantFPRange>
129 makeExactFCmpRegion(FCmpInst::Predicate Pred, const APFloat &Other);
130
131 /// Does the predicate \p Pred hold between ranges this and \p Other?
132 /// NOTE: false does not mean that inverse predicate holds!
133 bool fcmp(FCmpInst::Predicate Pred, const ConstantFPRange &Other) const;
134
135 /// Return the lower value for this range.
136 const APFloat &getLower() const { return Lower; }
137
138 /// Return the upper value for this range.
139 const APFloat &getUpper() const { return Upper; }
140
141 bool containsNaN() const { return MayBeQNaN || MayBeSNaN; }
142 bool containsQNaN() const { return MayBeQNaN; }
143 bool containsSNaN() const { return MayBeSNaN; }
144 bool isNaNOnly() const;
145
146 /// Get the semantics of this ConstantFPRange.
147 const fltSemantics &getSemantics() const { return Lower.getSemantics(); }
148
149 /// Return true if this set contains all of the elements possible
150 /// for this data-type.
151 bool isFullSet() const;
152
153 /// Return true if this set contains no members.
154 bool isEmptySet() const;
155
156 /// Return true if the specified value is in the set.
157 bool contains(const APFloat &Val) const;
158
159 /// Return true if the other range is a subset of this one.
160 bool contains(const ConstantFPRange &CR) const;
161
162 /// If this set contains a single element, return it, otherwise return null.
163 /// If \p ExcludesNaN is true, return the non-NaN single element.
164 const APFloat *getSingleElement(bool ExcludesNaN = false) const;
165
166 /// Return true if this set contains exactly one member.
167 /// If \p ExcludesNaN is true, return true if this set contains exactly one
168 /// non-NaN member.
169 bool isSingleElement(bool ExcludesNaN = false) const {
170 return getSingleElement(ExcludesNaN) != nullptr;
171 }
172
173 /// Return true if the sign bit of all values in this range is 1.
174 /// Return false if the sign bit of all values in this range is 0.
175 /// Otherwise, return std::nullopt.
176 std::optional<bool> getSignBit() const;
177
178 /// Return true if this range is equal to another range.
179 bool operator==(const ConstantFPRange &CR) const;
180 /// Return true if this range is not equal to another range.
181 bool operator!=(const ConstantFPRange &CR) const { return !operator==(CR); }
182
183 /// Return the FPClassTest which will return true for the value.
184 FPClassTest classify() const;
185
186 /// Print out the bounds to a stream.
187 void print(raw_ostream &OS) const;
188
189 /// Allow printing from a debugger easily.
190 void dump() const;
191
192 /// Return the range that results from the intersection of this range with
193 /// another range.
194 ConstantFPRange intersectWith(const ConstantFPRange &CR) const;
195
196 /// Return the smallest range that results from the union of this range
197 /// with another range. The resultant range is guaranteed to include the
198 /// elements of both sets, but may contain more.
199 ConstantFPRange unionWith(const ConstantFPRange &CR) const;
200};
201
203 CR.print(OS);
204 return OS;
205}
206
207} // end namespace llvm
208
209#endif // LLVM_IR_CONSTANTFPRANGE_H
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
std::optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1313
raw_pwrite_stream & OS
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:673
This class represents a range of floating-point values.
static ConstantFPRange getMayBeNaN(APFloat LowerVal, APFloat UpperVal)
Create a range which may contain NaNs.
static ConstantFPRange getFull(const fltSemantics &Sem)
Create full constant range with the given semantics.
bool isSingleElement(bool ExcludesNaN=false) const
Return true if this set contains exactly one member.
void print(raw_ostream &OS) const
Print out the bounds to a stream.
bool operator!=(const ConstantFPRange &CR) const
Return true if this range is not equal to another range.
static ConstantFPRange getEmpty(const fltSemantics &Sem)
Create empty constant range with the given semantics.
static ConstantFPRange getNonNaN(APFloat LowerVal, APFloat UpperVal)
Create a range which doesn't contain NaNs.
const APFloat & getUpper() const
Return the upper value for this range.
const APFloat & getLower() const
Return the lower value for this range.
const fltSemantics & getSemantics() const
Get the semantics of this ConstantFPRange.
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:303