LLVM 23.0.0git
KnownFPClass.cpp
Go to the documentation of this file.
1//===- llvm/Support/KnownFPClass.h - Stores known fplcass -------*- 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
15#include "llvm/ADT/APFloat.h"
17
18using namespace llvm;
19
21 : KnownFPClasses(C.classify()), SignBit(C.isNegative()) {}
22
23/// Return true if it's possible to assume IEEE treatment of input denormals in
24/// \p F for \p Val.
26 return Mode.Input == DenormalMode::IEEE;
27}
28
33
38
43
46 return false;
47
48 // If we know there are no denormals, nothing can be flushed to zero.
50 return true;
51
52 switch (Mode.Input) {
54 return true;
56 // Negative subnormal won't flush to +0
59 default:
60 // Both positive and negative subnormal could flush to +0
61 return false;
62 }
63
64 llvm_unreachable("covered switch over denormal mode");
65}
66
68 DenormalMode Mode) {
69 KnownFPClasses = Src.KnownFPClasses;
70 // If we aren't assuming the source can't be a zero, we don't have to check if
71 // a denormal input could be flushed.
72 if (!Src.isKnownNeverPosZero() && !Src.isKnownNeverNegZero())
73 return;
74
75 // If we know the input can't be a denormal, it can't be flushed to 0.
76 if (Src.isKnownNeverSubnormal())
77 return;
78
79 if (!Src.isKnownNeverPosSubnormal() && Mode != DenormalMode::getIEEE())
81
82 if (!Src.isKnownNeverNegSubnormal() && Mode != DenormalMode::getIEEE()) {
85
86 if (Mode.Input == DenormalMode::PositiveZero ||
87 Mode.Output == DenormalMode::PositiveZero ||
88 Mode.Input == DenormalMode::Dynamic ||
89 Mode.Output == DenormalMode::Dynamic)
91 }
92}
93
95 const KnownFPClass &RHS_, MinMaxKind Kind,
96 DenormalMode Mode) {
97 KnownFPClass KnownLHS = LHS_;
98 KnownFPClass KnownRHS = RHS_;
99
100 bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
101 KnownFPClass Known = KnownLHS | KnownRHS;
102
103 // If either operand is not NaN, the result is not NaN.
104 if (NeverNaN &&
105 (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
107 Known.knownNot(fcNan);
108
109 if (Kind == MinMaxKind::maxnum || Kind == MinMaxKind::maximumnum) {
110 // If at least one operand is known to be positive, the result must be
111 // positive.
112 if ((KnownLHS.cannotBeOrderedLessThanZero() &&
113 KnownLHS.isKnownNeverNaN()) ||
114 (KnownRHS.cannotBeOrderedLessThanZero() && KnownRHS.isKnownNeverNaN()))
116 } else if (Kind == MinMaxKind::maximum) {
117 // If at least one operand is known to be positive, the result must be
118 // positive.
119 if (KnownLHS.cannotBeOrderedLessThanZero() ||
122 } else if (Kind == MinMaxKind::minnum || Kind == MinMaxKind::minimumnum) {
123 // If at least one operand is known to be negative, the result must be
124 // negative.
125 if ((KnownLHS.cannotBeOrderedGreaterThanZero() &&
126 KnownLHS.isKnownNeverNaN()) ||
127 (KnownRHS.cannotBeOrderedGreaterThanZero() &&
128 KnownRHS.isKnownNeverNaN()))
130 } else if (Kind == MinMaxKind::minimum) {
131 // If at least one operand is known to be negative, the result must be
132 // negative.
133 if (KnownLHS.cannotBeOrderedGreaterThanZero() ||
136 } else
137 llvm_unreachable("unhandled intrinsic");
138
139 // Fixup zero handling if denormals could be returned as a zero.
140 //
141 // As there's no spec for denormal flushing, be conservative with the
142 // treatment of denormals that could be flushed to zero. For older
143 // subtargets on AMDGPU the min/max instructions would not flush the
144 // output and return the original value.
145 //
146 if ((Known.KnownFPClasses & fcZero) != fcNone &&
147 !Known.isKnownNeverSubnormal()) {
148 if (Mode != DenormalMode::getIEEE())
149 Known.KnownFPClasses |= fcZero;
150 }
151
152 if (Known.isKnownNeverNaN()) {
153 if (KnownLHS.SignBit && KnownRHS.SignBit &&
154 *KnownLHS.SignBit == *KnownRHS.SignBit) {
155 if (*KnownLHS.SignBit)
156 Known.signBitMustBeOne();
157 else
158 Known.signBitMustBeZero();
159 } else if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::minimum ||
160 Kind == MinMaxKind::maximumnum ||
161 Kind == MinMaxKind::minimumnum) ||
162 // FIXME: Should be using logical zero versions
163 ((KnownLHS.isKnownNeverNegZero() ||
164 KnownRHS.isKnownNeverPosZero()) &&
165 (KnownLHS.isKnownNeverPosZero() ||
166 KnownRHS.isKnownNeverNegZero()))) {
167 // Don't take sign bit from NaN operands.
168 if (!KnownLHS.isKnownNeverNaN())
169 KnownLHS.SignBit = std::nullopt;
170 if (!KnownRHS.isKnownNeverNaN())
171 KnownRHS.SignBit = std::nullopt;
172 if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::maximumnum ||
173 Kind == MinMaxKind::maxnum) &&
174 (KnownLHS.SignBit == false || KnownRHS.SignBit == false))
175 Known.signBitMustBeZero();
176 else if ((Kind == MinMaxKind::minimum || Kind == MinMaxKind::minimumnum ||
177 Kind == MinMaxKind::minnum) &&
178 (KnownLHS.SignBit == true || KnownRHS.SignBit == true))
179 Known.signBitMustBeOne();
180 }
181 }
182
183 return Known;
184}
185
187 DenormalMode DenormMode) {
188 KnownFPClass Known;
189
190 // This is essentially a stronger form of
191 // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
192 // actually have an IR canonicalization guarantee.
193
194 // Canonicalize may flush denormals to zero, so we have to consider the
195 // denormal mode to preserve known-not-0 knowledge.
196 Known.KnownFPClasses = KnownSrc.KnownFPClasses | fcZero | fcQNan;
197
198 // Stronger version of propagateNaN
199 // Canonicalize is guaranteed to quiet signaling nans.
200 if (KnownSrc.isKnownNeverNaN())
201 Known.knownNot(fcNan);
202 else
203 Known.knownNot(fcSNan);
204
205 // FIXME: Missing check of IEEE like types.
206
207 // If the parent function flushes denormals, the canonical output cannot be a
208 // denormal.
209 if (DenormMode == DenormalMode::getIEEE()) {
210 if (KnownSrc.isKnownNever(fcPosZero))
211 Known.knownNot(fcPosZero);
212 if (KnownSrc.isKnownNever(fcNegZero))
213 Known.knownNot(fcNegZero);
214 return Known;
215 }
216
217 if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
218 Known.knownNot(fcSubnormal);
219
220 if (DenormMode == DenormalMode::getPreserveSign()) {
221 if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
222 Known.knownNot(fcPosZero);
223 if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
224 Known.knownNot(fcNegZero);
225 return Known;
226 }
227
228 if (DenormMode.Input == DenormalMode::PositiveZero ||
229 (DenormMode.Output == DenormalMode::PositiveZero &&
230 DenormMode.Input == DenormalMode::IEEE))
231 Known.knownNot(fcNegZero);
232
233 return Known;
234}
235
236// Handle known sign bit and nan cases for fadd.
237static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
238 const KnownFPClass &KnownRHS, DenormalMode Mode) {
239 KnownFPClass Known;
240
241 // Adding positive and negative infinity produces NaN.
242 // TODO: Check sign of infinities.
243 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
244 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()))
245 Known.knownNot(fcNan);
246
247 if (KnownLHS.cannotBeOrderedLessThanZero() &&
248 KnownRHS.cannotBeOrderedLessThanZero()) {
250
251 // This can't underflow if one of the operands is known normal.
252 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
254 Known.knownNot(fcZero);
255 }
256
257 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
260
261 // This can't underflow if one of the operands is known normal.
262 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
264 Known.knownNot(fcZero);
265 }
266
267 return Known;
268}
269
271 const KnownFPClass &KnownRHS,
272 DenormalMode Mode) {
273 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, Mode);
274
275 // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
276 if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
277 KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
278 // Make sure output negative denormal can't flush to -0
279 (Mode.Output == DenormalMode::IEEE ||
280 Mode.Output == DenormalMode::PositiveZero))
281 Known.knownNot(fcNegZero);
282
283 return Known;
284}
285
287 DenormalMode Mode) {
288 KnownFPClass Known = fadd(KnownSrc, KnownSrc, Mode);
289
290 // Doubling 0 will give the same 0.
291 if (KnownSrc.isKnownNeverLogicalPosZero(Mode) &&
292 (Mode.Output == DenormalMode::IEEE ||
293 (Mode.Output == DenormalMode::PreserveSign &&
294 KnownSrc.isKnownNeverPosSubnormal()) ||
295 (Mode.Output == DenormalMode::PositiveZero &&
296 KnownSrc.isKnownNeverSubnormal())))
297 Known.knownNot(fcPosZero);
298
299 return Known;
300}
301
303 const KnownFPClass &KnownRHS,
304 DenormalMode Mode) {
305 return fadd(KnownLHS, fneg(KnownRHS), Mode);
306}
307
309 const KnownFPClass &KnownRHS,
310 DenormalMode Mode) {
311 KnownFPClass Known;
312
313 // xor sign bit.
314 if ((KnownLHS.isKnownNever(fcNegative) &&
315 KnownRHS.isKnownNever(fcNegative)) ||
316 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
317 Known.knownNot(fcNegative);
318
319 if ((KnownLHS.isKnownNever(fcPositive) &&
320 KnownRHS.isKnownNever(fcNegative)) ||
321 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
322 Known.knownNot(fcPositive);
323
324 // inf * anything => inf or nan
325 if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
326 KnownRHS.isKnownAlways(fcInf | fcNan))
328
329 // 0 * anything => 0 or nan
330 if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
331 KnownLHS.isKnownAlways(fcZero | fcNan))
333
334 // +/-0 * +/-inf = nan
335 if ((KnownLHS.isKnownAlways(fcZero | fcNan) &&
336 KnownRHS.isKnownAlways(fcInf | fcNan)) ||
337 (KnownLHS.isKnownAlways(fcInf | fcNan) &&
338 KnownRHS.isKnownAlways(fcZero | fcNan)))
339 Known.knownNot(~fcNan);
340
341 if (!KnownLHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
342 return Known;
343
344 if (KnownLHS.SignBit && KnownRHS.SignBit) {
345 if (*KnownLHS.SignBit == *KnownRHS.SignBit)
346 Known.signBitMustBeZero();
347 else
348 Known.signBitMustBeOne();
349 }
350
351 // If 0 * +/-inf produces NaN.
352 if ((KnownRHS.isKnownNeverInfinity() ||
353 KnownLHS.isKnownNeverLogicalZero(Mode)) &&
354 (KnownLHS.isKnownNeverInfinity() ||
355 KnownRHS.isKnownNeverLogicalZero(Mode)))
356 Known.knownNot(fcNan);
357
358 return Known;
359}
360
362 const KnownFPClass &KnownRHS,
363 DenormalMode Mode) {
364 KnownFPClass Known;
365
366 // Only 0/0, Inf/Inf produce NaN.
367 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
368 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
369 (KnownLHS.isKnownNeverLogicalZero(Mode) ||
370 KnownRHS.isKnownNeverLogicalZero(Mode))) {
371 Known.knownNot(fcNan);
372 }
373
374 // xor sign bit.
375 // X / -0.0 is -Inf (or NaN).
376 // +X / +X is +X
377 if ((KnownLHS.isKnownNever(fcNegative) &&
378 KnownRHS.isKnownNever(fcNegative)) ||
379 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
380 Known.knownNot(fcNegative);
381
382 if ((KnownLHS.isKnownNever(fcPositive) &&
383 KnownRHS.isKnownNever(fcNegative)) ||
384 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
385 Known.knownNot(fcPositive);
386
387 // 0 / x => 0 or nan
388 if (KnownLHS.isKnownAlways(fcZero))
390
391 // x / 0 => nan or inf
392 if (KnownRHS.isKnownAlways(fcZero))
393 Known.knownNot(fcFinite);
394
395 return Known;
396}
397
399 DenormalMode Mode) {
400 // X / X is always exactly 1.0 or a NaN.
402
403 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
404 Known.knownNot(fcNan);
405 else if (KnownSrc.isKnownNever(fcSNan))
406 Known.knownNot(fcSNan);
407
408 return Known;
409}
411 DenormalMode Mode) {
412 // X % X is always exactly [+-]0.0 or a NaN.
413 KnownFPClass Known(fcNan | fcZero);
414
415 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
416 Known.knownNot(fcNan);
417 else if (KnownSrc.isKnownNever(fcSNan))
418 Known.knownNot(fcSNan);
419
420 return Known;
421}
422
424 const KnownFPClass &KnownRHS,
425 const KnownFPClass &KnownAddend,
426 DenormalMode Mode) {
427 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, Mode);
428
429 // FMA differs from the base fmul + fadd handling only in the treatment of -0
430 // results.
431 //
432 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
433 // unlike for a separate fadd.
434 return fadd_impl(Mul, KnownAddend, Mode);
435}
436
438 const KnownFPClass &KnownAddend,
439 DenormalMode Mode) {
440 KnownFPClass Squared = square(KnownSquared, Mode);
441 KnownFPClass Known = fadd_impl(Squared, KnownAddend, Mode);
442
443 // Since we know the squared input must be positive, the add of opposite sign
444 // infinities nan hazard only applies for negative inf.
445 //
446 // TODO: Alternatively to proving addend is not -inf, we could know Squared is
447 // not pinf. Other than the degenerate always-subnormal input case, we can't
448 // prove that without a known range.
449 if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
450 Known.knownNot(fcNan);
451
452 return Known;
453}
454
456 KnownFPClass Known;
457 Known.knownNot(fcNegative);
458
459 Known.propagateNaN(KnownSrc);
460
461 if (KnownSrc.cannotBeOrderedLessThanZero()) {
462 // If the source is positive this cannot underflow.
463 Known.knownNot(fcPosZero);
464
465 // Cannot introduce denormal values.
467 }
468
469 // If the source is negative, this cannot overflow to infinity.
470 if (KnownSrc.cannotBeOrderedGreaterThanZero())
471 Known.knownNot(fcPosInf);
472
473 return Known;
474}
475
477 DenormalMode Mode) {
478 propagateDenormal(Src, Mode);
479 propagateNaN(Src, /*PreserveSign=*/true);
480}
481
483 DenormalMode Mode) {
484 KnownFPClass Known;
486
487 if (KnownSrc.isKnownNeverPosInfinity())
488 Known.knownNot(fcPosInf);
489
490 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
491 Known.knownNot(fcNan);
492
493 if (KnownSrc.isKnownNeverLogicalZero(Mode))
494 Known.knownNot(fcNegInf);
495
496 return Known;
497}
498
500 DenormalMode Mode) {
501 KnownFPClass Known;
503
504 if (KnownSrc.isKnownNeverPosInfinity())
505 Known.knownNot(fcPosInf);
506 if (KnownSrc.isKnownNever(fcSNan))
507 Known.knownNot(fcSNan);
508
509 // Any negative value besides -0 returns a nan.
510 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
511 Known.knownNot(fcNan);
512
513 // The only negative value that can be returned is -0 for -0 inputs.
515
516 // If the input denormal mode could be PreserveSign, a negative
517 // subnormal input could produce a negative zero output.
518 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
519 Known.knownNot(fcNegZero);
520
521 return Known;
522}
523
525 KnownFPClass Known;
526
527 // Return NaN on infinite inputs.
528 Known.knownNot(fcInf);
529 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
530 Known.knownNot(fcNan);
531
532 return Known;
533}
534
536 return sin(KnownSrc);
537}
538
540 const fltSemantics &DstTy,
541 const fltSemantics &SrcTy) {
542 // Infinity, nan and zero propagate from source.
543 KnownFPClass Known = KnownSrc;
544
545 // All subnormal inputs should be in the normal range in the result type.
546 if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
547 if (Known.KnownFPClasses & fcPosSubnormal)
549 if (Known.KnownFPClasses & fcNegSubnormal)
551 Known.knownNot(fcSubnormal);
552 }
553
554 // Sign bit of a nan isn't guaranteed.
555 if (!Known.isKnownNeverNaN())
556 Known.SignBit = std::nullopt;
557
558 return Known;
559}
560
562 KnownFPClass Known;
563
564 // Sign should be preserved
565 // TODO: Handle cannot be ordered greater than zero
566 if (KnownSrc.cannotBeOrderedLessThanZero())
568
569 Known.propagateNaN(KnownSrc, true);
570
571 // Infinity needs a range check.
572 return Known;
573}
574
576 bool IsTrunc,
577 bool IsMultiUnitFPType) {
578 KnownFPClass Known;
579
580 // Integer results cannot be subnormal.
581 Known.knownNot(fcSubnormal);
582
583 Known.propagateNaN(KnownSrc, true);
584
585 // Pass through infinities, except PPC_FP128 is a special case for
586 // intrinsics other than trunc.
587 if (IsTrunc || !IsMultiUnitFPType) {
588 if (KnownSrc.isKnownNeverPosInfinity())
589 Known.knownNot(fcPosInf);
590 if (KnownSrc.isKnownNeverNegInfinity())
591 Known.knownNot(fcNegInf);
592 }
593
594 // Negative round ups to 0 produce -0
595 if (KnownSrc.isKnownNever(fcPosFinite))
596 Known.knownNot(fcPosFinite);
597 if (KnownSrc.isKnownNever(fcNegFinite))
598 Known.knownNot(fcNegFinite);
599
600 return Known;
601}
602
604 DenormalMode Mode) {
605 KnownFPClass Known;
606 Known.knownNot(fcSubnormal);
607
608 if (KnownSrc.isKnownNever(fcNegative))
609 Known.knownNot(fcNegative);
610 else {
611 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
612 Known.knownNot(fcNegZero);
613 if (KnownSrc.isKnownNever(fcNegInf))
614 Known.knownNot(fcNegInf);
615 }
616
617 if (KnownSrc.isKnownNever(fcPositive))
618 Known.knownNot(fcPositive);
619 else {
620 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
621 Known.knownNot(fcPosZero);
622 if (KnownSrc.isKnownNever(fcPosInf))
623 Known.knownNot(fcPosInf);
624 }
625
626 Known.propagateNaN(KnownSrc);
627 return Known;
628}
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS, const KnownFPClass &KnownRHS, DenormalMode Mode)
static bool inputDenormalIsIEEE(DenormalMode Mode)
Return true if it's possible to assume IEEE treatment of input denormals in F for Val.
static bool inputDenormalIsIEEEOrPosZero(DenormalMode Mode)
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")))
static LLVM_ABI bool isRepresentableAsNormalIn(const fltSemantics &Src, const fltSemantics &Dst)
Definition APFloat.cpp:263
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Mul
Product of integers.
Represent subnormal handling kind for floating point instruction inputs and outputs.
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.
@ 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 bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
static constexpr DenormalMode getPreserveSign()
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static constexpr DenormalMode getIEEE()
bool isKnownNeverInfOrNaN() const
Return true if it's known this can never be an infinity or 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.
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
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.
LLVM_ABI void propagateDenormal(const KnownFPClass &Src, DenormalMode Mode)
Propagate knowledge from a source value that could be a denormal or zero.
static LLVM_ABI KnownFPClass fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv.
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 minMaxLike(const KnownFPClass &LHS, const KnownFPClass &RHS, MinMaxKind Kind, DenormalMode DenormMode=DenormalMode::getDynamic())
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 ...
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.
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.
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.
static LLVM_ABI KnownFPClass fadd(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd.
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 fma_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma squared, squared, addend.
static LLVM_ABI KnownFPClass frem_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem.
bool isKnownNeverPosSubnormal() const
Return true if it's known this can never be a positive subnormal.