LLVM 23.0.0git
FloatingPointMode.h
Go to the documentation of this file.
1//===- llvm/Support/FloatingPointMode.h -------------------------*- 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/// \file
10/// Utilities for dealing with flags related to floating point properties and
11/// mode controls.
12///
13//===----------------------------------------------------------------------===/
14
15#ifndef LLVM_ADT_FLOATINGPOINTMODE_H
16#define LLVM_ADT_FLOATINGPOINTMODE_H
17
22
23namespace llvm {
24
25/// Rounding mode.
26///
27/// Enumerates supported rounding modes, as well as some special values. The set
28/// of the modes must agree with IEEE-754, 4.3.1 and 4.3.2. The constants
29/// assigned to the IEEE rounding modes must agree with the values used by
30/// FLT_ROUNDS (C11, 5.2.4.2.2p8).
31///
32/// This value is packed into bitfield in some cases, including \c FPOptions, so
33/// the rounding mode values and the special value \c Dynamic must fit into the
34/// the bit field (now - 3 bits). The value \c Invalid is used only in values
35/// returned by intrinsics to indicate errors, it should never be stored as
36/// rounding mode value, so it does not need to fit the bit fields.
37///
38enum class RoundingMode : int8_t {
39 // Rounding mode defined in IEEE-754.
40 TowardZero = 0, ///< roundTowardZero.
41 NearestTiesToEven = 1, ///< roundTiesToEven.
42 TowardPositive = 2, ///< roundTowardPositive.
43 TowardNegative = 3, ///< roundTowardNegative.
44 NearestTiesToAway = 4, ///< roundTiesToAway.
45
46 // Special values.
47 Dynamic = 7, ///< Denotes mode unknown at compile time.
48 Invalid = -1 ///< Denotes invalid value.
49};
50
51/// Returns text representation of the given rounding mode.
53 switch (RM) {
54 case RoundingMode::TowardZero: return "towardzero";
55 case RoundingMode::NearestTiesToEven: return "tonearest";
56 case RoundingMode::TowardPositive: return "upward";
57 case RoundingMode::TowardNegative: return "downward";
58 case RoundingMode::NearestTiesToAway: return "tonearestaway";
59 case RoundingMode::Dynamic: return "dynamic";
60 default: return "invalid";
61 }
62}
63
65 OS << spell(RM);
66 return OS;
67}
68
69/// Represent subnormal handling kind for floating point instruction inputs and
70/// outputs.
72 /// Represent handled modes for denormal (aka subnormal) modes in the floating
73 /// point environment.
74 enum DenormalModeKind : int8_t {
75 Invalid = -1,
76
77 /// IEEE-754 denormal numbers preserved.
78 IEEE = 0,
79
80 /// The sign of a flushed-to-zero number is preserved in the sign of 0
82
83 /// Denormals are flushed to positive zero.
85
86 /// Denormals have unknown treatment.
88 };
89
90 /// Denormal flushing mode for floating point instruction results in the
91 /// default floating point environment.
93
94 /// Denormal treatment kind for floating point instruction inputs in the
95 /// default floating-point environment. If this is not DenormalModeKind::IEEE,
96 /// floating-point instructions implicitly treat the input value as 0.
98
99 constexpr DenormalMode() = default;
100 constexpr DenormalMode(const DenormalMode &) = default;
102 Output(Out), Input(In) {}
103
105
109
110 /// Return the assumed default mode for a function without denormal-fp-math.
111 static constexpr DenormalMode getDefault() {
112 return getIEEE();
113 }
114
118
123
128
132
133 constexpr uint32_t toIntValue() const {
135 return (static_cast<uint32_t>(Input) << 2) | static_cast<uint32_t>(Output);
136 }
137
139 uint32_t OutputMode = Data & 0x3;
140 uint32_t InputMode = (Data >> 2) & 0x3;
141
142 return {static_cast<DenormalModeKind>(OutputMode),
143 static_cast<DenormalModeKind>(InputMode)};
144 }
145
146 constexpr bool operator==(DenormalMode Other) const {
147 return Output == Other.Output && Input == Other.Input;
148 }
149
150 constexpr bool operator!=(DenormalMode Other) const {
151 return !(*this == Other);
152 }
153
154 constexpr bool isSimple() const { return Input == Output; }
155
156 constexpr bool isValid() const {
159 }
160
161 /// Return true if input denormals must be implicitly treated as 0.
162 constexpr bool inputsAreZero() const {
165 }
166
167 /// Return true if input denormals may be implicitly treated as 0.
168 constexpr bool inputsMayBeZero() const {
170 }
171
172 /// Return true if output denormals should be flushed to 0.
173 constexpr bool outputsAreZero() const {
176 }
177
178 /// Return true if output denormals may be implicitly treated as 0.
179 constexpr bool outputsMayBeZero() const {
181 }
182
183 /// Return true if input denormals could be flushed to +0.
184 constexpr bool inputsMayBePositiveZero() const {
187 }
188
189 /// Return true if output denormals could be flushed to +0.
190 constexpr bool outputsMayBePositiveZero() const {
193 }
194
195 /// Get the effective denormal mode if the mode if this caller calls into a
196 /// function with \p Callee. This promotes dynamic modes to the mode of the
197 /// caller.
198 constexpr DenormalMode mergeCalleeMode(DenormalMode Callee) const {
199 DenormalMode MergedMode = Callee;
200 if (Callee.Input == DenormalMode::Dynamic)
201 MergedMode.Input = Input;
202 if (Callee.Output == DenormalMode::Dynamic)
203 MergedMode.Output = Output;
204 return MergedMode;
205 }
206
207 inline void print(raw_ostream &OS, bool Legacy = true,
208 bool OmitIfSame = false) const;
209
210 inline std::string str() const {
211 std::string storage;
212 raw_string_ostream OS(storage);
213 print(OS);
214 return storage;
215 }
216};
217
219 Mode.print(OS);
220 return OS;
221}
222
223/// Parse the expected names from the denormal-fp-math attribute.
226 // Assume ieee on unspecified attribute.
228 .Cases({"", "ieee"}, DenormalMode::IEEE)
229 .Cases({"preservesign", "preserve-sign"}, DenormalMode::PreserveSign)
230 .Cases({"positivezero", "positive-zero"}, DenormalMode::PositiveZero)
231 .Case("dynamic", DenormalMode::Dynamic)
233}
234
235/// Return the name used for the denormal handling mode used by the
236/// expected names from the denormal-fp-math attribute.
238 bool LegacyName = true) {
239 switch (Mode) {
241 return "ieee";
243 return LegacyName ? "preserve-sign" : "preservesign";
245 return LegacyName ? "positive-zero" : "positivezero";
247 return "dynamic";
248 default:
249 return "";
250 }
251}
252
253/// Returns the denormal mode to use for inputs and outputs.
255 StringRef OutputStr, InputStr;
256 std::tie(OutputStr, InputStr) = Str.split(',');
257
259 Mode.Output = parseDenormalFPAttributeComponent(OutputStr);
260
261 // Maintain compatibility with old form of the attribute which only specified
262 // one component.
263 Mode.Input = InputStr.empty() ? Mode.Output :
265
266 return Mode;
267}
268
269void DenormalMode::print(raw_ostream &OS, bool Legacy, bool OmitIfSame) const {
270 OS << denormalModeKindName(Output, Legacy);
271 if (!OmitIfSame || Input != Output) {
272 OS << (Legacy ? ',' : '|');
273 OS << denormalModeKindName(Input, Legacy);
274 }
275}
276
277/// Represents the full denormal controls for a function, including the default
278/// mode and the f32 specific override.
280private:
281 static constexpr unsigned BitsPerEntry = 2;
282 static constexpr unsigned BitsPerMode = 4;
283 static constexpr unsigned ModeMask = (1 << BitsPerMode) - 1;
284
285public:
288
289 constexpr DenormalFPEnv(DenormalMode BaseMode,
291 : DefaultMode(BaseMode),
292 F32Mode(FloatMode.Output == DenormalMode::Invalid ? BaseMode.Output
293 : FloatMode.Output,
294 FloatMode.Input == DenormalMode::Invalid ? BaseMode.Input
295 : FloatMode.Input) {}
296
300
301 constexpr uint32_t toIntValue() const {
302 assert(DefaultMode.isValid() && F32Mode.isValid());
303 uint32_t Data =
304 DefaultMode.toIntValue() | (F32Mode.toIntValue() << BitsPerMode);
305
307 return Data;
308 }
309
314
315 constexpr bool operator==(DenormalFPEnv Other) const {
316 return DefaultMode == Other.DefaultMode && F32Mode == Other.F32Mode;
317 }
318
319 constexpr bool operator!=(DenormalFPEnv Other) const {
320 return !(*this == Other);
321 }
322
323 LLVM_ABI void print(raw_ostream &OS, bool OmitIfSame = true) const;
324
326 return DenormalFPEnv{DefaultMode.mergeCalleeMode(Callee.DefaultMode),
327 F32Mode.mergeCalleeMode(Callee.F32Mode)};
328 }
329};
330
332 FPEnv.print(OS);
333 return OS;
334}
335
336/// Floating-point class tests, supported by 'is_fpclass' intrinsic. Actual
337/// test may be an OR combination of basic tests.
365
367
368/// Return the test mask which returns true if the value's sign bit is flipped.
370
371/// Return the test mask which returns true after fabs is applied to the value.
373
374/// Return the test mask which returns true if the value could have the same set
375/// of classes, but with a different sign.
377
378/// Write a human readable form of \p Mask to \p OS
380
381/// Returns true if all values in \p LHS must be less than or equal to those in
382/// \p RHS. That is, the comparison `fcmp ogt LHS, RHS` will always return
383/// false.
384///
385/// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
386/// unlike fcmp.
388 bool OrderedZeroSign = false);
389
390/// Returns true if all values in \p LHS must be less than those in \p RHS. That
391/// is, the comparison `fcmp oge LHS, RHS` will always return false.
392//
393// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
394// unlike fcmp.
396 bool OrderedZeroSign = false);
397
398/// Returns true if all values in \p LHS must be greater than or equal to those
399/// in \p RHS. That is, the comparison `fcmp olt LHS, RHS` will always return
400/// false.
401///
402/// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
403/// unlike fcmp.
405 bool OrderedZeroSign = false);
406
407/// Returns true if all values in \p LHS must be greater than to those in \p
408/// RHS. That is, the comparison `fcmp ole LHS, RHS` will always return false.
409///
410/// If \p OrderedZeroSign is true, -0 will be treated as ordered less than +0,
411/// unlike fcmp.
413 bool OrderedZeroSign = false);
414
415} // namespace llvm
416
417#endif // LLVM_ADT_FLOATINGPOINTMODE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_DECLARE_ENUM_AS_BITMASK(Enum, LargestValue)
LLVM_DECLARE_ENUM_AS_BITMASK can be used to declare an enum type as a bit set, so that bitwise operat...
Definition BitmaskEnum.h:66
#define LLVM_ABI
Definition Compiler.h:213
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")))
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Value * RHS
Value * LHS
The Input class is used to parse a yaml document into in-memory structs and vectors.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:730
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
constexpr StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode, bool LegacyName=true)
Return the name used for the denormal handling mode used by the expected names from the denormal-fp-m...
DenormalMode::DenormalModeKind parseDenormalFPAttributeComponent(StringRef Str)
Parse the expected names from the denormal-fp-math attribute.
LLVM_ABI bool cannotOrderStrictlyGreaterEq(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be less than those in RHS.
LLVM_ABI bool cannotOrderStrictlyLess(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be greater than or equal to those in RHS.
LLVM_ABI bool cannotOrderStrictlyLessEq(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be greater than to those in RHS.
LLVM_ABI bool cannotOrderStrictlyGreater(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be less than or equal to those in RHS.
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.
LLVM_ABI FPClassTest inverse_fabs(FPClassTest Mask)
Return the test mask which returns true after fabs is applied to the value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
@ Other
Any other memory.
Definition ModRef.h:68
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
LLVM_ABI FPClassTest unknown_sign(FPClassTest Mask)
Return the test mask which returns true if the value could have the same set of classes,...
RoundingMode
Rounding mode.
@ TowardZero
roundTowardZero.
@ NearestTiesToEven
roundTiesToEven.
@ Dynamic
Denotes mode unknown at compile time.
@ TowardPositive
roundTowardPositive.
@ NearestTiesToAway
roundTiesToAway.
@ TowardNegative
roundTowardNegative.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
DenormalMode parseDenormalFPAttribute(StringRef Str)
Returns the denormal mode to use for inputs and outputs.
StringRef spell(RoundingMode RM)
Returns text representation of the given rounding mode.
Represents the full denormal controls for a function, including the default mode and the f32 specific...
static constexpr DenormalFPEnv getDefault()
DenormalFPEnv mergeCalleeMode(DenormalFPEnv Callee) const
constexpr bool operator!=(DenormalFPEnv Other) const
static constexpr DenormalFPEnv createFromIntValue(uint32_t Data)
constexpr DenormalFPEnv(DenormalMode BaseMode, DenormalMode FloatMode=DenormalMode::getInvalid())
constexpr bool operator==(DenormalFPEnv Other) const
LLVM_ABI void print(raw_ostream &OS, bool OmitIfSame=true) const
constexpr uint32_t toIntValue() const
Represent subnormal handling kind for floating point instruction inputs and outputs.
constexpr bool inputsMayBePositiveZero() const
Return true if input denormals could be flushed to +0.
constexpr bool operator!=(DenormalMode Other) const
void print(raw_ostream &OS, bool Legacy=true, bool OmitIfSame=false) const
static constexpr DenormalMode createFromIntValue(uint32_t Data)
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
constexpr bool outputsAreZero() const
Return true if output denormals should be flushed to 0.
constexpr bool operator==(DenormalMode Other) const
DenormalModeKind
Represent handled modes for denormal (aka subnormal) modes in the floating point environment.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
@ Dynamic
Denormals have unknown treatment.
@ IEEE
IEEE-754 denormal numbers preserved.
static constexpr DenormalMode getPositiveZero()
constexpr uint32_t toIntValue() const
constexpr DenormalMode(const DenormalMode &)=default
static constexpr DenormalMode getDefault()
Return the assumed default mode for a function without denormal-fp-math.
constexpr bool inputsMayBeZero() const
Return true if input denormals may be implicitly treated as 0.
std::string str() const
constexpr DenormalMode mergeCalleeMode(DenormalMode Callee) const
Get the effective denormal mode if the mode if this caller calls into a function with Callee.
constexpr bool outputsMayBePositiveZero() const
Return true if output denormals could be flushed to +0.
constexpr bool outputsMayBeZero() const
Return true if output denormals may be implicitly treated as 0.
static constexpr DenormalMode getInvalid()
constexpr bool isValid() const
constexpr bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
static constexpr DenormalMode getPreserveSign()
constexpr bool isSimple() const
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
DenormalMode & operator=(const DenormalMode &)=default
constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In)
constexpr DenormalMode()=default
static constexpr DenormalMode getDynamic()
static constexpr DenormalMode getIEEE()