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 : KnownFPClass(C.classify(), C.isNegative()) {}
23
25 DenormalMode Mode) {
26 KnownFPClass Known = KnownSrc;
27 switch (Mode.Input) {
29 return Known;
31 if (KnownSrc.getKnownFPClasses() & fcPosSubnormal)
32 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
33 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
34 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
35 return Known;
37 if (KnownSrc.getKnownFPClasses() & fcSubnormal)
38 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
39 return Known;
40 default:
41 if (KnownSrc.getKnownFPClasses() & fcSubnormal)
42 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
43 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
44 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
45 return Known;
46 }
47
48 llvm_unreachable("covered switch over denormal mode");
49}
50
52 DenormalMode Mode) {
53 KnownFPClass Known = KnownSrc;
54 switch (Mode.Output) {
56 return Known;
58 if (KnownSrc.getKnownFPClasses() & fcPosSubnormal)
59 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
60 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
61 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
62 return Known;
64 if (KnownSrc.getKnownFPClasses() & fcSubnormal)
65 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
66 return Known;
67 default:
68 if (KnownSrc.getKnownFPClasses() & fcSubnormal)
69 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
70 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
71 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
72 return Known;
73 }
74
75 llvm_unreachable("covered switch over denormal mode");
76}
77
81
85
89
91 const KnownFPClass &KnownRHS_,
92 MinMaxKind Kind, DenormalMode Mode) {
93 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
94 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
95
97
98 Known.propagateNonNaN(KnownLHS, KnownRHS);
99
100 // The *num functions return the non-NaN operand if only one operand is NaN.
101 // FIXME: minnum/maxnum may return a NaN if either operand is a signaling NaN.
102 if ((KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN()) &&
103 (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
105 Known.knownNot(fcNan);
106
107 switch (Kind) {
108 case MinMaxKind::maxnum: {
109 if (KnownLHS.isKnownNeverNaN())
110 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses(),
111 /*OrderedZeroSign=*/false));
112 if (KnownRHS.isKnownNeverNaN())
113 Known.knownNot(orderedStrictlyLess(KnownRHS.getKnownFPClasses(),
114 /*OrderedZeroSign=*/false));
115 break;
116 }
117 case MinMaxKind::minnum: {
118 if (KnownLHS.isKnownNeverNaN())
120 /*OrderedZeroSign=*/false));
121 if (KnownRHS.isKnownNeverNaN())
123 /*OrderedZeroSign=*/false));
124 break;
125 }
127 if (KnownLHS.isKnownNeverNaN())
128 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses(),
129 /*OrderedZeroSign=*/true));
130 if (KnownRHS.isKnownNeverNaN())
131 Known.knownNot(orderedStrictlyLess(KnownRHS.getKnownFPClasses(),
132 /*OrderedZeroSign=*/true));
133 break;
134 }
136 if (KnownLHS.isKnownNeverNaN())
138 /*OrderedZeroSign=*/true));
139 if (KnownRHS.isKnownNeverNaN())
141 /*OrderedZeroSign=*/true));
142 break;
143 }
144 case MinMaxKind::maximum: {
145 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses(),
146 /*OrderedZeroSign=*/true) |
148 /*OrderedZeroSign=*/true));
149 break;
150 }
151 case MinMaxKind::minimum: {
153 /*OrderedZeroSign=*/true) |
155 /*OrderedZeroSign=*/true));
156 break;
157 }
158 }
159
160 // Remove impossible non-NaN classes.
161 FPClassTest PossibleClasses =
162 KnownLHS.getKnownFPClasses() | KnownRHS.getKnownFPClasses() | fcNan;
163 Known.knownNot(~PossibleClasses);
164
165 return applyOutputDenormalMode(Known, Mode);
166}
167
169 DenormalMode DenormMode) {
171
172 // Canonicalize may flush denormals to zero, so we have to consider the
173 // denormal mode to preserve known-not-0 knowledge.
174 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcZero | fcQNan);
175
176 // Stronger version of propagateNaN
177 // Canonicalize is guaranteed to quiet signaling nans.
178 if (KnownSrc.isKnownNeverNaN())
179 Known.knownNot(fcNan);
180 else
181 Known.knownNot(fcSNan);
182
183 // FIXME: Missing check of IEEE like types.
184
185 // If the parent function flushes denormals, the canonical output cannot be a
186 // denormal.
187 if (DenormMode == DenormalMode::getIEEE()) {
188 if (KnownSrc.isKnownNever(fcPosZero))
189 Known.knownNot(fcPosZero);
190 if (KnownSrc.isKnownNever(fcNegZero))
191 Known.knownNot(fcNegZero);
192 return Known;
193 }
194
195 if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
196 Known.knownNot(fcSubnormal);
197
198 if (DenormMode == DenormalMode::getPreserveSign()) {
199 if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
200 Known.knownNot(fcPosZero);
201 if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
202 Known.knownNot(fcNegZero);
203 return Known;
204 }
205
206 if (DenormMode.Input == DenormalMode::PositiveZero ||
207 (DenormMode.Output == DenormalMode::PositiveZero &&
208 DenormMode.Input == DenormalMode::IEEE)) {
209 // -0.0 is not a subnormal and should not be flushed.
210 if (KnownSrc.isKnownNever(fcNegZero))
211 Known.knownNot(fcNegZero);
212
213 if (KnownSrc.isKnownNever(fcPosZero | fcSubnormal))
214 Known.knownNot(fcPosZero);
215 }
216
217 return Known;
218}
219
221 const KnownBits &Bits) {
222 assert(FltSemantics.sizeInBits == Bits.getBitWidth() &&
223 "Bitcast operand has incorrect bit width");
225
226 // Conflicting known bits do not describe a concrete value. Return unknown.
227 if (Bits.hasConflict())
228 return Known;
229
230 // Return unknown for types we have not validated.
231 auto IsSupported = [](const fltSemantics &Semantics) {
232 switch (APFloat::SemanticsToEnum(Semantics)) {
239 return true;
240 default:
241 return false;
242 }
243 };
244 if (!IsSupported(FltSemantics))
245 return Known;
246
247 // Transfer information from the sign bit.
248 if (Bits.isNonNegative())
249 Known.signBitMustBeZero();
250 else if (Bits.isNegative())
251 Known.signBitMustBeOne();
252
253 switch (APFloatBase::SemanticsToEnum(FltSemantics)) {
259 const unsigned MantissaBits = FltSemantics.precision - 1;
260 const APInt ExponentMask = APInt::getBitsSet(
261 FltSemantics.sizeInBits, MantissaBits, FltSemantics.sizeInBits - 1);
262 const APInt MantissaMask =
263 APInt::getLowBitsSet(FltSemantics.sizeInBits, MantissaBits);
264
265 const bool ExponentKnownAllZeros =
266 (Bits.Zero & ExponentMask) == ExponentMask;
267 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
268 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
269 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
270
271 const bool MantissaKnownAllZeros =
272 (Bits.Zero & MantissaMask) == MantissaMask;
273 const bool MantissaKnownNotAllZeros = !(Bits.One & MantissaMask).isZero();
274
275 // Zero and subnormal require an exponent with all zero bits.
276 if (ExponentKnownNotAllZeros)
277 Known.knownNot(fcZero | fcSubnormal);
278
279 // Infinity and NaN require an exponent with all one bits.
280 if (ExponentKnownNotAllOnes)
281 Known.knownNot(fcInf | fcNan);
282
283 // Normal values have an exponent that is not all zeros or all ones.
284 if (ExponentKnownAllZeros || ExponentKnownAllOnes)
285 Known.knownNot(fcNormal);
286
287 // Zero and infinity require a mantissa with all zero bits.
288 if (MantissaKnownNotAllZeros)
289 Known.knownNot(fcZero | fcInf);
290
291 // Subnormal and NaN require a non-zero mantissa.
292 if (MantissaKnownAllZeros)
293 Known.knownNot(fcSubnormal | fcNan);
294
295 const bool QuietBitKnownSet = Bits.One[MantissaBits - 1];
296 const bool QuietBitKnownClear = Bits.Zero[MantissaBits - 1];
297
298 if (QuietBitKnownSet)
299 Known.knownNot(fcSNan);
300 else if (QuietBitKnownClear)
301 Known.knownNot(fcQNan);
302
303 break;
304 }
306 // Layout of the x87 floating point type:
307 // [0:62] fraction
308 // [63] explicit integer bit
309 // [64:78] exponent
310 // [79] sign bit
311 // APFloat treats the x87 pseudo encodings as documented in
312 // fltSemantics::hasExplicitIntegerBit.
313 constexpr unsigned BitWidth = 80;
314 constexpr unsigned FractionBits = 63;
315 constexpr unsigned IntegerBitIndex = FractionBits;
316 const APInt FractionMask = APInt::getLowBitsSet(BitWidth, FractionBits);
317 const APInt ExponentMask =
318 APInt::getBitsSet(BitWidth, FractionBits + 1, BitWidth - 1);
319
320 const bool ExponentKnownAllZeros =
321 (Bits.Zero & ExponentMask) == ExponentMask;
322 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
323 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
324 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
325 const bool FractionKnownAllZeros =
326 (Bits.Zero & FractionMask) == FractionMask;
327 const bool FractionKnownNotAllZeros = !(Bits.One & FractionMask).isZero();
328 const bool IntegerBitKnownSet = Bits.One[IntegerBitIndex];
329 const bool IntegerBitKnownClear = Bits.Zero[IntegerBitIndex];
330
331 // zero and subnormal require an exponent with all zero bits and a cleared
332 // integer bit.
333 if (ExponentKnownNotAllZeros || IntegerBitKnownSet)
334 Known.knownNot(fcZero | fcSubnormal);
335
336 // Zero requires a zero fraction.
337 if (FractionKnownNotAllZeros)
338 Known.knownNot(fcZero);
339
340 // Infinity requires an exponent with all one bits, a set integer bit, and
341 // a zero fraction.
342 if (ExponentKnownNotAllOnes || IntegerBitKnownClear ||
343 FractionKnownNotAllZeros)
344 Known.knownNot(fcInf);
345
346 // A normal x87 value has its integer bit set. A zero exponent with that
347 // bit set is the x87 pseudodenormal encoding, which APFloat treats as
348 // normal.
349 if (IntegerBitKnownClear || ExponentKnownAllOnes)
350 Known.knownNot(fcNormal);
351
352 // A subnormal has a nonzero fraction; NaNs are possible with a zero
353 // fraction through pseudoinfinity and unnormal encodings.
354 if (FractionKnownAllZeros)
355 Known.knownNot(fcSubnormal);
356
357 // We can rule out NaN if the value has all exponent bits set to zero, or
358 // if the value is a canonical normal or infinity.
359 if (ExponentKnownAllZeros ||
360 (IntegerBitKnownSet &&
361 (ExponentKnownNotAllOnes || FractionKnownAllZeros)))
362 Known.knownNot(fcNan);
363
364 const bool QuietBitKnownSet = Bits.One[FractionBits - 1];
365 const bool QuietBitKnownClear = Bits.Zero[FractionBits - 1];
366
367 if (QuietBitKnownSet)
368 Known.knownNot(fcSNan);
369 else if (QuietBitKnownClear)
370 Known.knownNot(fcQNan);
371
372 break;
373 }
374 default:
375 llvm_unreachable("unhandled supported type");
376 }
377
378 return Known;
379}
380
382 KnownBits Known(FltSemantics.sizeInBits);
383 const FPClassTest FPClasses = getKnownFPClasses();
384
385 // Return unknown if poison.
386 if (FPClasses == fcNone)
387 return Known;
388
389 // Return unknown for types we have not validated.
390 auto IsSupported = [](const fltSemantics &Semantics) {
391 switch (APFloat::SemanticsToEnum(Semantics)) {
398 return true;
399 default:
400 return false;
401 }
402 };
403 if (!IsSupported(FltSemantics))
404 return Known;
405
406 switch (APFloat::SemanticsToEnum(FltSemantics)) {
412 // For ieee types, we cannot deduce anything if the source could be normal.
413 if (FPClasses & fcNormal)
414 break;
415
416 Known.setAllConflict();
417
418 const unsigned BitWidth = FltSemantics.sizeInBits;
419 const unsigned MantissaBits = FltSemantics.precision - 1;
420 const unsigned ExponentBits = BitWidth - MantissaBits - 1;
421
422 APInt MantissaMask = APInt::getLowBitsSet(BitWidth, MantissaBits);
423 APInt ExponentMask =
424 APInt::getBitsSet(BitWidth, MantissaBits, MantissaBits + ExponentBits);
425
426 const unsigned QuietBitIndex = MantissaBits - 1;
427 APInt PayloadMask = MantissaMask;
428 PayloadMask.clearBit(QuietBitIndex);
429
430 if (FPClasses & fcNan) {
431 // Exponent bits cannot be zeros.
432 Known.Zero &= ~ExponentMask;
433 // No individual payload bit is known.
434 Known.Zero &= ~PayloadMask;
435 Known.One &= ~PayloadMask;
436
437 if (FPClasses & fcQNan)
438 Known.Zero.clearBit(QuietBitIndex);
439 if (FPClasses & fcSNan)
440 Known.One.clearBit(QuietBitIndex);
441 }
442 if (FPClasses & fcInf) {
443 // Exponent bits cannot be zeros.
444 Known.Zero &= ~ExponentMask;
445 // Mantissa bits cannot be ones.
446 Known.One &= ~MantissaMask;
447 }
448 if (FPClasses & fcSubnormal) {
449 // Exponent bits cannot be ones.
450 Known.One &= ~ExponentMask;
451 // Unknown mantissa.
452 Known.One &= ~MantissaMask;
453 Known.Zero &= ~MantissaMask;
454 }
455 if (FPClasses & fcZero) {
456 // Exponent bits cannot be ones.
457 Known.One &= ~ExponentMask;
458 // Mantissa cannot be ones.
459 Known.One &= ~MantissaMask;
460 }
461
462 break;
463 }
466 break;
467
468 Known.setAllConflict();
469
470 if (FPClasses & fcInf)
471 Known = Known.intersectWith(KnownBits::makeConstant(
472 APFloat::getInf(FltSemantics).bitcastToAPInt()));
473
474 if (FPClasses & fcZero)
475 Known = Known.intersectWith(
477
478 break;
479 }
480 default:
481 llvm_unreachable("unhandled supported semantics");
482 }
483
484 Known.Zero.clearSignBit();
485 Known.One.clearSignBit();
486 if (std::optional<bool> Sign = getSignBit()) {
487 if (*Sign)
488 Known.makeNegative();
489 else
490 Known.makeNonNegative();
491 }
492
493 return Known;
494}
495
496// Handle known sign bit and nan cases for fadd, fsub, and fma.
497static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
498 const KnownFPClass &KnownRHS, bool IsFMA) {
500
501 if (KnownLHS.cannotBeOrderedLessThanZero() &&
502 KnownRHS.cannotBeOrderedLessThanZero()) {
504
505 // This can't underflow if one of the operands is known normal.
506 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
508 Known.knownNot(fcZero | fcPosSubnormal);
509 }
510
511 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
514
515 // This can't underflow if one of the operands is known normal.
516 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
518 Known.knownNot(fcZero | fcNegSubnormal);
519 }
520
521 if (!IsFMA) {
522 Known.propagateNonSNaN(KnownLHS, KnownRHS);
523
524 // Adding positive and negative infinity produces NaN, but only if both
525 // opposite-sign infinity combinations are possible.
526 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
527 (KnownLHS.isKnownNever(fcPosInf) || KnownRHS.isKnownNever(fcNegInf)) &&
528 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosInf)))
529 Known.knownNot(fcNan);
530
531 // (fadd x, +0.0) is guaranteed to return +0.0, not -0.0.
532 if (KnownLHS.isKnownNever(fcNegZero) || KnownRHS.isKnownNever(fcNegZero))
533 Known.knownNot(fcNegZero);
534 }
535
536 return Known;
537}
538
540 const KnownFPClass &KnownRHS_,
541 DenormalMode Mode) {
542 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
543 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
544
545 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, /*IsFMA=*/false);
546
547 return applyOutputDenormalMode(Known, Mode);
548}
549
551 DenormalMode Mode) {
552 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
553
554 KnownFPClass Known = fadd_impl(KnownSrc, KnownSrc, /*IsFMA=*/false);
555
556 if (KnownSrc.isKnownNever(fcPosSubnormal))
557 Known.knownNot(fcPosSubnormal);
558 if (KnownSrc.isKnownNever(fcNegSubnormal))
559 Known.knownNot(fcNegSubnormal);
560
561 // Doubling 0 will give the same 0.
562 if (KnownSrc.isKnownNever(fcPosZero))
563 Known.knownNot(fcPosZero);
564
565 return applyOutputDenormalMode(Known, Mode);
566}
567
569 const KnownFPClass &KnownRHS_,
570 DenormalMode Mode) {
571 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
572 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
573
574 // fsub(x, y) == fadd(x, -y) as long as we negate after subnormals are
575 // flushed.
576 KnownRHS.fneg();
577
578 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, /*IsFMA=*/false);
579
580 return applyOutputDenormalMode(Known, Mode);
581}
582
584 const KnownFPClass &KnownRHS_,
585 DenormalMode Mode) {
586 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
587 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
588
590
591 // fmul will xor the sign-bit of non-NaN inputs:
592 // +X * +Y or -X * -Y => +Q
593 // +X * -Y or -X * +Y => -Q
594
595 Known.propagateNonSNaN(KnownLHS, KnownRHS);
596
597 // NaN is generated from 0.0 * inf and inf * 0.0.
598 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
599 (KnownRHS.isKnownNeverInfinity() || KnownLHS.isKnownNever(fcZero)) &&
600 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNever(fcZero)))
601 Known.knownNot(fcNan);
602
603 // Infinity may be produced from two non-zero inputs.
604 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
608 Known.knownNot(fcPosInf);
609 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
613 Known.knownNot(fcNegInf);
614
615 // Normal and subnormal results require two non-zero finite operands.
616 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
620 Known.knownNot(fcPosSubnormal | fcPosNormal);
621 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
625 Known.knownNot(fcNegSubnormal | fcNegNormal);
626
627 // Zero may be produced from two finite inputs.
628 if ((KnownLHS.isKnownNever(fcPosFinite) ||
629 KnownRHS.isKnownNever(fcPosFinite)) &&
630 (KnownLHS.isKnownNever(fcNegFinite) ||
631 KnownRHS.isKnownNever(fcNegFinite)))
632 Known.knownNot(fcPosZero);
633 if ((KnownLHS.isKnownNever(fcPosFinite) ||
634 KnownRHS.isKnownNever(fcNegFinite)) &&
635 (KnownLHS.isKnownNever(fcNegFinite) ||
636 KnownRHS.isKnownNever(fcPosFinite)))
637 Known.knownNot(fcNegZero);
638
639 return applyOutputDenormalMode(Known, Mode);
640}
641
642// TODO: This generalizes to known ranges
644 const APFloat &CRHS, DenormalMode Mode) {
645 // Match denormal scaling pattern, similar to the case in ldexp. If the
646 // constant's exponent is sufficiently large, the result cannot be subnormal.
647
648 const fltSemantics &Flt = CRHS.getSemantics();
649 unsigned Precision = APFloat::semanticsPrecision(Flt);
650 const int MantissaBits = Precision - 1;
651
652 int MinKnownExponent = ilogb(CRHS);
653 bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);
654
655 KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
656 if (CannotBeSubnormal)
657 Known.knownNot(fcSubnormal);
658
659 // Multiply of values <= 1 cannot introduce overflow.
660 if (KnownLHS.isKnownNever(fcInf)) {
661 if (MinKnownExponent < 0)
662 Known.knownNot(fcInf);
663 else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
664 Flt)) == APFloat::cmpEqual)
665 Known.knownNot(fcInf);
666 }
667
668 return Known;
669}
670
672 const KnownFPClass &KnownRHS_,
673 DenormalMode Mode) {
674 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
675 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
676
678
679 // fdiv will xor the sign-bit of non-NaN inputs:
680 // +X / +Y or -X / -Y => +Q
681 // +X / -Y or -X / +Y => -Q
682
683 Known.propagateNonSNaN(KnownLHS, KnownRHS);
684
685 // NaN is generated from 0.0 / 0.0 and inf / inf.
686 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
687 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
688 (KnownLHS.isKnownNever(fcZero) || KnownRHS.isKnownNever(fcZero)))
689 Known.knownNot(fcNan);
690
691 // Infinity may be produced from non-zero / finite.
692 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
693 KnownRHS.isKnownNever(fcPosFinite)) &&
695 KnownRHS.isKnownNever(fcNegFinite)))
696 Known.knownNot(fcPosInf);
697 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
698 KnownRHS.isKnownNever(fcNegFinite)) &&
700 KnownRHS.isKnownNever(fcPosFinite)))
701 Known.knownNot(fcNegInf);
702
703 // Normal and subnormal results require two non-zero finite operands.
704 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
708 Known.knownNot(fcPosSubnormal | fcPosNormal);
709 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
713 Known.knownNot(fcNegSubnormal | fcNegNormal);
714
715 // Zero may be produced from finite / non-zero.
716 if ((KnownLHS.isKnownNever(fcPosFinite) ||
718 (KnownLHS.isKnownNever(fcNegFinite) ||
720 Known.knownNot(fcPosZero);
721 if ((KnownLHS.isKnownNever(fcPosFinite) ||
723 (KnownLHS.isKnownNever(fcNegFinite) ||
725 Known.knownNot(fcNegZero);
726
727 return applyOutputDenormalMode(Known, Mode);
728}
729
731 DenormalMode Mode) {
732 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
733
734 // X / X is always exactly 1.0 or a NaN.
736
737 Known.propagateNonSNaN(KnownSrc);
738
739 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNever(fcZero))
740 Known.knownNot(fcNan);
741
742 // The result is never subnormal, so the output denormal mode does not matter.
743 return Known;
744}
745
747 const KnownFPClass &KnownRHS_,
748 DenormalMode Mode) {
749 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
750 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
752
753 // We are assuming that frem(x, Inf) is already handled elsewhere.
754
755 Known.knownNot(fcInf);
756
757 Known.propagateNonSNaN(KnownLHS, KnownRHS);
758
759 // frem(Inf, x) and frem(x, 0) produce NaN.
760 if (KnownLHS.isKnownNeverInfOrNaN() && KnownRHS.isKnownNeverNaN() &&
761 KnownRHS.isKnownNever(fcZero)) {
762 Known.knownNot(fcNan);
763 }
764
765 // The sign for frem is the same as the first operand.
767 Known.knownNot(fcPosNormal | fcPosSubnormal);
769 Known.knownNot(fcNegNormal | fcNegSubnormal);
770
771 // A negative zero result requires a negative finite first operand.
772 if (KnownLHS.isKnownNever(fcNegFinite))
773 Known.knownNot(fcNegZero);
774
775 // A positive zero result requires a positive finite first operand.
776 if (KnownLHS.isKnownNever(fcPosFinite))
777 Known.knownNot(fcPosZero);
778
779 return applyOutputDenormalMode(Known, Mode);
780}
781
783 DenormalMode Mode) {
784 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
785
786 // X % X is always exactly [+-]0.0 or a NaN.
788
789 Known.propagateNonSNaN(KnownSrc);
790
791 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNever(fcZero))
792 Known.knownNot(fcNan);
793
794 // The sign of a zero result is the sign of the finite non-zero input.
796 Known.knownNot(fcPosZero);
798 Known.knownNot(fcNegZero);
799
800 // The result is never subnormal, so the output denormal mode does not matter.
801 return Known;
802}
803
805 const KnownFPClass &KnownRHS_,
806 const KnownFPClass &KnownAddend_,
807 DenormalMode Mode) {
808 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
809 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
810 KnownFPClass KnownAddend = applyInputDenormalMode(KnownAddend_, Mode);
811
812 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, DenormalMode::getIEEE());
813
814 // FMA differs from the base fmul + fadd handling only in the treatment of -0
815 // results.
816 //
817 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
818 // unlike for a separate fadd.
819 KnownFPClass Known = fadd_impl(Mul, KnownAddend, /*IsFMA=*/true);
820
821 // propagateNonSNaN for 3 arguments.
822 if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
823 KnownAddend.isKnownNever(fcSNan))
824 Known.knownNot(fcSNan);
825
826 // Rule out NaN.
827 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
828 KnownAddend.isKnownNeverNaN()) {
829 // NaN is produced when zero is multiplied by infinity, or when adding two
830 // exact infinities of the opposite sign. An exact infinity requires at
831 // least one infinite operand.
832
833 const bool NeverZeroMulInf =
834 (KnownLHS.isKnownNever(fcInf) || KnownRHS.isKnownNever(fcZero)) &&
835 (KnownRHS.isKnownNever(fcInf) || KnownLHS.isKnownNever(fcZero));
836 // Multiplying infinity by a non-zero finite may change the sign.
837 const bool NeverExactPosInf =
838 (KnownLHS.isKnownNever(fcPosInf) ||
840 (KnownRHS.isKnownNever(fcPosInf) ||
842 (KnownLHS.isKnownNever(fcNegInf) ||
844 (KnownRHS.isKnownNever(fcNegInf) ||
846 const bool NeverExactNegInf =
847 (KnownLHS.isKnownNever(fcPosInf) ||
849 (KnownRHS.isKnownNever(fcPosInf) ||
851 (KnownLHS.isKnownNever(fcNegInf) ||
853 (KnownRHS.isKnownNever(fcNegInf) ||
855 if (NeverZeroMulInf &&
856 (KnownAddend.isKnownNever(fcPosInf) || NeverExactNegInf) &&
857 (KnownAddend.isKnownNever(fcNegInf) || NeverExactPosInf))
858 Known.knownNot(fcNan);
859 }
860
861 return applyOutputDenormalMode(Known, Mode);
862}
863
865 const KnownFPClass &KnownRHS,
866 const KnownFPClass &KnownAddend,
867 DenormalMode Mode) {
868 // fmuladd can lower to either fma(x, y, z) or fadd(fmul(x, y), z). Compute
869 // the intersection of both possibilities.
870 KnownFPClass FMA = fma(KnownLHS, KnownRHS, KnownAddend, Mode);
871 KnownFPClass MulAdd = fadd(fmul(KnownLHS, KnownRHS, Mode), KnownAddend, Mode);
872 return FMA.intersectWith(MulAdd);
873}
874
876 const KnownFPClass &KnownAddend_,
877 DenormalMode Mode) {
878 KnownFPClass KnownSquared = applyInputDenormalMode(KnownSquared_, Mode);
879 KnownFPClass KnownAddend = applyInputDenormalMode(KnownAddend_, Mode);
880
881 KnownFPClass Squared = square(KnownSquared, DenormalMode::getIEEE());
882 KnownFPClass Known = fadd_impl(Squared, KnownAddend, /*IsFMA=*/true);
883
884 Known.propagateNonSNaN(KnownSquared, KnownAddend);
885
886 // Only fma(+inf, +inf, -inf) and fma(-inf, -inf, -inf) produce NaN when
887 // squaring.
888 if (KnownSquared.isKnownNeverNaN() && KnownAddend.isKnownNeverNaN() &&
889 (KnownSquared.isKnownNever(fcInf) || KnownAddend.isKnownNever(fcNegInf)))
890 Known.knownNot(fcNan);
891
892 return applyOutputDenormalMode(Known, Mode);
893}
894
896 const KnownFPClass &KnownAddend,
897 DenormalMode Mode) {
898 KnownFPClass FMA = fma_square(KnownSquared, KnownAddend, Mode);
899 KnownFPClass MulAdd = fadd(square(KnownSquared, Mode), KnownAddend, Mode);
900 return FMA.intersectWith(MulAdd);
901}
902
905 Known.knownNot(fcNegative);
906
907 Known.propagateNonNaN(KnownSrc);
908
909 // The following deductions assume that exp10(-1.0) = +0.1 and
910 // exp10(+1.0) = +10.0 are both finite normal values.
911
912 // Zero can only be produced if x < -1.0.
913 if (KnownSrc.isKnownNever(fcNegNormal | fcNegInf))
914 Known.knownNot(fcPosZero);
915
916 // Subnormals can only be produced if x < -1.0 and x is finite.
917 if (KnownSrc.isKnownNever(fcNegNormal))
918 Known.knownNot(fcPosSubnormal);
919
920 // Infinity can only be produced if x > +1.0.
921 if (KnownSrc.isKnownNever(fcPosNormal | fcPosInf))
922 Known.knownNot(fcPosInf);
923
924 return Known;
925}
926
928 bool IsMultiUnitFPType) {
929 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
931
932 // PPCDoubleDouble can represent the exact value of 1.0 + subnormal, and
933 // log(1.0 + subnormal) = subnormal.
934 if (!IsMultiUnitFPType)
935 Known.knownNot(fcNegZero | fcSubnormal);
936
937 Known.propagateNonSNaN(KnownSrc);
938
939 if (KnownSrc.isKnownNeverPosInfinity())
940 Known.knownNot(fcPosInf);
941
942 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
943 Known.knownNot(fcNan);
944
945 if (KnownSrc.isKnownNever(fcZero))
946 Known.knownNot(fcNegInf);
947
948 // This only matters for PPCDoubleDouble.
949 return applyOutputDenormalMode(Known, Mode);
950}
951
953 DenormalMode Mode) {
955 Known.knownNot(fcPosSubnormal);
956
957 if (KnownSrc.isKnownNeverPosInfinity())
958 Known.knownNot(fcPosInf);
959
960 Known.propagateNonSNaN(KnownSrc);
961
962 // Any negative value besides -0 returns a nan.
963 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
964 Known.knownNot(fcNan);
965
966 // The only negative value that can be returned is -0 for -0 inputs.
968
969 // If the input denormal mode could be PreserveSign, a negative
970 // subnormal input could produce a negative zero output.
971 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
972 Known.knownNot(fcNegZero);
973
974 return Known;
975}
976
979
980 Known.propagateNonSNaN(KnownSrc);
981
982 // Return NaN on infinite inputs.
983 Known.knownNot(fcInf);
984 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
985 Known.knownNot(fcNan);
986
987 return Known;
988}
989
991 return sin(KnownSrc);
992}
993
996
997 // tan never returns Inf (tan(+-Inf) = NaN; tan(finite) = finite).
998 Known.knownNot(fcInf);
999
1000 Known.propagateNonSNaN(KnownSrc);
1001
1002 // NaN propagates. tan(+-Inf) is NaN.
1003 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
1004 Known.knownNot(fcNan);
1005
1006 return Known;
1007}
1008
1011
1012 // sinh is sign-preserving: sinh(x) < 0 iff x < 0.
1013 if (KnownSrc.isKnownNever(fcNegative))
1014 Known.knownNot(fcNegative);
1015
1016 // A nonzero positive result requires a nonzero positive input.
1017 // Zero remains possible: sinh(+/-0.0) = +/-0.0, and flushing a subnormal
1018 // may produce +0.0.
1021
1022 Known.propagateNonNaN(KnownSrc);
1023
1024 return Known;
1025}
1026
1029
1030 // cosh(x) >= 1 for all real x; cosh(+-Inf) = +Inf. Never negative,
1031 // zero, or subnormal.
1032 Known.knownNot(fcNegative | fcZero | fcSubnormal);
1033
1034 Known.propagateNonNaN(KnownSrc);
1035
1036 return Known;
1037}
1038
1041
1042 // tanh is bounded to (-1, 1), never Inf.
1043 Known.knownNot(fcInf);
1044
1045 // tanh is sign-preserving: tanh(x) < 0 iff x < 0.
1046 if (KnownSrc.isKnownNever(fcNegSubnormal | fcNegNormal | fcNegInf)) {
1047 Known.knownNot(fcNegSubnormal | fcNegNormal);
1048
1049 // -0.0 is preserved: tanh(-0.0) = -0.0.
1050 if (KnownSrc.isKnownNever(fcNegZero))
1051 Known.knownNot(fcNegZero);
1052 }
1053
1054 // Likewise, tanh(x) > 0 iff x > 0. Zero is not ruled out: tanh(+-0.0) =
1055 // +-0.0, and a flushed subnormal may become +0.0.
1057 Known.knownNot(fcPosSubnormal | fcPosNormal);
1058
1059 Known.propagateNonNaN(KnownSrc);
1060
1061 return Known;
1062}
1063
1066
1067 // asin is bounded to [-pi/2, pi/2], never Inf.
1068 Known.knownNot(fcInf);
1069
1070 Known.propagateNonSNaN(KnownSrc);
1071
1072 // asin is sign-preserving for finite arguments.
1073 if (KnownSrc.isKnownNever(fcNegFinite))
1074 Known.knownNot(fcNegFinite);
1075
1076 if (KnownSrc.isKnownNever(fcPosSubnormal | fcPosNormal))
1077 Known.knownNot(fcPosSubnormal | fcPosNormal);
1078
1079 // NaN propagates. asin(x) is also NaN for |x| > 1, so we cannot rule
1080 // out NaN without knowing the source is in [-1, 1].
1081 return Known;
1082}
1083
1086
1087 // acos(x) is bounded to [0, pi] for -1 <= x <= 1, and is never negative,
1088 // infinite, or subnormal. The smallest non-zero value occurs when x is
1089 // close to 1.0, where acos(x) can be approximated by sqrt(2 * (1 - x)).
1090 // Since sqrt cannot produce a subnormal result, we can conclude that
1091 // acos(x) will also never produce a subnormal result.
1092 Known.knownNot(fcNegative | fcInf | fcSubnormal);
1093
1094 // acos(x) == +0.0 iff x == +1.0
1095 if (KnownSrc.isKnownNever(fcPosNormal))
1096 Known.knownNot(fcZero);
1097
1098 Known.propagateNonSNaN(KnownSrc);
1099
1100 // NaN propagates. acos(x) is also NaN for |x| > 1, so we cannot rule
1101 // out NaN without knowing the source is in [-1, 1].
1102 return Known;
1103}
1104
1107
1108 // atan is bounded to (-pi/2, pi/2), never Inf. atan(+-Inf) = +-pi/2 (finite).
1109 Known.knownNot(fcInf);
1110
1111 // Ruling out Subnormal/Normal from the result requires the
1112 // input to never be finite-nonzero and never inf, since
1113 // atan(+-inf) = +-pi/2
1115 Known.knownNot(fcNegSubnormal | fcNegNormal);
1116
1118 Known.knownNot(fcPosSubnormal | fcPosNormal);
1119
1120 // atan(-0.0) = -0.0. Negative finite inputs may also produce -0.0
1121 // if the result rounds to a negative subnormal that is flushed to zero.
1123 Known.knownNot(fcNegZero);
1124
1125 Known.propagateNonNaN(KnownSrc);
1126
1127 return Known;
1128}
1129
1131 const KnownFPClass &KnownX_,
1132 DenormalMode Mode) {
1133 KnownFPClass KnownY = applyInputDenormalMode(KnownY_, Mode);
1134 KnownFPClass KnownX = applyInputDenormalMode(KnownX_, Mode);
1136
1137 // Even though these deductions are correct, we are ignoring the following
1138 // potentially erroneous cases:
1139 // * atan2(y, inf) is not subnormal
1140 // * atan2(inf, x) is not zero or subnormal
1141
1142 // atan2 result is in (-pi, pi], never Inf.
1143 Known.knownNot(fcInf);
1144
1145 Known.propagateNonNaN(KnownY, KnownX);
1146
1147 // If x <= -0.0, then |atan2(y, x)| >= pi/2
1148 if (KnownX.isKnownNever(fcPositive))
1149 Known.knownNot(fcZero | fcSubnormal);
1150
1151 // If y >= +0.0, then atan2(y, x) >= +0.0
1152 if (KnownY.isKnownNever(fcNegative))
1153 Known.knownNot(fcNegative);
1154
1155 // If y <= -0.0, then atan2(y, x) <= -0.0
1156 if (KnownY.isKnownNever(fcPositive))
1157 Known.knownNot(fcPositive);
1158
1159 return applyOutputDenormalMode(Known, Mode);
1160}
1161
1162static KnownFPClass fpconvert(const KnownFPClass &KnownSrc_,
1163 const fltSemantics &DstSem,
1164 const fltSemantics &SrcSem, DenormalMode Mode) {
1168 auto IsSupported = [](APFloatBase::Semantics SemType) -> bool {
1169 switch (SemType) {
1176 return true;
1177 default:
1178 return false;
1179 }
1180 };
1181
1182 // Return unknown for types we have not validated.
1183 // TODO: Add support for lossless casts to PPCDoubleDouble.
1184 if (!IsSupported(SrcType) || !IsSupported(DstType))
1185 return Known;
1186
1188
1189 // TODO: Until we pass the rounding mode into fpconvert, the rounding mode is
1190 // assumed to be dynamic. This includes potential future rounding modes such
1191 // as roundAwayZero (not the same as roundNearestTiesAway) and roundToOdd
1192 // (jamming).
1193
1194 Known.propagateNonNaN(KnownSrc);
1195
1196 const bool NormalSrcIsFiniteDst = DstSem.maxExponent > SrcSem.maxExponent ||
1197 (DstSem.maxExponent == SrcSem.maxExponent &&
1198 DstSem.precision >= SrcSem.precision);
1199
1200 // True if the dst can represent all non-zero finite values of src.
1201 const bool NonZeroFiniteSrcIsNonZeroInDst =
1202 DstSem.minExponent <= SrcSem.minExponent &&
1203 DstSem.precision >= SrcSem.precision;
1204
1205 // For example: f32 = bf16, f128 = f80
1206 const bool NormalIsNormalAndSubnormalIsSubnormal =
1207 DstSem.minExponent == SrcSem.minExponent &&
1208 DstSem.maxExponent >= SrcSem.maxExponent &&
1209 DstSem.precision >= SrcSem.precision;
1210
1211 // Rule out infinity.
1212 // We are assuming that subnormal values have a magnitude less than 1.0.
1213 if (KnownSrc.isKnownNever(fcPosInf) &&
1214 (KnownSrc.isKnownNever(fcPosNormal) || NormalSrcIsFiniteDst))
1215 Known.knownNot(fcPosInf);
1216 if (KnownSrc.isKnownNever(fcNegInf) &&
1217 (KnownSrc.isKnownNever(fcNegNormal) || NormalSrcIsFiniteDst))
1218 Known.knownNot(fcNegInf);
1219
1220 // Rule out non-zero finite.
1221 if (NormalIsNormalAndSubnormalIsSubnormal) {
1222 // Normal never becomes subnormal, and vice-versa.
1223 if (KnownSrc.isKnownNever(fcPosNormal))
1224 Known.knownNot(fcPosNormal);
1225 if (KnownSrc.isKnownNever(fcNegNormal))
1226 Known.knownNot(fcNegNormal);
1227 if (KnownSrc.isKnownNever(fcPosSubnormal))
1228 Known.knownNot(fcPosSubnormal);
1229 if (KnownSrc.isKnownNever(fcNegSubnormal))
1230 Known.knownNot(fcNegSubnormal);
1231 } else {
1232 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1233 Known.knownNot(fcPosNormal | fcPosSubnormal);
1234 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1235 Known.knownNot(fcNegNormal | fcNegSubnormal);
1236 }
1237
1238 // Rule out subnormal.
1239 if (APFloat::isRepresentableAsNormalIn(SrcSem, DstSem))
1240 Known.knownNot(fcSubnormal);
1241
1242 // Rule out positive zero.
1243 if (KnownSrc.isKnownNever(fcPosZero) &&
1245 NonZeroFiniteSrcIsNonZeroInDst))
1246 Known.knownNot(fcPosZero);
1247
1248 // Rule out negative zero.
1249 if (KnownSrc.isKnownNever(fcNegZero) &&
1251 NonZeroFiniteSrcIsNonZeroInDst))
1252 Known.knownNot(fcNegZero);
1253
1255}
1256
1257// Determine what the input and output denormal modes are for fpconvert from
1258// the denormal modes for the dst and src types.
1259//
1260// TODO: We are currently conservative, and assume DenormalMode::getDynamic() if
1261// the dst or src denormal mode is not IEEE.
1263 DenormalMode SrcMode) {
1264 if (DstMode == DenormalMode::getIEEE() && SrcMode == DenormalMode::getIEEE())
1265 return DenormalMode::getIEEE();
1266 return DenormalMode::getDynamic();
1267}
1268
1270 const fltSemantics &DstTy,
1271 const fltSemantics &SrcTy,
1272 DenormalMode DstMode, DenormalMode SrcMode) {
1273 // Note that fpext may round for some bizarre type combinations.
1274 // Such as ieee_binary256 = fpext(PPCDoubleDouble) if we add support for
1275 // ieee_binary256 in the future. PPCDoubleDouble can represent values such as
1276 // DBL_MAX + DBL_TRUE_MIN which would normally require 2098 bits of precision
1277 // to represent.
1278 return fpconvert(KnownSrc, DstTy, SrcTy,
1279 getConvertDenormalMode(DstMode, SrcMode));
1280}
1281
1283 const fltSemantics &DstTy,
1284 const fltSemantics &SrcTy,
1285 DenormalMode DstMode, DenormalMode SrcMode) {
1286 // TODO: pass rounding mode from fptrunc_round
1287 return fpconvert(KnownSrc, DstTy, SrcTy,
1288 getConvertDenormalMode(DstMode, SrcMode));
1289}
1290
1292 bool MayBeMultiUnitFPType,
1293 DenormalMode Mode) {
1295
1296 // Integer results cannot be subnormal.
1297 Known.knownNot(fcSubnormal);
1298
1299 Known.propagateNonNaN(KnownSrc);
1300
1301 // Pass through infinities, except PPC_FP128 is a special case for intrinsics.
1302 if (!MayBeMultiUnitFPType) {
1303 if (KnownSrc.isKnownNeverPosInfinity())
1304 Known.knownNot(fcPosInf);
1305 if (KnownSrc.isKnownNeverNegInfinity())
1306 Known.knownNot(fcNegInf);
1307 }
1308
1309 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1310 Known.knownNot(fcPosNormal);
1311
1312 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1313 Known.knownNot(fcNegNormal);
1314
1315 // Negative round ups towards zero produce negative zero.
1316 if (KnownSrc.isKnownNever(fcNegFinite))
1317 Known.knownNot(fcNegZero);
1318
1319 // Negative subnormals may flush to positive zero.
1320 if (KnownSrc.isKnownNever(fcPosFinite) &&
1321 (KnownSrc.isKnownNever(fcNegSubnormal) ||
1322 !Mode.inputsMayBePositiveZero()))
1323 Known.knownNot(fcPosZero);
1324
1325 return Known;
1326}
1327
1329 DenormalMode Mode) {
1331 /*MayBeMultiUnitFPType=*/true, Mode);
1332
1333 if (KnownSrc.isKnownNeverPosInfinity())
1334 Known.knownNot(fcPosInf);
1335 if (KnownSrc.isKnownNeverNegInfinity())
1336 Known.knownNot(fcNegInf);
1337
1338 return Known;
1339}
1340
1342 bool IsMultiUnitFPType, DenormalMode Mode) {
1343 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1344
1345 // Applicable for multi-unit floating point types.
1346 if (KnownSrc.isKnownNeverPosInfinity())
1347 Known.knownNot(fcPosInf);
1348
1349 return Known;
1350}
1351
1353 bool IsMultiUnitFPType, DenormalMode Mode) {
1354 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1355
1356 // Applicable for multi-unit floating point types.
1357 if (KnownSrc.isKnownNeverNegInfinity())
1358 Known.knownNot(fcNegInf);
1359
1360 return Known;
1361}
1362
1364 DenormalMode Mode) {
1365 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
1367
1368 Known.knownNot(fcSubnormal);
1369
1370 Known.propagateNonNaN(KnownSrc);
1371
1372 if (KnownSrc.isKnownNeverPosInfinity())
1373 Known.knownNot(fcPosInf);
1374 if (KnownSrc.isKnownNeverNegInfinity())
1375 Known.knownNot(fcNegInf);
1376
1377 if (KnownSrc.isKnownNever(fcPosZero))
1378 Known.knownNot(fcPosZero);
1379 if (KnownSrc.isKnownNever(fcNegZero))
1380 Known.knownNot(fcNegZero);
1381
1382 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1383 Known.knownNot(fcPosNormal);
1384 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1385 Known.knownNot(fcNegNormal);
1386
1387 return Known;
1388}
1389
1391 const APInt &ConstantRangeExpMin,
1392 const APInt &ConstantRangeExpMax,
1393 const fltSemantics &Flt, DenormalMode Mode) {
1395
1396 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
1397
1398 if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
1399 // ldexp(x, 0) -> x
1400 // Here we make sure to properly propagate sNaN and denormals.
1401 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcNan);
1402 Known.propagateNonNaN(KnownSrc);
1403 return applyOutputDenormalMode(Known, Mode);
1404 }
1405
1406 Known.propagateNonNaN(KnownSrc);
1407
1408 // Sign is preserved, but underflows may produce zeroes.
1409 if (KnownSrc.isKnownNever(fcNegative))
1410 Known.knownNot(fcNegative);
1411 else if (KnownSrc.cannotBeOrderedLessThanZero())
1413
1414 if (KnownSrc.isKnownNever(fcPositive))
1415 Known.knownNot(fcPositive);
1416 else if (KnownSrc.cannotBeOrderedGreaterThanZero())
1418
1419 // TODO: determine when it is safe to rule out subnormal for ppcf128.
1420 if (&Flt != &APFloat::PPCDoubleDouble()) {
1421 unsigned Precision = APFloat::semanticsPrecision(Flt);
1422 const int MantissaBits = Precision - 1;
1423 if (ConstantRangeExpMin.sge(MantissaBits))
1424 Known.knownNot(fcSubnormal);
1425 }
1426
1427 if (ConstantRangeExpMax.isNonPositive()) {
1428 // If we know the power is <= 0, can't introduce inf
1429 if (KnownSrc.isKnownNeverPosInfinity())
1430 Known.knownNot(fcPosInf);
1431 if (KnownSrc.isKnownNeverNegInfinity())
1432 Known.knownNot(fcNegInf);
1433 } else if (ConstantRangeExpMin.isNonNegative()) {
1434 // If we know the power is >= 0, can't introduce subnormal or zero
1435 if (KnownSrc.isKnownNeverPosSubnormal())
1436 Known.knownNot(fcPosSubnormal);
1437 if (KnownSrc.isKnownNeverNegSubnormal())
1438 Known.knownNot(fcNegSubnormal);
1439 if (KnownSrc.isKnownNever(fcPosZero))
1440 Known.knownNot(fcPosZero);
1441 if (KnownSrc.isKnownNever(fcNegZero))
1442 Known.knownNot(fcNegZero);
1443 }
1444
1445 return applyOutputDenormalMode(Known, Mode);
1446}
1447
1449 const KnownBits &ExpBits,
1450 const fltSemantics &Flt, DenormalMode Mode) {
1451 return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
1452 ExpBits.getSignedMaxValue(), Flt, Mode);
1453}
1454
1456 const KnownFPClass &KnownRHS) {
1458
1459 Known.propagateNonSNaN(KnownLHS, KnownRHS);
1460
1461 // pow may return NaN if one of the arguments is NaN. NaN may be produced from
1462 // a non-zero-finite-negative base and a non-integer exponent.
1463 if (KnownLHS.isKnownNever(fcNan | fcNegNormal | fcNegSubnormal) &&
1464 KnownRHS.isKnownNeverNaN())
1465 Known.knownNot(fcNan);
1466
1467 // We could rule out negative and subnormal results when exponent is known to
1468 // never be a normal value, but having either argument being known to never be
1469 // normal is unlikely and not worth considering.
1470
1471 // Only a negative base raised to an odd power returns a negative value.
1472 if (KnownLHS.isKnownNever(fcNegative)) {
1473 Known.knownNot(fcNegative);
1474 } else if (KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1475 Known.knownNot(fcNegNormal | fcNegSubnormal);
1476 // See if we can also rule out -0.0 or -inf.
1477 // Here at least one of -0.0 or -inf is a possible base.
1478
1479 // pow(-0.0, odd-positive) = -0.0
1480 // pow(-inf, odd-negative) = -0.0
1481 if ((KnownLHS.isKnownNever(fcNegZero) ||
1482 KnownRHS.isKnownNever(fcPosNormal)) &&
1483 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcNegNormal)))
1484 Known.knownNot(fcNegZero);
1485
1486 // pow(-0.0, odd-negative) = -inf
1487 // pow(-inf, odd-positive) = -inf
1488 if ((KnownLHS.isKnownNever(fcNegZero) ||
1489 KnownRHS.isKnownNever(fcNegNormal)) &&
1490 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosNormal)))
1491 Known.knownNot(fcNegInf);
1492 }
1493
1494 return Known;
1495}
1496
1498 const KnownBits &ExponentKnownBits) {
1500 Known.propagateNonNaN(KnownSrc);
1501
1502 if (ExponentKnownBits.isZero()) {
1503 // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
1504 // return 1.0 or a NaN.
1505 if (KnownSrc.isKnownNever(fcSNan)) {
1506 Known.knownNot(~fcPosNormal);
1507 return Known;
1508 }
1509
1510 Known.knownNot(~(fcPosNormal | fcNan));
1511 return Known;
1512 }
1513
1514 // Given that exp is an integer, here are the
1515 // ways that powi can return a negative value:
1516 //
1517 // powi(x, exp) --> negative if exp is odd and x is negative.
1518 // powi(-0, exp) --> -inf if exp is negative odd.
1519 // powi(-0, exp) --> -0 if exp is positive odd.
1520 // powi(-inf, exp) --> -0 if exp is negative odd.
1521 // powi(-inf, exp) --> -inf if exp is positive odd.
1522 if (KnownSrc.isKnownNever(fcNegative) || ExponentKnownBits.isEven()) {
1523 Known.knownNot(fcNegative);
1524 } else if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1525 Known.knownNot(fcNegNormal | fcNegSubnormal);
1526 // See if we can also rule out -0.0 or -inf.
1527 // Here at least one of -0.0 or -inf is a possible base.
1528
1529 // We already know that ExponentKnownBits.isEven() is false here.
1530 const bool IsKnownNeverOddPositive = ExponentKnownBits.isNegative();
1531 const bool IsKnownNeverOddNegative = ExponentKnownBits.isNonNegative();
1532
1533 // powi(-0.0, odd-positive) = -0.0
1534 // powi(-inf, odd-negative) = -0.0
1535 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddPositive) &&
1536 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddNegative))
1537 Known.knownNot(fcNegZero);
1538
1539 // powi(-0.0, odd-negative) = -inf
1540 // powi(-inf, odd-positive) = -inf
1541 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddNegative) &&
1542 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddPositive))
1543 Known.knownNot(fcNegInf);
1544 }
1545
1546 // powi(x, exp) --> inf
1547 // when:
1548 // * powi(inf, exp), exp > 0
1549 // * powi(+/-0, exp), exp < 0
1550 // * powi(finite, exp), |exp| > 1
1551 // * powi(subnormal, -1)
1552 // TODO:
1553 // 1. This simple all or nothing approach. We can do better
1554 // and cover sign/parity and exp > 1 vs exp < -1 separately.
1555 // 2. powi(0/nan, exp), exp > 0 can be refinable
1556 // to fcNan | fcZero | fcPosNormal.
1557 {
1558 APInt MinExp = ExponentKnownBits.getSignedMinValue();
1559 APInt MaxExp = ExponentKnownBits.getSignedMaxValue();
1560
1561 // powi(inf, exp), exp > 0
1562 bool MayInfSrc =
1563 !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();
1564
1565 // powi(+/-0, exp), exp < 0
1566 bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();
1567
1568 // powi(finite, exp), |exp| > 1
1569 bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
1570 bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
1571 bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;
1572
1573 // powi(subnormal, -1)
1574 bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
1575 bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;
1576
1577 if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
1578 Known.knownNot(fcInf);
1579 }
1580
1581 return Known;
1582}
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, bool IsFMA)
static DenormalMode getConvertDenormalMode(DenormalMode DstMode, DenormalMode SrcMode)
static KnownFPClass fpconvert(const KnownFPClass &KnownSrc_, const fltSemantics &DstSem, const fltSemantics &SrcSem, 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:334
static LLVM_ABI Semantics SemanticsToEnum(const llvm::fltSemantics &Sem)
Definition APFloat.cpp:184
static LLVM_ABI bool isRepresentableAsNormalIn(const fltSemantics &Src, const fltSemantics &Dst)
Definition APFloat.cpp:384
static const fltSemantics & PPCDoubleDouble()
Definition APFloat.h:310
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
bool isKnownNeverInfOrNaN() const
Return true if it's known this can never be an infinity or nan.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
static LLVM_ABI KnownFPClass applyOutputDenormalMode(const KnownFPClass &Src, DenormalMode Mode)
Return the known classes of Src after producing an output that may flush subnormals to zero according...
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
static LLVM_ABI KnownFPClass applyInputDenormalMode(const KnownFPClass &Src, DenormalMode Mode)
Return the known classes of Src after passing through an input that may flush subnormals to zero acco...
static LLVM_ABI KnownFPClass fmul(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fmul.
static LLVM_ABI KnownFPClass ceil(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ceil.
static LLVM_ABI KnownFPClass fadd_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd x, x.
static LLVM_ABI KnownFPClass fmuladd(const KnownFPClass &LHS, const KnownFPClass &RHS, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fmuladd.
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.
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 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.
static LLVM_ABI KnownFPClass fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv.
KnownFPClass(FPClassMask Known=FPClassMask::kfcAllFlags)
static LLVM_ABI KnownFPClass fpext(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy, DenormalMode DstMode, DenormalMode SrcMode)
Propagate known class for fpext.
static LLVM_ABI KnownFPClass cos(const KnownFPClass &Src)
Report known values for cos.
static LLVM_ABI KnownFPClass fptrunc(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy, DenormalMode DstMode, DenormalMode SrcMode)
Propagate known class for fptrunc and fptrunc_round.
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())
static LLVM_ABI KnownFPClass fmuladd_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fmuladd squared, squared, addend.
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.
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.
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 ...
FPClassTest getKnownFPClasses() const
Floating-point classes the value could be one of.
static LLVM_ABI KnownFPClass roundToIntegral(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for rounding intrinsics (rint, nearbyint, round, roundeven).
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.
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
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 isKnownNever(FPClassMask Mask) const
Return true if it's known this can never be one of the mask entries.
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.
static LLVM_ABI KnownFPClass trunc(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for trunc.
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 log(const KnownFPClass &Src, DenormalMode Mode, bool IsMultiUnitFPType)
Propagate known class for log/log2/log10.
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.
static LLVM_ABI KnownFPClass floor(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for floor.
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,...
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.
#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.
@ IEEE
IEEE-754 denormal numbers preserved.
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 getDynamic()
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
APFloatBase::ExponentType maxExponent
Definition APFloat.h:1026
APFloatBase::ExponentType minExponent
Definition APFloat.h:1030
unsigned int sizeInBits
Definition APFloat.h:1037
unsigned int precision
Definition APFloat.h:1034