Skip to content

Commit 9928b14

Browse files
committed
tmp
1 parent 99c43e3 commit 9928b14

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
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+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_IR_CONSTANTFPRANGE_H
16+
#define LLVM_IR_CONSTANTFPRANGE_H
17+
18+
#include "llvm/ADT/APFloat.h"
19+
#include "llvm/IR/InstrTypes.h"
20+
#include "llvm/IR/Instruction.h"
21+
#include "llvm/Support/Compiler.h"
22+
#include <optional>
23+
24+
namespace llvm {
25+
26+
class raw_ostream;
27+
struct KnownFPClass;
28+
29+
/// This class represents a range of floating-point values.
30+
class [[nodiscard]] ConstantFPRange {
31+
APFloat Lower, Upper;
32+
bool MaybeQNaN : 1;
33+
bool MaybeSNaN : 1;
34+
bool SignBitMaybeZero : 1;
35+
bool SignBitMaybeOne : 1;
36+
37+
/// Create empty constant range with same semantics.
38+
ConstantFPRange getEmpty() const {
39+
return ConstantFPRange(getSemantics(), /*IsFullSet=*/false);
40+
}
41+
42+
/// Create full constant range with same semantics.
43+
ConstantFPRange getFull() const {
44+
return ConstantFPRange(getSemantics(), /*IsFullSet=*/true);
45+
}
46+
47+
public:
48+
/// Initialize a full or empty set for the specified semantics.
49+
explicit ConstantFPRange(const fltSemantics &FloatSema, bool IsFullSet);
50+
51+
/// Initialize a range to hold the single specified value.
52+
ConstantFPRange(const APFloat &Value);
53+
54+
/// Initialize a range of values explicitly.
55+
ConstantFPRange(APFloat Lower, APFloat Upper, bool MaybeQNaN, bool MaybeSNaN,
56+
bool SignBitMaybeZero, bool SignBitMaybeOne);
57+
58+
/// Create empty constant range with the given semantics.
59+
static ConstantFPRange getEmpty(const fltSemantics &FloatSema) {
60+
return ConstantFPRange(FloatSema, /*IsFullSet=*/false);
61+
}
62+
63+
/// Create full constant range with the given semantics.
64+
static ConstantFPRange getFull(const fltSemantics &FloatSema) {
65+
return ConstantFPRange(FloatSema, /*IsFullSet=*/true);
66+
}
67+
68+
/// Initialize a range based on a known floating-point classes constraint.
69+
static ConstantFPRange fromKnownFPClass(const KnownFPClass &Known);
70+
71+
/// Produce the exact range such that all values in the returned range satisfy
72+
/// the given predicate with any value contained within Other. Formally, this
73+
/// returns the exact answer when the superset of 'union over all y in Other
74+
/// is exactly same as the subset of intersection over all y in Other.
75+
/// { x : fcmp op x y is true}'.
76+
///
77+
/// Example: Pred = olt and Other = float 3 returns [-inf, 3)
78+
static ConstantFPRange makeExactFCmpRegion(FCmpInst::Predicate Pred,
79+
const APFloat &Other);
80+
81+
/// Does the predicate \p Pred hold between ranges this and \p Other?
82+
/// NOTE: false does not mean that inverse predicate holds!
83+
bool fcmp(FCmpInst::Predicate Pred, const ConstantFPRange &Other) const;
84+
85+
/// Return the lower value for this range.
86+
const APFloat &getLower() const { return Lower; }
87+
88+
/// Return the upper value for this range.
89+
const APFloat &getUpper() const { return Upper; }
90+
91+
/// Get the semantics of this ConstantFPRange.
92+
const fltSemantics &getSemantics() const { return Lower.getSemantics(); }
93+
94+
/// Return true if this set contains all of the elements possible
95+
/// for this data-type.
96+
bool isFullSet() const;
97+
98+
/// Return true if this set contains no members.
99+
bool isEmptySet() const;
100+
101+
/// Return true if the specified value is in the set.
102+
bool contains(const APFloat &Val) const;
103+
104+
/// Return true if the other range is a subset of this one.
105+
bool contains(const ConstantFPRange &CR) const;
106+
107+
/// If this set contains a single element, return it, otherwise return null.
108+
const APFloat *getSingleElement() const;
109+
110+
/// Return true if this set contains exactly one member.
111+
bool isSingleElement() const { return getSingleElement() != nullptr; }
112+
113+
/// Return true if the sign bit of all values in this range is 1.
114+
/// Return false if the sign bit of all values in this range is 0.
115+
/// Otherwise, return std::nullopt.
116+
std::optional<bool> getSignBit();
117+
118+
/// Return true if this range is equal to another range.
119+
bool operator==(const ConstantFPRange &CR) const;
120+
bool operator!=(const ConstantFPRange &CR) const { return !operator==(CR); }
121+
122+
/// Return known floating-point classes for values in this range.
123+
KnownFPClass toKnownFPClass();
124+
125+
/// Print out the bounds to a stream.
126+
void print(raw_ostream &OS) const;
127+
128+
/// Allow printing from a debugger easily.
129+
void dump() const;
130+
};
131+
132+
inline raw_ostream &operator<<(raw_ostream &OS, const ConstantFPRange &CR) {
133+
CR.print(OS);
134+
return OS;
135+
}
136+
137+
} // end namespace llvm
138+
139+
#endif // LLVM_IR_CONSTANTFPRANGE_H

0 commit comments

Comments
 (0)