|
|
|||
File indexing completed on 2026-05-10 08:43:57
0001 //===- ConstantFPRange.h - Represent a range for floating-point -*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // Represent a range of possible values that may occur when the program is run 0010 // for a floating-point value. This keeps track of a lower and upper bound for 0011 // the constant. 0012 // 0013 // Range = [Lower, Upper] U (MayBeQNaN ? QNaN : {}) U (MayBeSNaN ? SNaN : {}) 0014 // Specifically, [inf, -inf] represents an empty set. 0015 // Note: 0016 // 1. Bounds are inclusive. 0017 // 2. -0 is considered to be less than 0. That is, range [0, 0] doesn't contain 0018 // -0. 0019 // 3. Currently wrapping ranges are not supported. 0020 // 0021 //===----------------------------------------------------------------------===// 0022 0023 #ifndef LLVM_IR_CONSTANTFPRANGE_H 0024 #define LLVM_IR_CONSTANTFPRANGE_H 0025 0026 #include "llvm/ADT/APFloat.h" 0027 #include "llvm/IR/Instructions.h" 0028 #include <optional> 0029 0030 namespace llvm { 0031 0032 class raw_ostream; 0033 struct KnownFPClass; 0034 0035 /// This class represents a range of floating-point values. 0036 class [[nodiscard]] ConstantFPRange { 0037 APFloat Lower, Upper; 0038 bool MayBeQNaN : 1; 0039 bool MayBeSNaN : 1; 0040 0041 /// Create empty constant range with same semantics. 0042 ConstantFPRange getEmpty() const { 0043 return ConstantFPRange(getSemantics(), /*IsFullSet=*/false); 0044 } 0045 0046 /// Create full constant range with same semantics. 0047 ConstantFPRange getFull() const { 0048 return ConstantFPRange(getSemantics(), /*IsFullSet=*/true); 0049 } 0050 0051 void makeEmpty(); 0052 void makeFull(); 0053 0054 /// Initialize a full or empty set for the specified semantics. 0055 explicit ConstantFPRange(const fltSemantics &Sem, bool IsFullSet); 0056 0057 public: 0058 /// Initialize a range to hold the single specified value. 0059 explicit ConstantFPRange(const APFloat &Value); 0060 0061 /// Initialize a range of values explicitly. 0062 /// Note: If \p LowerVal is greater than \p UpperVal, please use the canonical 0063 /// form [Inf, -Inf]. 0064 ConstantFPRange(APFloat LowerVal, APFloat UpperVal, bool MayBeQNaN, 0065 bool MayBeSNaN); 0066 0067 /// Create empty constant range with the given semantics. 0068 static ConstantFPRange getEmpty(const fltSemantics &Sem) { 0069 return ConstantFPRange(Sem, /*IsFullSet=*/false); 0070 } 0071 0072 /// Create full constant range with the given semantics. 0073 static ConstantFPRange getFull(const fltSemantics &Sem) { 0074 return ConstantFPRange(Sem, /*IsFullSet=*/true); 0075 } 0076 0077 /// Helper for (-inf, inf) to represent all finite values. 0078 static ConstantFPRange getFinite(const fltSemantics &Sem); 0079 0080 /// Helper for [-inf, inf] to represent all non-NaN values. 0081 static ConstantFPRange getNonNaN(const fltSemantics &Sem); 0082 0083 /// Create a range which doesn't contain NaNs. 0084 static ConstantFPRange getNonNaN(APFloat LowerVal, APFloat UpperVal) { 0085 return ConstantFPRange(std::move(LowerVal), std::move(UpperVal), 0086 /*MayBeQNaN=*/false, /*MayBeSNaN=*/false); 0087 } 0088 0089 /// Create a range which may contain NaNs. 0090 static ConstantFPRange getMayBeNaN(APFloat LowerVal, APFloat UpperVal) { 0091 return ConstantFPRange(std::move(LowerVal), std::move(UpperVal), 0092 /*MayBeQNaN=*/true, /*MayBeSNaN=*/true); 0093 } 0094 0095 /// Create a range which only contains NaNs. 0096 static ConstantFPRange getNaNOnly(const fltSemantics &Sem, bool MayBeQNaN, 0097 bool MayBeSNaN); 0098 0099 /// Produce the smallest range such that all values that may satisfy the given 0100 /// predicate with any value contained within Other is contained in the 0101 /// returned range. Formally, this returns a superset of 0102 /// 'union over all y in Other . { x : fcmp op x y is true }'. If the exact 0103 /// answer is not representable as a ConstantFPRange, the return value will be 0104 /// a proper superset of the above. 0105 /// 0106 /// Example: Pred = ole and Other = float [2, 5] returns Result = [-inf, 5] 0107 static ConstantFPRange makeAllowedFCmpRegion(FCmpInst::Predicate Pred, 0108 const ConstantFPRange &Other); 0109 0110 /// Produce the largest range such that all values in the returned range 0111 /// satisfy the given predicate with all values contained within Other. 0112 /// Formally, this returns a subset of 0113 /// 'intersection over all y in Other . { x : fcmp op x y is true }'. If the 0114 /// exact answer is not representable as a ConstantFPRange, the return value 0115 /// will be a proper subset of the above. 0116 /// 0117 /// Example: Pred = ole and Other = float [2, 5] returns [-inf, 2] 0118 static ConstantFPRange makeSatisfyingFCmpRegion(FCmpInst::Predicate Pred, 0119 const ConstantFPRange &Other); 0120 0121 /// Produce the exact range such that all values in the returned range satisfy 0122 /// the given predicate with any value contained within Other. Formally, this 0123 /// returns { x : fcmp op x Other is true }. 0124 /// 0125 /// Example: Pred = olt and Other = float 3 returns [-inf, 3) 0126 /// If the exact answer is not representable as a ConstantFPRange, returns 0127 /// std::nullopt. 0128 static std::optional<ConstantFPRange> 0129 makeExactFCmpRegion(FCmpInst::Predicate Pred, const APFloat &Other); 0130 0131 /// Does the predicate \p Pred hold between ranges this and \p Other? 0132 /// NOTE: false does not mean that inverse predicate holds! 0133 bool fcmp(FCmpInst::Predicate Pred, const ConstantFPRange &Other) const; 0134 0135 /// Return the lower value for this range. 0136 const APFloat &getLower() const { return Lower; } 0137 0138 /// Return the upper value for this range. 0139 const APFloat &getUpper() const { return Upper; } 0140 0141 bool containsNaN() const { return MayBeQNaN || MayBeSNaN; } 0142 bool containsQNaN() const { return MayBeQNaN; } 0143 bool containsSNaN() const { return MayBeSNaN; } 0144 bool isNaNOnly() const; 0145 0146 /// Get the semantics of this ConstantFPRange. 0147 const fltSemantics &getSemantics() const { return Lower.getSemantics(); } 0148 0149 /// Return true if this set contains all of the elements possible 0150 /// for this data-type. 0151 bool isFullSet() const; 0152 0153 /// Return true if this set contains no members. 0154 bool isEmptySet() const; 0155 0156 /// Return true if the specified value is in the set. 0157 bool contains(const APFloat &Val) const; 0158 0159 /// Return true if the other range is a subset of this one. 0160 bool contains(const ConstantFPRange &CR) const; 0161 0162 /// If this set contains a single element, return it, otherwise return null. 0163 /// If \p ExcludesNaN is true, return the non-NaN single element. 0164 const APFloat *getSingleElement(bool ExcludesNaN = false) const; 0165 0166 /// Return true if this set contains exactly one member. 0167 /// If \p ExcludesNaN is true, return true if this set contains exactly one 0168 /// non-NaN member. 0169 bool isSingleElement(bool ExcludesNaN = false) const { 0170 return getSingleElement(ExcludesNaN) != nullptr; 0171 } 0172 0173 /// Return true if the sign bit of all values in this range is 1. 0174 /// Return false if the sign bit of all values in this range is 0. 0175 /// Otherwise, return std::nullopt. 0176 std::optional<bool> getSignBit() const; 0177 0178 /// Return true if this range is equal to another range. 0179 bool operator==(const ConstantFPRange &CR) const; 0180 /// Return true if this range is not equal to another range. 0181 bool operator!=(const ConstantFPRange &CR) const { return !operator==(CR); } 0182 0183 /// Return the FPClassTest which will return true for the value. 0184 FPClassTest classify() const; 0185 0186 /// Print out the bounds to a stream. 0187 void print(raw_ostream &OS) const; 0188 0189 /// Allow printing from a debugger easily. 0190 void dump() const; 0191 0192 /// Return the range that results from the intersection of this range with 0193 /// another range. 0194 ConstantFPRange intersectWith(const ConstantFPRange &CR) const; 0195 0196 /// Return the smallest range that results from the union of this range 0197 /// with another range. The resultant range is guaranteed to include the 0198 /// elements of both sets, but may contain more. 0199 ConstantFPRange unionWith(const ConstantFPRange &CR) const; 0200 }; 0201 0202 inline raw_ostream &operator<<(raw_ostream &OS, const ConstantFPRange &CR) { 0203 CR.print(OS); 0204 return OS; 0205 } 0206 0207 } // end namespace llvm 0208 0209 #endif // LLVM_IR_CONSTANTFPRANGE_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|