LLVM 24.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"
18
19using namespace llvm;
20
22 : KnownFPClassesValue(C.classify()) {
23 setSignBit(C.isNegative());
24}
25
26/// Return true if it's possible to assume IEEE treatment of input denormals in
27/// \p F for \p Val.
29 return Mode.Input == DenormalMode::IEEE;
30}
31
36
41
46
49 return false;
50
51 // If we know there are no denormals, nothing can be flushed to zero.
53 return true;
54
55 switch (Mode.Input) {
57 return true;
59 // Negative subnormal won't flush to +0
62 default:
63 // Both positive and negative subnormal could flush to +0
64 return false;
65 }
66
67 llvm_unreachable("covered switch over denormal mode");
68}
69
71 DenormalMode Mode) {
72 setKnownFPClasses(Src.getKnownFPClasses());
73 // If we aren't assuming the source can't be a zero, we don't have to check if
74 // a denormal input could be flushed.
75 if (!Src.isKnownNeverPosZero() && !Src.isKnownNeverNegZero())
76 return;
77
78 // If we know the input can't be a denormal, it can't be flushed to 0.
79 if (Src.isKnownNeverSubnormal())
80 return;
81
82 if (!Src.isKnownNeverPosSubnormal() && Mode != DenormalMode::getIEEE())
84
85 if (!Src.isKnownNeverNegSubnormal() && Mode != DenormalMode::getIEEE()) {
88
89 if (Mode.Input == DenormalMode::PositiveZero ||
90 Mode.Output == DenormalMode::PositiveZero ||
91 Mode.Input == DenormalMode::Dynamic ||
92 Mode.Output == DenormalMode::Dynamic)
94 }
95}
96
98 const KnownFPClass &RHS_, MinMaxKind Kind,
99 DenormalMode Mode) {
100 KnownFPClass KnownLHS = LHS_;
101 KnownFPClass KnownRHS = RHS_;
102
103 bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
104 KnownFPClass Known = KnownLHS | KnownRHS;
105
106 // If either operand is not NaN, the result is not NaN.
107 if (NeverNaN &&
108 (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
110 Known.knownNot(fcNan);
111
112 if (Kind == MinMaxKind::maxnum || Kind == MinMaxKind::maximumnum) {
113 if (KnownLHS.isKnownNeverNaN())
114 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses()));
115 if (KnownRHS.isKnownNeverNaN())
116 Known.knownNot(orderedStrictlyLess(KnownRHS.getKnownFPClasses()));
117 } else if (Kind == MinMaxKind::maximum) {
118 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses()) |
120 } else if (Kind == MinMaxKind::minnum || Kind == MinMaxKind::minimumnum) {
121 if (KnownLHS.isKnownNeverNaN())
122 Known.knownNot(orderedStrictlyGreater(KnownLHS.getKnownFPClasses()));
123 if (KnownRHS.isKnownNeverNaN())
124 Known.knownNot(orderedStrictlyGreater(KnownRHS.getKnownFPClasses()));
125 } else if (Kind == MinMaxKind::minimum) {
126 Known.knownNot(orderedStrictlyGreater(KnownLHS.getKnownFPClasses()) |
128 } else
129 llvm_unreachable("unhandled intrinsic");
130
131 // Fixup zero handling if denormals could be returned as a zero.
132 //
133 // As there's no spec for denormal flushing, be conservative with the
134 // treatment of denormals that could be flushed to zero. For older
135 // subtargets on AMDGPU the min/max instructions would not flush the
136 // output and return the original value.
137 //
138 if ((Known.getKnownFPClasses() & fcZero) != fcNone &&
139 !Known.isKnownNeverSubnormal()) {
140 if (Mode != DenormalMode::getIEEE())
141 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcZero);
142 }
143
144 if (Known.isKnownNeverNaN()) {
145 if (KnownLHS.getSignBit() && KnownRHS.getSignBit() &&
146 *KnownLHS.getSignBit() == *KnownRHS.getSignBit()) {
147 if (*KnownLHS.getSignBit())
148 Known.signBitMustBeOne();
149 else
150 Known.signBitMustBeZero();
151 } else if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::minimum ||
152 Kind == MinMaxKind::maximumnum ||
153 Kind == MinMaxKind::minimumnum) ||
154 // FIXME: Should be using logical zero versions
155 ((KnownLHS.isKnownNeverNegZero() ||
156 KnownRHS.isKnownNeverPosZero()) &&
157 (KnownLHS.isKnownNeverPosZero() ||
158 KnownRHS.isKnownNeverNegZero()))) {
159 // Don't take sign bit from NaN operands.
160 if (!KnownLHS.isKnownNeverNaN())
161 KnownLHS.setSignBit(std::nullopt);
162 if (!KnownRHS.isKnownNeverNaN())
163 KnownRHS.setSignBit(std::nullopt);
164 if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::maximumnum ||
165 Kind == MinMaxKind::maxnum) &&
166 (KnownLHS.getSignBit() == false || KnownRHS.getSignBit() == false))
167 Known.signBitMustBeZero();
168 else if ((Kind == MinMaxKind::minimum || Kind == MinMaxKind::minimumnum ||
169 Kind == MinMaxKind::minnum) &&
170 (KnownLHS.getSignBit() == true || KnownRHS.getSignBit() == true))
171 Known.signBitMustBeOne();
172 }
173 }
174
175 return Known;
176}
177
179 DenormalMode DenormMode) {
181
182 // This is essentially a stronger form of
183 // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
184 // actually have an IR canonicalization guarantee.
185
186 // Canonicalize may flush denormals to zero, so we have to consider the
187 // denormal mode to preserve known-not-0 knowledge.
188 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcZero | fcQNan);
189
190 // Stronger version of propagateNaN
191 // Canonicalize is guaranteed to quiet signaling nans.
192 if (KnownSrc.isKnownNeverNaN())
193 Known.knownNot(fcNan);
194 else
195 Known.knownNot(fcSNan);
196
197 // FIXME: Missing check of IEEE like types.
198
199 // If the parent function flushes denormals, the canonical output cannot be a
200 // denormal.
201 if (DenormMode == DenormalMode::getIEEE()) {
202 if (KnownSrc.isKnownNever(fcPosZero))
203 Known.knownNot(fcPosZero);
204 if (KnownSrc.isKnownNever(fcNegZero))
205 Known.knownNot(fcNegZero);
206 return Known;
207 }
208
209 if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
210 Known.knownNot(fcSubnormal);
211
212 if (DenormMode == DenormalMode::getPreserveSign()) {
213 if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
214 Known.knownNot(fcPosZero);
215 if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
216 Known.knownNot(fcNegZero);
217 return Known;
218 }
219
220 if (DenormMode.Input == DenormalMode::PositiveZero ||
221 (DenormMode.Output == DenormalMode::PositiveZero &&
222 DenormMode.Input == DenormalMode::IEEE)) {
223 // -0.0 is not a subnormal and should not be flushed.
224 if (KnownSrc.isKnownNever(fcNegZero))
225 Known.knownNot(fcNegZero);
226
227 if (KnownSrc.isKnownNever(fcPosZero | fcSubnormal))
228 Known.knownNot(fcPosZero);
229 }
230
231 return Known;
232}
233
235 const KnownBits &Bits) {
236 assert(FltSemantics.sizeInBits == Bits.getBitWidth() &&
237 "Bitcast operand has incorrect bit width");
239
240 // Conflicting known bits do not describe a concrete value. Return unknown.
241 if (Bits.hasConflict())
242 return Known;
243
244 // Return unknown for types we have not validated.
245 auto IsSupported = [](const fltSemantics &Semantics) {
246 switch (APFloat::SemanticsToEnum(Semantics)) {
253 return true;
254 default:
255 return false;
256 }
257 };
258 if (!IsSupported(FltSemantics))
259 return Known;
260
261 // Transfer information from the sign bit.
262 if (Bits.isNonNegative())
263 Known.signBitMustBeZero();
264 else if (Bits.isNegative())
265 Known.signBitMustBeOne();
266
267 if (APFloat::isIEEELikeFP(FltSemantics)) {
268 const unsigned MantissaBits = FltSemantics.precision - 1;
269 const APInt ExponentMask = APInt::getBitsSet(
270 FltSemantics.sizeInBits, MantissaBits, FltSemantics.sizeInBits - 1);
271 const APInt MantissaMask =
272 APInt::getLowBitsSet(FltSemantics.sizeInBits, MantissaBits);
273
274 const bool ExponentKnownAllZeros =
275 (Bits.Zero & ExponentMask) == ExponentMask;
276 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
277 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
278 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
279
280 const bool MantissaKnownAllZeros =
281 (Bits.Zero & MantissaMask) == MantissaMask;
282 const bool MantissaKnownNotAllZeros = !(Bits.One & MantissaMask).isZero();
283
284 // Zero and subnormal require an exponent with all zero bits.
285 if (ExponentKnownNotAllZeros)
286 Known.knownNot(fcZero | fcSubnormal);
287
288 // Infinity and NaN require an exponent with all one bits.
289 if (ExponentKnownNotAllOnes)
290 Known.knownNot(fcInf | fcNan);
291
292 // Normal values have an exponent that is not all zeros or all ones.
293 if (ExponentKnownAllZeros || ExponentKnownAllOnes)
294 Known.knownNot(fcNormal);
295
296 // Zero and infinity require a mantissa with all zero bits.
297 if (MantissaKnownNotAllZeros)
298 Known.knownNot(fcZero | fcInf);
299
300 // Subnormal and NaN require a non-zero mantissa.
301 if (MantissaKnownAllZeros)
302 Known.knownNot(fcSubnormal | fcNan);
303
304 const bool QuietBitKnownSet = Bits.One[MantissaBits - 1];
305 const bool QuietBitKnownClear = Bits.Zero[MantissaBits - 1];
306
307 if (QuietBitKnownSet)
308 Known.knownNot(fcSNan);
309 else if (QuietBitKnownClear)
310 Known.knownNot(fcQNan);
311 }
312
313 return Known;
314}
315
317 KnownBits Known(FltSemantics.sizeInBits);
318 const FPClassTest FPClasses = getKnownFPClasses();
319
320 // Return unknown if poison.
321 if (FPClasses == fcNone)
322 return Known;
323
324 // Return unknown for types we have not validated.
325 auto IsSupported = [](const fltSemantics &Semantics) {
326 switch (APFloat::SemanticsToEnum(Semantics)) {
333 return true;
334 default:
335 return false;
336 }
337 };
338 if (!IsSupported(FltSemantics))
339 return Known;
340
341 switch (APFloat::SemanticsToEnum(FltSemantics)) {
347 // For ieee types, we cannot deduce anything if the source could be normal.
348 if (FPClasses & fcNormal)
349 break;
350
351 Known.setAllConflict();
352
353 const unsigned BitWidth = FltSemantics.sizeInBits;
354 const unsigned MantissaBits = FltSemantics.precision - 1;
355 const unsigned ExponentBits = BitWidth - MantissaBits - 1;
356
357 APInt MantissaMask = APInt::getLowBitsSet(BitWidth, MantissaBits);
358 APInt ExponentMask =
359 APInt::getBitsSet(BitWidth, MantissaBits, MantissaBits + ExponentBits);
360
361 const unsigned QuietBitIndex = MantissaBits - 1;
362 APInt PayloadMask = MantissaMask;
363 PayloadMask.clearBit(QuietBitIndex);
364
365 if (FPClasses & fcNan) {
366 // Exponent bits cannot be zeros.
367 Known.Zero &= ~ExponentMask;
368 // No individual payload bit is known.
369 Known.Zero &= ~PayloadMask;
370 Known.One &= ~PayloadMask;
371
372 if (FPClasses & fcQNan)
373 Known.Zero.clearBit(QuietBitIndex);
374 if (FPClasses & fcSNan)
375 Known.One.clearBit(QuietBitIndex);
376 }
377 if (FPClasses & fcInf) {
378 // Exponent bits cannot be zeros.
379 Known.Zero &= ~ExponentMask;
380 // Mantissa bits cannot be ones.
381 Known.One &= ~MantissaMask;
382 }
383 if (FPClasses & fcSubnormal) {
384 // Exponent bits cannot be ones.
385 Known.One &= ~ExponentMask;
386 // Unknown mantissa.
387 Known.One &= ~MantissaMask;
388 Known.Zero &= ~MantissaMask;
389 }
390 if (FPClasses & fcZero) {
391 // Exponent bits cannot be ones.
392 Known.One &= ~ExponentMask;
393 // Mantissa cannot be ones.
394 Known.One &= ~MantissaMask;
395 }
396
397 break;
398 }
401 break;
402
403 Known.setAllConflict();
404
405 if (FPClasses & fcInf)
406 Known = Known.intersectWith(KnownBits::makeConstant(
407 APFloat::getInf(FltSemantics).bitcastToAPInt()));
408
409 if (FPClasses & fcZero)
410 Known = Known.intersectWith(
412
413 break;
414 }
415 default:
416 llvm_unreachable("unhandled supported semantics");
417 }
418
419 Known.Zero.clearSignBit();
420 Known.One.clearSignBit();
421 if (std::optional<bool> Sign = getSignBit()) {
422 if (*Sign)
423 Known.makeNegative();
424 else
425 Known.makeNonNegative();
426 }
427
428 return Known;
429}
430
431// Handle known sign bit and nan cases for fadd.
432static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
433 const KnownFPClass &KnownRHS, DenormalMode Mode) {
435
436 // Adding positive and negative infinity produces NaN, but only if both
437 // opposite-sign infinity combinations are possible.
438 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
439 (KnownLHS.isKnownNever(fcPosInf) || KnownRHS.isKnownNever(fcNegInf)) &&
440 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosInf)))
441 Known.knownNot(fcNan);
442
443 if (KnownLHS.cannotBeOrderedLessThanZero() &&
444 KnownRHS.cannotBeOrderedLessThanZero()) {
446
447 // This can't underflow if one of the operands is known normal.
448 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
450 Known.knownNot(fcZero | fcPosSubnormal);
451 }
452
453 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
456
457 // This can't underflow if one of the operands is known normal.
458 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
460 Known.knownNot(fcZero | fcNegSubnormal);
461 }
462
463 return Known;
464}
465
467 const KnownFPClass &KnownRHS,
468 DenormalMode Mode) {
469 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, Mode);
470
471 // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
472 if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
473 KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
474 // Make sure output negative denormal can't flush to -0
475 (Mode.Output == DenormalMode::IEEE ||
476 Mode.Output == DenormalMode::PositiveZero))
477 Known.knownNot(fcNegZero);
478
479 Known.propagateNonSNaN(KnownLHS, KnownRHS);
480
481 return Known;
482}
483
485 DenormalMode Mode) {
486 KnownFPClass Known = fadd(KnownSrc, KnownSrc, Mode);
487
488 // Doubling 0 will give the same 0.
489 if (KnownSrc.isKnownNeverLogicalPosZero(Mode) &&
490 (Mode.Output == DenormalMode::IEEE ||
491 (Mode.Output == DenormalMode::PreserveSign &&
492 KnownSrc.isKnownNeverPosSubnormal()) ||
493 (Mode.Output == DenormalMode::PositiveZero &&
494 KnownSrc.isKnownNeverSubnormal())))
495 Known.knownNot(fcPosZero);
496
497 return Known;
498}
499
501 const KnownFPClass &KnownRHS,
502 DenormalMode Mode) {
503 return fadd(KnownLHS, fneg(KnownRHS), Mode);
504}
505
507 const KnownFPClass &KnownRHS,
508 DenormalMode Mode) {
510
511 Known.propagateNonSNaN(KnownLHS, KnownRHS);
512
513 // +X * +Y or -X * -Y => +Q
514 // +X * -Y or -X * +Y => -Q
515 Known.propagateXorSign(KnownLHS, KnownRHS);
516
517 // Inf * Y => Inf or NaN
518 if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
519 KnownRHS.isKnownAlways(fcInf | fcNan))
520 Known.knownNot(fcNormal | fcSubnormal | fcZero);
521
522 // 0 * Y => 0 or NaN
523 if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
524 KnownLHS.isKnownAlways(fcZero | fcNan))
525 Known.knownNot(fcNormal | fcSubnormal | fcInf);
526
527 if (!KnownLHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
528 return Known;
529
530 // 0 * +/-inf => NaN
531 if ((KnownRHS.isKnownNeverInfinity() ||
532 KnownLHS.isKnownNeverLogicalZero(Mode)) &&
533 (KnownLHS.isKnownNeverInfinity() ||
534 KnownRHS.isKnownNeverLogicalZero(Mode)))
535 Known.knownNot(fcNan);
536
537 return Known;
538}
539
540// TODO: This generalizes to known ranges
542 const APFloat &CRHS, DenormalMode Mode) {
543 // Match denormal scaling pattern, similar to the case in ldexp. If the
544 // constant's exponent is sufficiently large, the result cannot be subnormal.
545
546 const fltSemantics &Flt = CRHS.getSemantics();
547 unsigned Precision = APFloat::semanticsPrecision(Flt);
548 const int MantissaBits = Precision - 1;
549
550 int MinKnownExponent = ilogb(CRHS);
551 bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);
552
553 KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
554 if (CannotBeSubnormal)
555 Known.knownNot(fcSubnormal);
556
557 // Multiply of values <= 1 cannot introduce overflow.
558 if (KnownLHS.isKnownNever(fcInf)) {
559 if (MinKnownExponent < 0)
560 Known.knownNot(fcInf);
561 else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
562 Flt)) == APFloat::cmpEqual)
563 Known.knownNot(fcInf);
564 }
565
566 return Known;
567}
568
570 const KnownFPClass &KnownRHS,
571 DenormalMode Mode) {
573
574 Known.propagateNonSNaN(KnownLHS, KnownRHS);
575
576 // Only 0/0, Inf/Inf produce NaN.
577 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
578 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
579 (KnownLHS.isKnownNeverLogicalZero(Mode) ||
580 KnownRHS.isKnownNeverLogicalZero(Mode))) {
581 Known.knownNot(fcNan);
582 }
583
584 // X / -0.0 => -Inf (or NaN)
585 // +X / +Y or -X / -Y => +Q
586 // +X / -Y or -X / +Y => -Q
587 Known.propagateXorSign(KnownLHS, KnownRHS);
588
589 // Normal and subnormal results require two non-zero finite operands.
590 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
594 Known.knownNot(fcNegNormal | fcNegSubnormal);
595 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
599 Known.knownNot(fcPosNormal | fcPosSubnormal);
600
601 // 0 / X => 0 or NaN
602 if (KnownLHS.isKnownAlways(fcZero))
603 Known.knownNot(fcSubnormal | fcNormal | fcInf);
604
605 // X / 0 => NaN or Inf
606 if (KnownRHS.isKnownAlways(fcZero))
607 Known.knownNot(fcFinite);
608
609 return Known;
610}
611
613 DenormalMode Mode) {
614 // X / X is always exactly 1.0 or a NaN.
616
617 Known.propagateNonSNaN(KnownSrc);
618
619 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
620 Known.knownNot(fcNan);
621
622 return Known;
623}
624
626 const KnownFPClass &KnownRHS,
627 DenormalMode Mode) {
629
630 Known.knownNot(fcInf);
631
632 // Inf REM x and x REM 0 produce NaN.
633 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
634 KnownLHS.isKnownNeverInfinity() &&
635 KnownRHS.isKnownNeverLogicalZero(Mode)) {
636 Known.knownNot(fcNan);
637 }
638
639 // The sign for frem is the same as the first operand.
640 if (KnownLHS.cannotBeOrderedLessThanZero())
642 if (KnownLHS.cannotBeOrderedGreaterThanZero())
644
645 // See if we can be more aggressive about the sign of 0.
646 if (KnownLHS.isKnownNever(fcNegative))
647 Known.knownNot(fcNegative);
648 if (KnownLHS.isKnownNever(fcPositive))
649 Known.knownNot(fcPositive);
650
651 return Known;
652}
653
655 DenormalMode Mode) {
656 // X % X is always exactly [+-]0.0 or a NaN.
658
659 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
660 Known.knownNot(fcNan);
661 else if (KnownSrc.isKnownNever(fcSNan))
662 Known.knownNot(fcSNan);
663
664 return Known;
665}
666
668 const KnownFPClass &KnownRHS,
669 const KnownFPClass &KnownAddend,
670 DenormalMode Mode) {
671 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, Mode);
672
673 // FMA differs from the base fmul + fadd handling only in the treatment of -0
674 // results.
675 //
676 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
677 // unlike for a separate fadd.
678 KnownFPClass Known = fadd_impl(Mul, KnownAddend, Mode);
679
680 // propagateNonSNaN for 3 arguments.
681 if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
682 KnownAddend.isKnownNever(fcSNan))
683 Known.knownNot(fcSNan);
684
685 return Known;
686}
687
689 const KnownFPClass &KnownAddend,
690 DenormalMode Mode) {
691 KnownFPClass Squared = square(KnownSquared, Mode);
692 KnownFPClass Known = fadd_impl(Squared, KnownAddend, Mode);
693
694 // Since we know the squared input must be positive, the add of opposite sign
695 // infinities nan hazard only applies for negative inf.
696 //
697 // TODO: Alternatively to proving addend is not -inf, we could know Squared is
698 // not pinf. Other than the degenerate always-subnormal input case, we can't
699 // prove that without a known range.
700 if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
701 Known.knownNot(fcNan);
702
703 Known.propagateNonSNaN(KnownSquared, KnownAddend);
704
705 return Known;
706}
707
710 Known.knownNot(fcNegative);
711
712 Known.propagateNonNaN(KnownSrc);
713
714 if (KnownSrc.cannotBeOrderedLessThanZero()) {
715 // If the source is positive this cannot underflow.
716 Known.knownNot(fcPosZero);
717
718 // Cannot introduce denormal values.
719 Known.knownNot(fcPosSubnormal);
720 }
721
722 // If the source is negative, this cannot overflow to infinity.
723 if (KnownSrc.cannotBeOrderedGreaterThanZero())
724 Known.knownNot(fcPosInf);
725
726 return Known;
727}
728
734
736 DenormalMode Mode) {
738 Known.knownNot(fcNegZero | fcSubnormal);
739
740 Known.propagateNonSNaN(KnownSrc);
741
742 if (KnownSrc.isKnownNeverPosInfinity())
743 Known.knownNot(fcPosInf);
744
745 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
746 Known.knownNot(fcNan);
747
748 if (KnownSrc.isKnownNeverLogicalZero(Mode))
749 Known.knownNot(fcNegInf);
750
751 return Known;
752}
753
755 DenormalMode Mode) {
757 Known.knownNot(fcPosSubnormal);
758
759 if (KnownSrc.isKnownNeverPosInfinity())
760 Known.knownNot(fcPosInf);
761
762 Known.propagateNonSNaN(KnownSrc);
763
764 // Any negative value besides -0.0 returns a nan.
765 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
766 Known.knownNot(fcNan);
767
768 // The only negative value that can be returned is -0.0 for -0.0 inputs.
770
771 // Only sqrt(+0.0) == +0.0. However, subnormals may also be treated as +0.0
772 // depending on the input denormal mode.
773 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
774 Known.knownNot(fcPosZero);
775
776 // Only sqrt(-0.0) == -0.0. However, negative subnormals may also be treated
777 // as -0.0 depending on the input denormal mode.
778 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
779 Known.knownNot(fcNegZero);
780
781 return Known;
782}
783
786
787 Known.propagateNonSNaN(KnownSrc);
788
789 // Return NaN on infinite inputs.
790 Known.knownNot(fcInf);
791 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
792 Known.knownNot(fcNan);
793
794 return Known;
795}
796
798 return sin(KnownSrc);
799}
800
803
804 // tan never returns Inf (tan(+-Inf) = NaN; tan(finite) = finite).
805 Known.knownNot(fcInf);
806
807 Known.propagateNonSNaN(KnownSrc);
808
809 // NaN propagates. tan(+-Inf) is NaN.
810 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
811 Known.knownNot(fcNan);
812
813 return Known;
814}
815
818
819 // sinh is sign-preserving: sinh(x) < 0 iff x < 0.
820 if (KnownSrc.isKnownNever(fcNegative))
821 Known.knownNot(fcNegative);
822
823 Known.propagateNonNaN(KnownSrc);
824
825 return Known;
826}
827
830
831 // cosh(x) >= 1 for all real x; cosh(+-Inf) = +Inf. Never negative,
832 // zero, or subnormal.
833 Known.knownNot(fcNegative | fcZero | fcSubnormal);
834
835 Known.propagateNonNaN(KnownSrc);
836
837 return Known;
838}
839
842
843 // tanh is bounded to (-1, 1), never Inf.
844 Known.knownNot(fcInf);
845
846 // tanh is sign-preserving: tanh(x) < 0 iff x < 0.
847 if (KnownSrc.isKnownNever(fcNegative))
848 Known.knownNot(fcNegative);
849
850 Known.propagateNonNaN(KnownSrc);
851
852 return Known;
853}
854
857
858 // asin is bounded to [-pi/2, pi/2], never Inf.
859 Known.knownNot(fcInf);
860
861 Known.propagateNonSNaN(KnownSrc);
862
863 // asin is sign-preserving for finite arguments.
864 if (KnownSrc.isKnownNever(fcNegFinite))
865 Known.knownNot(fcNegFinite);
866
867 // NaN propagates. asin(x) is also NaN for |x| > 1, so we cannot rule
868 // out NaN without knowing the source is in [-1, 1].
869 return Known;
870}
871
874
875 // acos(x) is bounded to [0, pi] for -1 <= x <= 1, and is never negative,
876 // infinite, or subnormal. The smallest non-zero value occurs when x is
877 // close to 1.0, where acos(x) can be approximated by sqrt(2 * (1 - x)).
878 // Since sqrt cannot produce a subnormal result, we can conclude that
879 // acos(x) will also never produce a subnormal result.
880 Known.knownNot(fcNegative | fcInf | fcSubnormal);
881
882 // acos(x) == +0.0 iff x == +1.0
883 if (KnownSrc.isKnownNever(fcPosNormal))
884 Known.knownNot(fcZero);
885
886 Known.propagateNonSNaN(KnownSrc);
887
888 // NaN propagates. acos(x) is also NaN for |x| > 1, so we cannot rule
889 // out NaN without knowing the source is in [-1, 1].
890 return Known;
891}
892
895
896 // atan is bounded to (-pi/2, pi/2), never Inf. atan(+-Inf) = +-pi/2 (finite).
897 Known.knownNot(fcInf);
898
899 // atan is sign-preserving: atan(x) < 0 iff x < 0.
900 if (KnownSrc.isKnownNever(fcNegative))
901 Known.knownNot(fcNegative);
902
903 Known.propagateNonNaN(KnownSrc);
904
905 return Known;
906}
907
909 const KnownFPClass &KnownX,
910 DenormalMode Mode) {
912
913 // Even though these deductions are correct, we are ignoring the following
914 // potentially erroneous cases:
915 // * atan2(y, inf) is not subnormal
916 // * atan2(inf, x) is not zero or subnormal
917
918 // atan2 result is in (-pi, pi], never Inf.
919 Known.knownNot(fcInf);
920
921 Known.propagateNonNaN(KnownY, KnownX);
922
923 // Negative subnormals could be treated like positive zero.
924 const bool XCannotHavePositiveInput = KnownX.isKnownNever(fcPositive) &&
925 KnownX.isKnownNeverLogicalPosZero(Mode);
926 const bool YCannotHavePositiveInput = KnownY.isKnownNever(fcPositive) &&
927 KnownY.isKnownNeverLogicalPosZero(Mode);
928
929 // If x <= -0.0, then |atan2(y, x)| >= pi/2
930 if (XCannotHavePositiveInput)
931 Known.knownNot(fcZero | fcSubnormal);
932
933 // If y >= +0.0, then atan2(y, x) >= +0.0
934 if (KnownY.isKnownNever(fcNegative))
935 Known.knownNot(fcNegative);
936
937 // If y <= -0.0, then atan2(y, x) <= -0.0
938 // We do this deduction last in case we were able to rule out a negative
939 // subnormal result earlier.
940 if (YCannotHavePositiveInput) {
942 // Negative subnormal results can flush to +0.0.
943 if (Known.isKnownNever(fcNegSubnormal) || !Mode.outputsMayBePositiveZero())
944 Known.knownNot(fcPosZero);
945 }
946
947 return Known;
948}
949
951 const fltSemantics &DstTy,
952 const fltSemantics &SrcTy) {
953 // Infinity, nan and zero propagate from source.
954 KnownFPClass Known = KnownSrc;
955
956 // All subnormal inputs should be in the normal range in the result type.
957 if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
958 if (Known.getKnownFPClasses() & fcPosSubnormal)
959 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosNormal);
960 if (Known.getKnownFPClasses() & fcNegSubnormal)
961 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegNormal);
962 Known.knownNot(fcSubnormal);
963 }
964
965 // Sign bit of a nan isn't guaranteed.
966 if (!Known.isKnownNeverNaN())
967 Known.setSignBit(std::nullopt);
968
969 return Known;
970}
971
974
975 // Sign should be preserved
976 // TODO: Handle cannot be ordered greater than zero
977 if (KnownSrc.cannotBeOrderedLessThanZero())
979
980 Known.propagateNonNaN(KnownSrc);
981
982 // Infinity needs a range check.
983 return Known;
984}
985
987 bool IsTrunc,
988 bool IsMultiUnitFPType) {
990
991 // Integer results cannot be subnormal.
992 Known.knownNot(fcSubnormal);
993
994 Known.propagateNonNaN(KnownSrc);
995
996 // Pass through infinities, except PPC_FP128 is a special case for
997 // intrinsics other than trunc.
998 if (IsTrunc || !IsMultiUnitFPType) {
999 if (KnownSrc.isKnownNeverPosInfinity())
1000 Known.knownNot(fcPosInf);
1001 if (KnownSrc.isKnownNeverNegInfinity())
1002 Known.knownNot(fcNegInf);
1003 }
1004
1005 // Negative round ups to 0 produce -0
1006 if (KnownSrc.isKnownNever(fcPosFinite))
1007 Known.knownNot(fcPosFinite);
1008 if (KnownSrc.isKnownNever(fcNegFinite))
1009 Known.knownNot(fcNegFinite);
1010
1011 return Known;
1012}
1013
1015 DenormalMode Mode) {
1017 Known.knownNot(fcSubnormal);
1018
1019 if (KnownSrc.isKnownNever(fcNegative))
1020 Known.knownNot(fcNegative);
1021 else {
1022 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
1023 Known.knownNot(fcNegZero);
1024 if (KnownSrc.isKnownNever(fcNegInf))
1025 Known.knownNot(fcNegInf);
1026 }
1027
1028 if (KnownSrc.isKnownNever(fcPositive))
1029 Known.knownNot(fcPositive);
1030 else {
1031 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
1032 Known.knownNot(fcPosZero);
1033 if (KnownSrc.isKnownNever(fcPosInf))
1034 Known.knownNot(fcPosInf);
1035 }
1036
1037 Known.propagateNonNaN(KnownSrc);
1038 return Known;
1039}
1040
1042 const APInt &ConstantRangeExpMin,
1043 const APInt &ConstantRangeExpMax,
1044 const fltSemantics &Flt, DenormalMode Mode) {
1046 Known.propagateNonNaN(KnownSrc);
1047
1048 // Sign is preserved, but underflows may produce zeroes.
1049 if (KnownSrc.isKnownNever(fcNegative))
1050 Known.knownNot(fcNegative);
1051 else if (KnownSrc.cannotBeOrderedLessThanZero())
1053
1054 if (KnownSrc.isKnownNever(fcPositive))
1055 Known.knownNot(fcPositive);
1056 else if (KnownSrc.cannotBeOrderedGreaterThanZero())
1058
1059 unsigned Precision = APFloat::semanticsPrecision(Flt);
1060 const int MantissaBits = Precision - 1;
1061 if (ConstantRangeExpMin.sge(MantissaBits))
1062 Known.knownNot(fcSubnormal);
1063
1064 if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
1065 // ldexp(x, 0) -> x, so propagate everything.
1066 Known.propagateCanonicalizingSrc(KnownSrc, Mode);
1067 } else if (ConstantRangeExpMax.isNonPositive()) {
1068 // If we know the power is <= 0, can't introduce inf
1069 if (KnownSrc.isKnownNeverPosInfinity())
1070 Known.knownNot(fcPosInf);
1071 if (KnownSrc.isKnownNeverNegInfinity())
1072 Known.knownNot(fcNegInf);
1073 } else if (ConstantRangeExpMin.isNonNegative()) {
1074 // If we know the power is >= 0, can't introduce subnormal or zero
1075 if (KnownSrc.isKnownNeverPosSubnormal())
1076 Known.knownNot(fcPosSubnormal);
1077 if (KnownSrc.isKnownNeverNegSubnormal())
1078 Known.knownNot(fcNegSubnormal);
1079 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
1080 Known.knownNot(fcPosZero);
1081 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
1082 Known.knownNot(fcNegZero);
1083 }
1084
1085 return Known;
1086}
1087
1089 const KnownBits &ExpBits,
1090 const fltSemantics &Flt, DenormalMode Mode) {
1091 return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
1092 ExpBits.getSignedMaxValue(), Flt, Mode);
1093}
1094
1096 const KnownFPClass &KnownRHS) {
1098
1099 Known.propagateNonSNaN(KnownLHS, KnownRHS);
1100
1101 // pow may return NaN if one of the arguments is NaN. NaN may be produced from
1102 // a non-zero-finite-negative base and a non-integer exponent.
1103 if (KnownLHS.isKnownNever(fcNan | fcNegNormal | fcNegSubnormal) &&
1104 KnownRHS.isKnownNeverNaN())
1105 Known.knownNot(fcNan);
1106
1107 // We could rule out negative and subnormal results when exponent is known to
1108 // never be a normal value, but having either argument being known to never be
1109 // normal is unlikely and not worth considering.
1110
1111 // Only a negative base raised to an odd power returns a negative value.
1112 if (KnownLHS.isKnownNever(fcNegative)) {
1113 Known.knownNot(fcNegative);
1114 } else if (KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1115 Known.knownNot(fcNegNormal | fcNegSubnormal);
1116 // See if we can also rule out -0.0 or -inf.
1117 // Here at least one of -0.0 or -inf is a possible base.
1118
1119 // pow(-0.0, odd-positive) = -0.0
1120 // pow(-inf, odd-negative) = -0.0
1121 if ((KnownLHS.isKnownNever(fcNegZero) ||
1122 KnownRHS.isKnownNever(fcPosNormal)) &&
1123 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcNegNormal)))
1124 Known.knownNot(fcNegZero);
1125
1126 // pow(-0.0, odd-negative) = -inf
1127 // pow(-inf, odd-positive) = -inf
1128 if ((KnownLHS.isKnownNever(fcNegZero) ||
1129 KnownRHS.isKnownNever(fcNegNormal)) &&
1130 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosNormal)))
1131 Known.knownNot(fcNegInf);
1132 }
1133
1134 return Known;
1135}
1136
1138 const KnownBits &ExponentKnownBits) {
1140 Known.propagateNonNaN(KnownSrc);
1141
1142 if (ExponentKnownBits.isZero()) {
1143 // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
1144 // return 1.0 or a NaN.
1145 if (KnownSrc.isKnownNever(fcSNan)) {
1146 Known.knownNot(~fcPosNormal);
1147 return Known;
1148 }
1149
1150 Known.knownNot(~(fcPosNormal | fcNan));
1151 return Known;
1152 }
1153
1154 // Given that exp is an integer, here are the
1155 // ways that powi can return a negative value:
1156 //
1157 // powi(x, exp) --> negative if exp is odd and x is negative.
1158 // powi(-0, exp) --> -inf if exp is negative odd.
1159 // powi(-0, exp) --> -0 if exp is positive odd.
1160 // powi(-inf, exp) --> -0 if exp is negative odd.
1161 // powi(-inf, exp) --> -inf if exp is positive odd.
1162 if (KnownSrc.isKnownNever(fcNegative) || ExponentKnownBits.isEven()) {
1163 Known.knownNot(fcNegative);
1164 } else if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1165 Known.knownNot(fcNegNormal | fcNegSubnormal);
1166 // See if we can also rule out -0.0 or -inf.
1167 // Here at least one of -0.0 or -inf is a possible base.
1168
1169 // We already know that ExponentKnownBits.isEven() is false here.
1170 const bool IsKnownNeverOddPositive = ExponentKnownBits.isNegative();
1171 const bool IsKnownNeverOddNegative = ExponentKnownBits.isNonNegative();
1172
1173 // powi(-0.0, odd-positive) = -0.0
1174 // powi(-inf, odd-negative) = -0.0
1175 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddPositive) &&
1176 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddNegative))
1177 Known.knownNot(fcNegZero);
1178
1179 // powi(-0.0, odd-negative) = -inf
1180 // powi(-inf, odd-positive) = -inf
1181 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddNegative) &&
1182 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddPositive))
1183 Known.knownNot(fcNegInf);
1184 }
1185
1186 // powi(x, exp) --> inf
1187 // when:
1188 // * powi(inf, exp), exp > 0
1189 // * powi(+/-0, exp), exp < 0
1190 // * powi(finite, exp), |exp| > 1
1191 // * powi(subnormal, -1)
1192 // TODO:
1193 // 1. This simple all or nothing approach. We can do better
1194 // and cover sign/parity and exp > 1 vs exp < -1 separately.
1195 // 2. powi(0/nan, exp), exp > 0 can be refinable
1196 // to fcNan | fcZero | fcPosNormal.
1197 {
1198 APInt MinExp = ExponentKnownBits.getSignedMinValue();
1199 APInt MaxExp = ExponentKnownBits.getSignedMaxValue();
1200
1201 // powi(inf, exp), exp > 0
1202 bool MayInfSrc =
1203 !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();
1204
1205 // powi(+/-0, exp), exp < 0
1206 bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();
1207
1208 // powi(finite, exp), |exp| > 1
1209 bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
1210 bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
1211 bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;
1212
1213 // powi(subnormal, -1)
1214 bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
1215 bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;
1216
1217 if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
1218 Known.knownNot(fcInf);
1219 }
1220
1221 return Known;
1222}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition Lint.cpp:540
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 unsigned int semanticsPrecision(const fltSemantics &)
Definition APFloat.cpp:329
static LLVM_ABI Semantics SemanticsToEnum(const llvm::fltSemantics &Sem)
Definition APFloat.cpp:185
static LLVM_ABI bool isRepresentableAsNormalIn(const fltSemantics &Src, const fltSemantics &Dst)
Definition APFloat.cpp:379
static LLVM_ABI bool isIEEELikeFP(const fltSemantics &)
Definition APFloat.cpp:370
cmpResult compareAbsoluteValue(const APFloat &RHS) const
Definition APFloat.h:1538
const fltSemantics & getSemantics() const
Definition APFloat.h:1591
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
Definition APFloat.h:1192
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Definition APFloat.h:1202
Class for arbitrary precision integers.
Definition APInt.h:78
void clearBit(unsigned BitPosition)
Set a given bit to 0.
Definition APInt.h:1426
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition APInt.h:1205
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition APInt.h:254
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:376
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:325
bool isNonPositive() const
Determine if this APInt Value is non-positive (<= 0).
Definition APInt.h:357
bool isStrictlyPositive() const
Determine if this APInt Value is positive.
Definition APInt.h:352
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
Definition APInt.h:330
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
Definition APInt.h:302
bool slt(const APInt &RHS) const
Signed less than comparison.
Definition APInt.h:1134
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
Definition APInt.h:1241
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
@ Known
Known to have no common set bits.
LLVM_ABI FPClassTest orderedStrictlyGreater(FPClassTest Mask, bool OrderedZeroSign=false)
Returns all FPClasses which are greater than all values in Mask That is, return all classes for which...
int ilogb(const APFloat &Arg)
Returns the exponent of the internal representation of the APFloat.
Definition APFloat.h:1692
LLVM_ABI FPClassTest orderedStrictlyLess(FPClassTest Mask, bool OrderedZeroSign=false)
Returns all FPClasses which are less than all values in Mask That is, return all classes for which th...
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
@ Mul
Product of integers.
constexpr unsigned BitWidth
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()
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
Definition KnownBits.h:315
bool isNonNegative() const
Returns true if this value is known to be non-negative.
Definition KnownBits.h:106
bool isZero() const
Returns true if value is all zero.
Definition KnownBits.h:78
APInt getSignedMaxValue() const
Return the maximal signed value possible given these KnownBits.
Definition KnownBits.h:152
bool isEven() const
Return if the value is known even (the low bit is 0).
Definition KnownBits.h:162
bool isNegative() const
Returns true if this value is known to be negative.
Definition KnownBits.h:103
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
Definition KnownBits.h:136
bool isKnownNeverInfOrNaN() const
Return true if it's known this can never be an infinity or nan.
void setKnownFPClasses(FPClassTest Classes)
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 frem(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem.
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
FPClassTest KnownFPClassesValue
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.
static LLVM_ABI KnownFPClass atan2(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for atan2.
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.
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 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 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.
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.
std::optional< bool > getSignBit() const
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 fpext(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy)
Propagate known class for fpext.
FPClassTest getKnownFPClasses() const
Floating-point classes the value could be one of.
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.
LLVM_ABI KnownBits toKnownBits(const fltSemantics &FltSemantics) const
Report known bits for a float with provided semantics.
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 -...
LLVM_ABI void propagateCanonicalizingSrc(const KnownFPClass &Src, DenormalMode Mode)
Report known classes if Src is evaluated through a potentially canonicalizing operation.
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 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.
static LLVM_ABI KnownFPClass frem_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem x, x.
static LLVM_ABI KnownFPClass powi(const KnownFPClass &Src, const KnownBits &N)
Propagate known class for powi.
void propagateNonNaN(const KnownFPClass &Src)
static LLVM_ABI KnownFPClass pow(const KnownFPClass &LHS, const KnownFPClass &RHS)
Propagate known class for pow.
static LLVM_ABI KnownFPClass ldexp(const KnownFPClass &Src, const APInt &ConstantRangeMin, const APInt &ConstantRangeMax, const fltSemantics &Flt, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ldexp, assuming the exponent is known to be within [ConstantRangeMin,...
void setSignBit(std::optional< bool > Sign)
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.
unsigned int sizeInBits
Definition APFloat.h:1037
unsigned int precision
Definition APFloat.h:1034