@@ -50,7 +50,6 @@ class [[nodiscard]] ConstantFPRange {
5050
5151 void makeEmpty ();
5252 void makeFull ();
53- bool isNaNOnly () const ;
5453
5554 // / Initialize a full or empty set for the specified semantics.
5655 explicit ConstantFPRange (const fltSemantics &Sem, bool IsFullSet);
@@ -78,6 +77,9 @@ class [[nodiscard]] ConstantFPRange {
7877 // / Helper for (-inf, inf) to represent all finite values.
7978 static ConstantFPRange getFinite (const fltSemantics &Sem);
8079
80+ // / Helper for [-inf, inf] to represent all non-NaN values.
81+ static ConstantFPRange getNonNaN (const fltSemantics &Sem);
82+
8183 // / Create a range which doesn't contain NaNs.
8284 static ConstantFPRange getNonNaN (APFloat LowerVal, APFloat UpperVal) {
8385 return ConstantFPRange (std::move (LowerVal), std::move (UpperVal),
@@ -118,13 +120,13 @@ class [[nodiscard]] ConstantFPRange {
118120
119121 // / Produce the exact range such that all values in the returned range satisfy
120122 // / the given predicate with any value contained within Other. Formally, this
121- // / returns the exact answer when the superset of 'union over all y in Other
122- // / is exactly same as the subset of intersection over all y in Other.
123- // / { x : fcmp op x y is true}'.
123+ // / returns { x : fcmp op x Other is true }.
124124 // /
125125 // / Example: Pred = olt and Other = float 3 returns [-inf, 3)
126- static ConstantFPRange makeExactFCmpRegion (FCmpInst::Predicate Pred,
127- const APFloat &Other);
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);
128130
129131 // / Does the predicate \p Pred hold between ranges this and \p Other?
130132 // / NOTE: false does not mean that inverse predicate holds!
@@ -139,6 +141,7 @@ class [[nodiscard]] ConstantFPRange {
139141 bool containsNaN () const { return MayBeQNaN || MayBeSNaN; }
140142 bool containsQNaN () const { return MayBeQNaN; }
141143 bool containsSNaN () const { return MayBeSNaN; }
144+ bool isNaNOnly () const ;
142145
143146 // / Get the semantics of this ConstantFPRange.
144147 const fltSemantics &getSemantics () const { return Lower.getSemantics (); }
@@ -157,10 +160,15 @@ class [[nodiscard]] ConstantFPRange {
157160 bool contains (const ConstantFPRange &CR) const ;
158161
159162 // / If this set contains a single element, return it, otherwise return null.
160- const APFloat *getSingleElement () const ;
163+ // / If \p ExcludesNaN is true, return the non-NaN single element.
164+ const APFloat *getSingleElement (bool ExcludesNaN = false ) const ;
161165
162166 // / Return true if this set contains exactly one member.
163- bool isSingleElement () const { return getSingleElement () != nullptr ; }
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+ }
164172
165173 // / Return true if the sign bit of all values in this range is 1.
166174 // / Return false if the sign bit of all values in this range is 0.
@@ -185,7 +193,7 @@ class [[nodiscard]] ConstantFPRange {
185193 // / another range.
186194 ConstantFPRange intersectWith (const ConstantFPRange &CR) const ;
187195
188- // / Return the range that results from the union of this range
196+ // / Return the smallest range that results from the union of this range
189197 // / with another range. The resultant range is guaranteed to include the
190198 // / elements of both sets, but may contain more.
191199 ConstantFPRange unionWith (const ConstantFPRange &CR) const ;
0 commit comments