Skip to content

Commit 1afb524

Browse files
committed
add basic implementation
1 parent 2e76f7c commit 1afb524

File tree

3 files changed

+315
-18
lines changed

3 files changed

+315
-18
lines changed

llvm/include/llvm/IR/ConstantFPRange.h

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@
1010
// for a floating-point value. This keeps track of a lower and upper bound for
1111
// the constant.
1212
//
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+
//
1318
//===----------------------------------------------------------------------===//
1419

1520
#ifndef LLVM_IR_CONSTANTFPRANGE_H
1621
#define LLVM_IR_CONSTANTFPRANGE_H
1722

1823
#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"
2225
#include <optional>
2326

2427
namespace llvm {
@@ -29,10 +32,8 @@ struct KnownFPClass;
2932
/// This class represents a range of floating-point values.
3033
class [[nodiscard]] ConstantFPRange {
3134
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;
3637

3738
/// Create empty constant range with same semantics.
3839
ConstantFPRange getEmpty() const {
@@ -44,29 +45,55 @@ class [[nodiscard]] ConstantFPRange {
4445
return ConstantFPRange(getSemantics(), /*IsFullSet=*/true);
4546
}
4647

48+
void makeEmpty();
49+
void makeFull();
50+
bool isNaNOnly() const;
51+
4752
public:
53+
/// Return true if the floating point format is supported.
54+
static bool isSupportedSemantics(const fltSemantics &Sem);
55+
4856
/// 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);
5058

5159
/// Initialize a range to hold the single specified value.
5260
ConstantFPRange(const APFloat &Value);
5361

5462
/// 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);
5765

5866
/// 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);
6169
}
6270

6371
/// 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);
6674
}
6775

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);
7097

7198
/// Produce the exact range such that all values in the returned range satisfy
7299
/// the given predicate with any value contained within Other. Formally, this
@@ -113,20 +140,36 @@ class [[nodiscard]] ConstantFPRange {
113140
/// Return true if the sign bit of all values in this range is 1.
114141
/// Return false if the sign bit of all values in this range is 0.
115142
/// Otherwise, return std::nullopt.
116-
std::optional<bool> getSignBit();
143+
std::optional<bool> getSignBit() const;
117144

118145
/// Return true if this range is equal to another range.
119146
bool operator==(const ConstantFPRange &CR) const;
147+
/// Return true if this range is not equal to another range.
120148
bool operator!=(const ConstantFPRange &CR) const { return !operator==(CR); }
121149

150+
/// Return the FPClassTest which will return true for the value.
151+
FPClassTest classify() const;
152+
122153
/// Return known floating-point classes for values in this range.
123-
KnownFPClass toKnownFPClass();
154+
KnownFPClass toKnownFPClass() const;
124155

125156
/// Print out the bounds to a stream.
126157
void print(raw_ostream &OS) const;
127158

128159
/// Allow printing from a debugger easily.
129160
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;
130173
};
131174

132175
inline raw_ostream &operator<<(raw_ostream &OS, const ConstantFPRange &CR) {

llvm/lib/IR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_llvm_component_library(LLVMCore
88
BuiltinGCs.cpp
99
Comdat.cpp
1010
ConstantFold.cpp
11+
ConstantFPRange.cpp
1112
ConstantRange.cpp
1213
ConstantRangeList.cpp
1314
Constants.cpp

0 commit comments

Comments
 (0)