LLVM 23.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;
23struct fltSemantics;
24struct KnownBits;
25
27 /// Floating-point classes the value could be one of.
29
30 /// std::nullopt if the sign bit is unknown, true if the sign bit is
31 /// definitely set or false if the sign bit is definitely unset.
32 std::optional<bool> SignBit;
33
34 KnownFPClass(FPClassTest Known = fcAllFlags, std::optional<bool> Sign = {})
35 : KnownFPClasses(Known), SignBit(Sign) {}
36 LLVM_ABI KnownFPClass(const APFloat &C);
37
39 return KnownFPClasses == Other.KnownFPClasses && SignBit == Other.SignBit;
40 }
41
42 /// Return true if it's known this can never be one of the mask entries.
43 bool isKnownNever(FPClassTest Mask) const {
44 return (KnownFPClasses & Mask) == fcNone;
45 }
46
47 bool isKnownAlways(FPClassTest Mask) const { return isKnownNever(~Mask); }
48
49 bool isUnknown() const { return KnownFPClasses == fcAllFlags && !SignBit; }
50
51 /// Return true if it's known this can never be a nan.
52 bool isKnownNeverNaN() const { return isKnownNever(fcNan); }
53
54 /// Return true if it's known this must always be a nan.
55 bool isKnownAlwaysNaN() const { return isKnownAlways(fcNan); }
56
57 /// Return true if it's known this can never be an infinity.
58 bool isKnownNeverInfinity() const { return isKnownNever(fcInf); }
59
60 /// Return true if it's known this can never be an infinity or nan
61 bool isKnownNeverInfOrNaN() const { return isKnownNever(fcInf | fcNan); }
62
63 /// Return true if it's known this can never be +infinity.
65
66 /// Return true if it's known this can never be -infinity.
68
69 /// Return true if it's known this can never be a subnormal
71
72 /// Return true if it's known this can never be a positive subnormal
74
75 /// Return true if it's known this can never be a negative subnormal
77
78 /// Return true if it's known this can never be a zero. This means a literal
79 /// [+-]0, and does not include denormal inputs implicitly treated as [+-]0.
80 bool isKnownNeverZero() const { return isKnownNever(fcZero); }
81
82 /// Return true if it's known this can never be a literal positive zero.
83 bool isKnownNeverPosZero() const { return isKnownNever(fcPosZero); }
84
85 /// Return true if it's known this can never be a negative zero. This means a
86 /// literal -0 and does not include denormal inputs implicitly treated as -0.
87 bool isKnownNeverNegZero() const { return isKnownNever(fcNegZero); }
88
89 /// Return true if it's known this can never be interpreted as a zero. This
90 /// extends isKnownNeverZero to cover the case where the assumed
91 /// floating-point mode for the function interprets denormals as zero.
93
94 /// Return true if it's known this can never be interpreted as a negative
95 /// zero.
97
98 /// Return true if it's known this can never be interpreted as a positive
99 /// zero.
101
106
107 /// Return true if we can prove that the analyzed floating-point value is
108 /// either NaN or never less than -0.0.
109 ///
110 /// NaN --> true
111 /// +0 --> true
112 /// -0 --> true
113 /// x > +0 --> true
114 /// x < -0 --> false
118
119 /// Return true if we can prove that the analyzed floating-point value is
120 /// either NaN or never greater than -0.0.
121 /// NaN --> true
122 /// +0 --> true
123 /// -0 --> true
124 /// x > +0 --> false
125 /// x < -0 --> true
129
130 /// Return true if it's known this can never be a positive value or a logical
131 /// 0.
132 ///
133 /// NaN --> true
134 /// x <= +0 --> false
135 /// psub --> true if mode is ieee, false otherwise.
136 /// x > +0 --> true
140
141 /// Return true if it's know this can never be a negative value or a logical
142 /// 0.
143 ///
144 /// NaN --> true
145 /// x >= -0 --> false
146 /// nsub --> true if mode is ieee, false otherwise.
147 /// x < -0 --> true
151
153 return KnownFPClass(KnownFPClasses | RHS.KnownFPClasses,
154 SignBit == RHS.SignBit ? SignBit : std::nullopt);
155 }
156
158 std::optional<bool> MergedSignBit;
159 if (SignBit && !RHS.SignBit)
160 MergedSignBit = SignBit;
161 else if (!SignBit && RHS.SignBit)
162 MergedSignBit = RHS.SignBit;
163
164 return KnownFPClass(KnownFPClasses & RHS.KnownFPClasses, MergedSignBit);
165 }
166
168 KnownFPClasses = KnownFPClasses | RHS.KnownFPClasses;
169
170 if (SignBit != RHS.SignBit)
171 SignBit = std::nullopt;
172 return *this;
173 }
174
175 void knownNot(FPClassTest RuleOut) {
176 KnownFPClasses = KnownFPClasses & ~RuleOut;
177 if (isKnownNever(fcNan) && !SignBit) {
179 SignBit = false;
180 else if (isKnownNever(fcPositive))
181 SignBit = true;
182 }
183 }
184
185 void fneg() {
187 if (SignBit)
188 SignBit = !*SignBit;
189 }
190
191 static KnownFPClass fneg(const KnownFPClass &Src) {
192 KnownFPClass Known = Src;
193 Known.fneg();
194 return Known;
195 }
196
212
213 static KnownFPClass fabs(const KnownFPClass &Src) {
214 KnownFPClass Known = Src;
215 Known.fabs();
216 return Known;
217 }
218
219 // Enum of min/max intrinsics to avoid dependency on IR.
228
232
233 /// Apply the canonicalize intrinsic to this value. This is essentially a
234 /// stronger form of propagateCanonicalizingSrc.
236 canonicalize(const KnownFPClass &Src,
238
239 /// Report known values for a bitcast into a float with provided semantics.
240 LLVM_ABI static KnownFPClass bitcast(const fltSemantics &FltSemantics,
241 const KnownBits &Bits);
242
243 /// Report known values for fadd
245 fadd(const KnownFPClass &LHS, const KnownFPClass &RHS,
247
248 /// Report known values for fadd x, x
250 fadd_self(const KnownFPClass &Src,
252
253 /// Report known values for fsub
255 fsub(const KnownFPClass &LHS, const KnownFPClass &RHS,
257
258 /// Report known values for fmul
260 fmul(const KnownFPClass &LHS, const KnownFPClass &RHS,
262
263 // Special case of fmul x, x.
266 KnownFPClass Known = fmul(Src, Src, Mode);
267
268 // X * X is always non-negative or a NaN.
269 Known.knownNot(fcNegative);
270 Known.propagateNaN(Src);
271 return Known;
272 }
273
275 fmul(const KnownFPClass &LHS, const APFloat &RHS,
277
278 /// Report known values for fdiv
280 fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS,
282
283 /// Report known values for fdiv x, x
285 fdiv_self(const KnownFPClass &Src,
287
288 /// Report known values for frem
290 frem_self(const KnownFPClass &Src,
292
293 /// Report known values for fma
295 fma(const KnownFPClass &LHS, const KnownFPClass &RHS,
296 const KnownFPClass &Addend,
298
299 /// Report known values for fma squared, squared, addend
301 fma_square(const KnownFPClass &Squared, const KnownFPClass &Addend,
303
304 /// Report known values for exp, exp2 and exp10.
305 LLVM_ABI static KnownFPClass exp(const KnownFPClass &Src);
306
307 /// Report known values for sin
308 LLVM_ABI static KnownFPClass sin(const KnownFPClass &Src);
309
310 /// Report known values for cos
311 LLVM_ABI static KnownFPClass cos(const KnownFPClass &Src);
312
313 /// Report known values for tan
314 LLVM_ABI static KnownFPClass tan(const KnownFPClass &Src);
315
316 /// Report known values for sinh
317 LLVM_ABI static KnownFPClass sinh(const KnownFPClass &Src);
318
319 /// Report known values for cosh
320 LLVM_ABI static KnownFPClass cosh(const KnownFPClass &Src);
321
322 /// Report known values for tanh
323 LLVM_ABI static KnownFPClass tanh(const KnownFPClass &Src);
324
325 /// Report known values for asin
326 LLVM_ABI static KnownFPClass asin(const KnownFPClass &Src);
327
328 /// Report known values for acos
329 LLVM_ABI static KnownFPClass acos(const KnownFPClass &Src);
330
331 /// Report known values for atan
332 LLVM_ABI static KnownFPClass atan(const KnownFPClass &Src);
333
334 /// Report known values for atan2
336 const KnownFPClass &RHS);
337
338 /// Return true if the sign bit must be 0, ignoring the sign of nans.
340
341 /// Assume the sign bit is zero.
344 SignBit = false;
345 }
346
347 /// Assume the sign bit is one.
350 SignBit = true;
351 }
352
353 void copysign(const KnownFPClass &Sign) {
354 // Don't know anything about the sign of the source. Expand the possible set
355 // to its opposite sign pair.
362 if (KnownFPClasses & fcInf)
364
365 // Sign bit is exactly preserved even for nans.
366 SignBit = Sign.SignBit;
367
368 // Clear sign bits based on the input sign mask.
369 if (Sign.isKnownNever(fcPositive | fcNan) || (SignBit && *SignBit))
371 if (Sign.isKnownNever(fcNegative | fcNan) || (SignBit && !*SignBit))
373 }
374
375 static KnownFPClass copysign(const KnownFPClass &KnownMag,
376 const KnownFPClass &KnownSign) {
377 KnownFPClass Known = KnownMag;
378 Known.copysign(KnownSign);
379 return Known;
380 }
381
382 // Propagate knowledge that a non-NaN source implies the result can also not
383 // be a NaN. For unconstrained operations, signaling nans are not guaranteed
384 // to be quieted but cannot be introduced.
385 void propagateNaN(const KnownFPClass &Src, bool PreserveSign = false) {
386 if (Src.isKnownNever(fcNan)) {
388 if (PreserveSign)
389 SignBit = Src.SignBit;
390 } else if (Src.isKnownNever(fcSNan))
392 }
393
394 /// Propagate knowledge from a source value that could be a denormal or
395 /// zero. We have to be conservative since output flushing is not guaranteed,
396 /// so known-never-zero may not hold.
397 ///
398 /// This assumes a copy-like operation and will replace any currently known
399 /// information.
401
402 /// Report known classes if \p Src is evaluated through a potentially
403 /// canonicalizing operation. We can assume signaling nans will not be
404 /// introduced, but cannot assume a denormal will be flushed under FTZ/DAZ.
405 ///
406 /// This assumes a copy-like operation and will replace any currently known
407 /// information.
410
411 /// Propagate known class for log/log2/log10
414
415 /// Propagate known class for sqrt
418
419 /// Propagate known class for fpext.
420 static LLVM_ABI KnownFPClass fpext(const KnownFPClass &KnownSrc,
421 const fltSemantics &DstTy,
422 const fltSemantics &SrcTy);
423
424 /// Propagate known class for fptrunc.
425 static LLVM_ABI KnownFPClass fptrunc(const KnownFPClass &KnownSrc);
426
427 /// Propagate known class for rounding intrinsics (trunc, floor, ceil, rint,
428 /// nearbyint, round, roundeven). This is trunc if \p IsTrunc. \p
429 /// IsMultiUnitFPType if this is for a multi-unit floating-point type.
431 bool IsTrunc,
432 bool IsMultiUnitFPType);
433
434 /// Propagate known class for mantissa component of frexp
437
438 /// Propagate known class for ldexp
440 ldexp(const KnownFPClass &Src, const KnownBits &N, const fltSemantics &Flt,
442
443 /// Propagate known class for powi
444 static LLVM_ABI KnownFPClass powi(const KnownFPClass &Src,
445 const KnownBits &N);
446
447 void resetAll() { *this = KnownFPClass(); }
448};
449
451 LHS |= RHS;
452 return LHS;
453}
454
456 RHS |= LHS;
457 return std::move(RHS);
458}
459
460} // namespace llvm
461
462#endif
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#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
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:2161
#define N
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getDynamic()
bool isKnownNeverInfOrNaN() const
Return true if it's known this can never be an infinity or nan.
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.
KnownFPClass(FPClassTest Known=fcAllFlags, std::optional< bool > Sign={})
bool cannotBeOrderedGreaterThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never greater tha...
static LLVM_ABI KnownFPClass sin(const KnownFPClass &Src)
Report known values for sin.
static LLVM_ABI KnownFPClass fdiv_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv x, x.
static constexpr FPClassTest OrderedGreaterThanZeroMask
static constexpr FPClassTest OrderedLessThanZeroMask
void knownNot(FPClassTest RuleOut)
static LLVM_ABI KnownFPClass fmul(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fmul.
static LLVM_ABI KnownFPClass fadd_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd x, x.
bool isKnownNeverZero() const
Return true if it's known this can never be a zero.
void copysign(const KnownFPClass &Sign)
static KnownFPClass square(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
static LLVM_ABI KnownFPClass fsub(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fsub.
bool isKnownNeverSubnormal() const
Return true if it's known this can never be a subnormal.
bool isKnownAlways(FPClassTest Mask) const
KnownFPClass unionWith(const KnownFPClass &RHS) const
static LLVM_ABI KnownFPClass canonicalize(const KnownFPClass &Src, DenormalMode DenormMode=DenormalMode::getDynamic())
Apply the canonicalize intrinsic to this value.
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a zero.
static LLVM_ABI KnownFPClass log(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for log/log2/log10.
static LLVM_ABI KnownFPClass atan(const KnownFPClass &Src)
Report known values for atan.
LLVM_ABI void propagateDenormal(const KnownFPClass &Src, DenormalMode Mode)
Propagate knowledge from a source value that could be a denormal or zero.
bool cannotBeOrderedLessEqZero(DenormalMode Mode) const
Return true if it's known this can never be a positive value or a logical 0.
static LLVM_ABI KnownFPClass atan2(const KnownFPClass &LHS, const KnownFPClass &RHS)
Report known values for atan2.
static LLVM_ABI KnownFPClass fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv.
KnownFPClass & operator|=(const KnownFPClass &RHS)
static KnownFPClass fneg(const KnownFPClass &Src)
static LLVM_ABI KnownFPClass roundToIntegral(const KnownFPClass &Src, bool IsTrunc, bool IsMultiUnitFPType)
Propagate known class for rounding intrinsics (trunc, floor, ceil, rint, nearbyint,...
static LLVM_ABI KnownFPClass cos(const KnownFPClass &Src)
Report known values for cos.
static LLVM_ABI KnownFPClass ldexp(const KnownFPClass &Src, const KnownBits &N, const fltSemantics &Flt, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ldexp.
static LLVM_ABI KnownFPClass cosh(const KnownFPClass &Src)
Report known values for cosh.
static LLVM_ABI KnownFPClass minMaxLike(const KnownFPClass &LHS, const KnownFPClass &RHS, MinMaxKind Kind, DenormalMode DenormMode=DenormalMode::getDynamic())
bool isUnknown() const
KnownFPClass intersectWith(const KnownFPClass &RHS) 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.
static LLVM_ABI KnownFPClass exp(const KnownFPClass &Src)
Report known values for exp, exp2 and exp10.
static LLVM_ABI KnownFPClass frexp_mant(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for mantissa component of frexp.
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 ...
static LLVM_ABI KnownFPClass asin(const KnownFPClass &Src)
Report known values for asin.
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.
static LLVM_ABI KnownFPClass fpext(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy)
Propagate known class for fpext.
static KnownFPClass copysign(const KnownFPClass &KnownMag, const KnownFPClass &KnownSign)
bool isKnownNeverNegZero() const
Return true if it's known this can never be a negative zero.
static LLVM_ABI KnownFPClass fma(const KnownFPClass &LHS, const KnownFPClass &RHS, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma.
static LLVM_ABI KnownFPClass tan(const KnownFPClass &Src)
Report known values for tan.
void propagateNaN(const KnownFPClass &Src, bool PreserveSign=false)
static LLVM_ABI KnownFPClass fptrunc(const KnownFPClass &KnownSrc)
Propagate known class for fptrunc.
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.
static LLVM_ABI KnownFPClass sqrt(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for sqrt.
LLVM_ABI bool isKnownNeverLogicalPosZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a positive zero.
bool isKnownNeverPosInfinity() const
Return true if it's known this can never be +infinity.
bool cannotBeOrderedGreaterEqZero(DenormalMode Mode) const
Return true if it's know this can never be a negative value or a logical 0.
static LLVM_ABI KnownFPClass fadd(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd.
static KnownFPClass fabs(const KnownFPClass &Src)
LLVM_ABI bool isKnownNeverLogicalNegZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a negative zero.
static LLVM_ABI KnownFPClass bitcast(const fltSemantics &FltSemantics, const KnownBits &Bits)
Report known values for a bitcast into a float with provided semantics.
static LLVM_ABI KnownFPClass fma_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma squared, squared, addend.
static LLVM_ABI KnownFPClass acos(const KnownFPClass &Src)
Report known values for acos.
bool operator==(KnownFPClass Other) const
static LLVM_ABI KnownFPClass frem_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem.
static LLVM_ABI KnownFPClass powi(const KnownFPClass &Src, const KnownBits &N)
Propagate known class for powi.
bool signBitIsZeroOrNaN() const
Return true if the sign bit must be 0, ignoring the sign of nans.
static LLVM_ABI KnownFPClass sinh(const KnownFPClass &Src)
Report known values for sinh.
bool isKnownNeverPosSubnormal() const
Return true if it's known this can never be a positive subnormal.
static LLVM_ABI KnownFPClass tanh(const KnownFPClass &Src)
Report known values for tanh.