LLVM 22.0.0git
KnownFPClass.h
Go to the documentation of this file.
1//===- llvm/Support/KnownFPClass.h - Stores known fpclass -------*- 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// This file contains a class for representing known fpclasses used by
10// computeKnownFPClass.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_SUPPORT_KNOWNFPCLASS_H
15#define LLVM_SUPPORT_KNOWNFPCLASS_H
16
19#include <optional>
20
21namespace llvm {
22class APFloat;
23
25 /// Floating-point classes the value could be one of.
27
28 /// std::nullopt if the sign bit is unknown, true if the sign bit is
29 /// definitely set or false if the sign bit is definitely unset.
30 std::optional<bool> SignBit;
31
32 KnownFPClass() = default;
33 KnownFPClass(const APFloat &C);
34
36 return KnownFPClasses == Other.KnownFPClasses && SignBit == Other.SignBit;
37 }
38
39 /// Return true if it's known this can never be one of the mask entries.
40 bool isKnownNever(FPClassTest Mask) const {
41 return (KnownFPClasses & Mask) == fcNone;
42 }
43
44 bool isKnownAlways(FPClassTest Mask) const { return isKnownNever(~Mask); }
45
46 bool isUnknown() const { return KnownFPClasses == fcAllFlags && !SignBit; }
47
48 /// Return true if it's known this can never be a nan.
49 bool isKnownNeverNaN() const { return isKnownNever(fcNan); }
50
51 /// Return true if it's known this must always be a nan.
52 bool isKnownAlwaysNaN() const { return isKnownAlways(fcNan); }
53
54 /// Return true if it's known this can never be an infinity.
55 bool isKnownNeverInfinity() const { return isKnownNever(fcInf); }
56
57 /// Return true if it's known this can never be +infinity.
59
60 /// Return true if it's known this can never be -infinity.
62
63 /// Return true if it's known this can never be a subnormal
65
66 /// Return true if it's known this can never be a positive subnormal
68
69 /// Return true if it's known this can never be a negative subnormal
71
72 /// Return true if it's known this can never be a zero. This means a literal
73 /// [+-]0, and does not include denormal inputs implicitly treated as [+-]0.
74 bool isKnownNeverZero() const { return isKnownNever(fcZero); }
75
76 /// Return true if it's known this can never be a literal positive zero.
77 bool isKnownNeverPosZero() const { return isKnownNever(fcPosZero); }
78
79 /// Return true if it's known this can never be a negative zero. This means a
80 /// literal -0 and does not include denormal inputs implicitly treated as -0.
81 bool isKnownNeverNegZero() const { return isKnownNever(fcNegZero); }
82
83 /// Return true if it's know this can never be interpreted as a zero. This
84 /// extends isKnownNeverZero to cover the case where the assumed
85 /// floating-point mode for the function interprets denormals as zero.
87
88 /// Return true if it's know this can never be interpreted as a negative zero.
90
91 /// Return true if it's know this can never be interpreted as a positive zero.
93
98
99 /// Return true if we can prove that the analyzed floating-point value is
100 /// either NaN or never less than -0.0.
101 ///
102 /// NaN --> true
103 /// +0 --> true
104 /// -0 --> true
105 /// x > +0 --> true
106 /// x < -0 --> false
110
111 /// Return true if we can prove that the analyzed floating-point value is
112 /// either NaN or never greater than -0.0.
113 /// NaN --> true
114 /// +0 --> true
115 /// -0 --> true
116 /// x > +0 --> false
117 /// x < -0 --> true
121
123 KnownFPClasses = KnownFPClasses | RHS.KnownFPClasses;
124
125 if (SignBit != RHS.SignBit)
126 SignBit = std::nullopt;
127 return *this;
128 }
129
130 void knownNot(FPClassTest RuleOut) {
131 KnownFPClasses = KnownFPClasses & ~RuleOut;
132 if (isKnownNever(fcNan) && !SignBit) {
134 SignBit = false;
135 else if (isKnownNever(fcPositive))
136 SignBit = true;
137 }
138 }
139
140 void fneg() {
142 if (SignBit)
143 SignBit = !*SignBit;
144 }
145
161
162 /// Return true if the sign bit must be 0, ignoring the sign of nans.
164
165 /// Assume the sign bit is zero.
168 SignBit = false;
169 }
170
171 /// Assume the sign bit is one.
174 SignBit = true;
175 }
176
177 void copysign(const KnownFPClass &Sign) {
178 // Don't know anything about the sign of the source. Expand the possible set
179 // to its opposite sign pair.
186 if (KnownFPClasses & fcInf)
188
189 // Sign bit is exactly preserved even for nans.
190 SignBit = Sign.SignBit;
191
192 // Clear sign bits based on the input sign mask.
193 if (Sign.isKnownNever(fcPositive | fcNan) || (SignBit && *SignBit))
195 if (Sign.isKnownNever(fcNegative | fcNan) || (SignBit && !*SignBit))
197 }
198
199 // Propagate knowledge that a non-NaN source implies the result can also not
200 // be a NaN. For unconstrained operations, signaling nans are not guaranteed
201 // to be quieted but cannot be introduced.
202 void propagateNaN(const KnownFPClass &Src, bool PreserveSign = false) {
203 if (Src.isKnownNever(fcNan)) {
205 if (PreserveSign)
206 SignBit = Src.SignBit;
207 } else if (Src.isKnownNever(fcSNan))
209 }
210
211 /// Propagate knowledge from a source value that could be a denormal or
212 /// zero. We have to be conservative since output flushing is not guaranteed,
213 /// so known-never-zero may not hold.
214 ///
215 /// This assumes a copy-like operation and will replace any currently known
216 /// information.
218
219 /// Report known classes if \p Src is evaluated through a potentially
220 /// canonicalizing operation. We can assume signaling nans will not be
221 /// introduced, but cannot assume a denormal will be flushed under FTZ/DAZ.
222 ///
223 /// This assumes a copy-like operation and will replace any currently known
224 /// information.
227
228 void resetAll() { *this = KnownFPClass(); }
229};
230
232 LHS |= RHS;
233 return LHS;
234}
235
237 RHS |= LHS;
238 return std::move(RHS);
239}
240
241} // namespace llvm
242
243#endif
#define LLVM_ABI
Definition Compiler.h:213
Utilities for dealing with flags related to floating point properties and mode controls.
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Value * RHS
Value * LHS
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI FPClassTest fneg(FPClassTest Mask)
Return the test mask which returns true if the value's sign bit is flipped.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
@ Other
Any other memory.
Definition ModRef.h:68
APInt operator|(APInt a, const APInt &b)
Definition APInt.h:2144
Represent subnormal handling kind for floating point instruction inputs and outputs.
bool isKnownAlwaysNaN() const
Return true if it's known this must always be a nan.
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
bool cannotBeOrderedGreaterThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never greater tha...
static constexpr FPClassTest OrderedGreaterThanZeroMask
static constexpr FPClassTest OrderedLessThanZeroMask
void knownNot(FPClassTest RuleOut)
bool isKnownNeverZero() const
Return true if it's known this can never be a zero.
void copysign(const KnownFPClass &Sign)
bool isKnownNeverSubnormal() const
Return true if it's known this can never be a subnormal.
bool isKnownAlways(FPClassTest Mask) const
KnownFPClass()=default
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's know this can never be interpreted as a zero.
LLVM_ABI void propagateDenormal(const KnownFPClass &Src, DenormalMode Mode)
Propagate knowledge from a source value that could be a denormal or zero.
KnownFPClass & operator|=(const KnownFPClass &RHS)
bool isUnknown() const
bool isKnownNeverNegInfinity() const
Return true if it's known this can never be -infinity.
bool isKnownNeverNegSubnormal() const
Return true if it's known this can never be a negative subnormal.
bool isKnownNeverPosZero() const
Return true if it's known this can never be a literal positive zero.
std::optional< bool > SignBit
std::nullopt if the sign bit is unknown, true if the sign bit is definitely set or false if the sign ...
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool isKnownNever(FPClassTest Mask) const
Return true if it's known this can never be one of the mask entries.
bool isKnownNeverNegZero() const
Return true if it's known this can never be a negative zero.
void propagateNaN(const KnownFPClass &Src, bool PreserveSign=false)
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
void signBitMustBeOne()
Assume the sign bit is one.
LLVM_ABI void propagateCanonicalizingSrc(const KnownFPClass &Src, DenormalMode Mode)
Report known classes if Src is evaluated through a potentially canonicalizing operation.
void signBitMustBeZero()
Assume the sign bit is zero.
LLVM_ABI bool isKnownNeverLogicalPosZero(DenormalMode Mode) const
Return true if it's know this can never be interpreted as a positive zero.
bool isKnownNeverPosInfinity() const
Return true if it's known this can never be +infinity.
LLVM_ABI bool isKnownNeverLogicalNegZero(DenormalMode Mode) const
Return true if it's know this can never be interpreted as a negative zero.
bool operator==(KnownFPClass Other) const
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
bool isKnownNeverPosSubnormal() const
Return true if it's known this can never be a positive subnormal.