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 and fsub. Invalid for fma.
497static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
498 const KnownFPClass &KnownRHS, RoundingMode RM) {
500
501 Known.propagateNonSNaN(KnownLHS, KnownRHS);
502
503 // Adding positive and negative infinity produces NaN, but only if both
504 // opposite-sign infinity combinations are possible.
505 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
506 (KnownLHS.isKnownNever(fcPosInf) || KnownRHS.isKnownNever(fcNegInf)) &&
507 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosInf)))
508 Known.knownNot(fcNan);
509
510 if (KnownLHS.cannotBeOrderedLessThanZero() &&
511 KnownRHS.cannotBeOrderedLessThanZero()) {
513
514 // This can't underflow if one of the operands is known normal.
515 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
517 Known.knownNot(fcZero | fcPosSubnormal);
518 }
519
520 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
523
524 // This can't underflow if one of the operands is known normal.
525 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
527 Known.knownNot(fcZero | fcNegSubnormal);
528 }
529
530 // TODO: Refine signed zeroes for other rounding modes once fadd/fsub take a
531 // rounding mode parameter.
533 // (fadd x, +0.0) is guaranteed to return +0.0, not -0.0.
534 if (KnownLHS.isKnownNever(fcNegZero) || KnownRHS.isKnownNever(fcNegZero))
535 Known.knownNot(fcNegZero);
536 }
537
538 return Known;
539}
540
542 const KnownFPClass &KnownRHS_,
543 DenormalMode Mode) {
544 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
545 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
546
548 fadd_impl(KnownLHS, KnownRHS, RoundingMode::NearestTiesToEven);
549
550 return applyOutputDenormalMode(Known, Mode);
551}
552
554 DenormalMode Mode) {
555 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
556
558 fadd_impl(KnownSrc, KnownSrc, RoundingMode::NearestTiesToEven);
559
560 if (KnownSrc.isKnownNever(fcPosSubnormal))
561 Known.knownNot(fcPosSubnormal);
562 if (KnownSrc.isKnownNever(fcNegSubnormal))
563 Known.knownNot(fcNegSubnormal);
564
565 // Doubling 0 will give the same 0.
566 if (KnownSrc.isKnownNever(fcPosZero))
567 Known.knownNot(fcPosZero);
568
569 return applyOutputDenormalMode(Known, Mode);
570}
571
573 const KnownFPClass &KnownRHS_,
574 DenormalMode Mode) {
575 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
576 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
577
578 // fsub(x, y) == fadd(x, -y) as long as we negate after subnormals are
579 // flushed.
580 KnownRHS.fneg();
581
583 fadd_impl(KnownLHS, KnownRHS, RoundingMode::NearestTiesToEven);
584
585 return applyOutputDenormalMode(Known, Mode);
586}
587
589 const KnownFPClass &KnownRHS_,
590 DenormalMode Mode) {
591 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
592 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
593
595
596 // fmul will xor the sign-bit of non-NaN inputs:
597 // +X * +Y or -X * -Y => +Q
598 // +X * -Y or -X * +Y => -Q
599
600 Known.propagateNonSNaN(KnownLHS, KnownRHS);
601
602 // NaN is generated from 0.0 * inf and inf * 0.0.
603 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
604 (KnownRHS.isKnownNeverInfinity() || KnownLHS.isKnownNever(fcZero)) &&
605 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNever(fcZero)))
606 Known.knownNot(fcNan);
607
608 // Infinity may be produced from two non-zero inputs.
609 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
613 Known.knownNot(fcPosInf);
614 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
618 Known.knownNot(fcNegInf);
619
620 // Normal and subnormal results require two non-zero finite operands.
621 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
625 Known.knownNot(fcPosSubnormal | fcPosNormal);
626 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
630 Known.knownNot(fcNegSubnormal | fcNegNormal);
631
632 // Zero may be produced from two finite inputs.
633 if ((KnownLHS.isKnownNever(fcPosFinite) ||
634 KnownRHS.isKnownNever(fcPosFinite)) &&
635 (KnownLHS.isKnownNever(fcNegFinite) ||
636 KnownRHS.isKnownNever(fcNegFinite)))
637 Known.knownNot(fcPosZero);
638 if ((KnownLHS.isKnownNever(fcPosFinite) ||
639 KnownRHS.isKnownNever(fcNegFinite)) &&
640 (KnownLHS.isKnownNever(fcNegFinite) ||
641 KnownRHS.isKnownNever(fcPosFinite)))
642 Known.knownNot(fcNegZero);
643
644 return applyOutputDenormalMode(Known, Mode);
645}
646
647// TODO: This generalizes to known ranges
649 const APFloat &CRHS, DenormalMode Mode) {
650 // Match denormal scaling pattern, similar to the case in ldexp. If the
651 // constant's exponent is sufficiently large, the result cannot be subnormal.
652
653 const fltSemantics &Flt = CRHS.getSemantics();
654 unsigned Precision = APFloat::semanticsPrecision(Flt);
655 const int MantissaBits = Precision - 1;
656
657 int MinKnownExponent = ilogb(CRHS);
658 bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);
659
660 KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
661 if (CannotBeSubnormal)
662 Known.knownNot(fcSubnormal);
663
664 // Multiply of values <= 1 cannot introduce overflow.
665 if (KnownLHS.isKnownNever(fcInf)) {
666 if (MinKnownExponent < 0)
667 Known.knownNot(fcInf);
668 else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
669 Flt)) == APFloat::cmpEqual)
670 Known.knownNot(fcInf);
671 }
672
673 return Known;
674}
675
677 const KnownFPClass &KnownRHS_,
678 DenormalMode Mode) {
679 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
680 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
681
683
684 // fdiv will xor the sign-bit of non-NaN inputs:
685 // +X / +Y or -X / -Y => +Q
686 // +X / -Y or -X / +Y => -Q
687
688 Known.propagateNonSNaN(KnownLHS, KnownRHS);
689
690 // NaN is generated from 0.0 / 0.0 and inf / inf.
691 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
692 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
693 (KnownLHS.isKnownNever(fcZero) || KnownRHS.isKnownNever(fcZero)))
694 Known.knownNot(fcNan);
695
696 // Infinity may be produced from non-zero / finite.
697 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
698 KnownRHS.isKnownNever(fcPosFinite)) &&
700 KnownRHS.isKnownNever(fcNegFinite)))
701 Known.knownNot(fcPosInf);
702 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal | fcPosInf) ||
703 KnownRHS.isKnownNever(fcNegFinite)) &&
705 KnownRHS.isKnownNever(fcPosFinite)))
706 Known.knownNot(fcNegInf);
707
708 // Normal and subnormal results require two non-zero finite operands.
709 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
713 Known.knownNot(fcPosSubnormal | fcPosNormal);
714 if ((KnownLHS.isKnownNever(fcPosSubnormal | fcPosNormal) ||
718 Known.knownNot(fcNegSubnormal | fcNegNormal);
719
720 // Zero may be produced from finite / non-zero.
721 if ((KnownLHS.isKnownNever(fcPosFinite) ||
723 (KnownLHS.isKnownNever(fcNegFinite) ||
725 Known.knownNot(fcPosZero);
726 if ((KnownLHS.isKnownNever(fcPosFinite) ||
728 (KnownLHS.isKnownNever(fcNegFinite) ||
730 Known.knownNot(fcNegZero);
731
732 return applyOutputDenormalMode(Known, Mode);
733}
734
736 DenormalMode Mode) {
737 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
738
739 // X / X is always exactly 1.0 or a NaN.
741
742 Known.propagateNonSNaN(KnownSrc);
743
744 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNever(fcZero))
745 Known.knownNot(fcNan);
746
747 // The result is never subnormal, so the output denormal mode does not matter.
748 return Known;
749}
750
752 const KnownFPClass &KnownRHS_,
753 DenormalMode Mode) {
754 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
755 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
757
758 // We are assuming that frem(x, Inf) is already handled elsewhere.
759
760 Known.knownNot(fcInf);
761
762 Known.propagateNonSNaN(KnownLHS, KnownRHS);
763
764 // frem(Inf, x) and frem(x, 0) produce NaN.
765 if (KnownLHS.isKnownNeverInfOrNaN() && KnownRHS.isKnownNeverNaN() &&
766 KnownRHS.isKnownNever(fcZero)) {
767 Known.knownNot(fcNan);
768 }
769
770 // The sign for frem is the same as the first operand.
772 Known.knownNot(fcPosNormal | fcPosSubnormal);
774 Known.knownNot(fcNegNormal | fcNegSubnormal);
775
776 // A negative zero result requires a negative finite first operand.
777 if (KnownLHS.isKnownNever(fcNegFinite))
778 Known.knownNot(fcNegZero);
779
780 // A positive zero result requires a positive finite first operand.
781 if (KnownLHS.isKnownNever(fcPosFinite))
782 Known.knownNot(fcPosZero);
783
784 return applyOutputDenormalMode(Known, Mode);
785}
786
788 DenormalMode Mode) {
789 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
790
791 // X % X is always exactly [+-]0.0 or a NaN.
793
794 Known.propagateNonSNaN(KnownSrc);
795
796 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNever(fcZero))
797 Known.knownNot(fcNan);
798
799 // The sign of a zero result is the sign of the finite non-zero input.
801 Known.knownNot(fcPosZero);
803 Known.knownNot(fcNegZero);
804
805 // The result is never subnormal, so the output denormal mode does not matter.
806 return Known;
807}
808
809static KnownFPClass fma_impl(const KnownFPClass &KnownLHS,
810 const KnownFPClass &KnownRHS) {
812
813 if (KnownLHS.cannotBeOrderedLessThanZero() &&
814 KnownRHS.cannotBeOrderedLessThanZero()) {
816
817 // This can't underflow if one of the operands is known normal.
818 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
820 Known.knownNot(fcZero | fcPosSubnormal);
821 }
822
823 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
826
827 // This can't underflow if one of the operands is known normal.
828 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
830 Known.knownNot(fcZero | fcNegSubnormal);
831 }
832
833 return Known;
834}
835
837 const KnownFPClass &KnownRHS_,
838 const KnownFPClass &KnownAddend_,
839 DenormalMode Mode) {
840 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
841 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
842 KnownFPClass KnownAddend = applyInputDenormalMode(KnownAddend_, Mode);
843
844 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, DenormalMode::getIEEE());
845
846 // FMA differs from the base fmul + fadd handling only in the treatment of -0
847 // results.
848 //
849 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
850 // unlike for a separate fadd.
851 KnownFPClass Known = fma_impl(Mul, KnownAddend);
852
853 // propagateNonSNaN for 3 arguments.
854 if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
855 KnownAddend.isKnownNever(fcSNan))
856 Known.knownNot(fcSNan);
857
858 // Rule out NaN.
859 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
860 KnownAddend.isKnownNeverNaN()) {
861 // NaN is produced when zero is multiplied by infinity, or when adding two
862 // exact infinities of the opposite sign. An exact infinity requires at
863 // least one infinite operand.
864
865 const bool NeverZeroMulInf =
866 (KnownLHS.isKnownNever(fcInf) || KnownRHS.isKnownNever(fcZero)) &&
867 (KnownRHS.isKnownNever(fcInf) || KnownLHS.isKnownNever(fcZero));
868 // Multiplying infinity by a non-zero finite may change the sign.
869 const bool NeverExactPosInf =
870 (KnownLHS.isKnownNever(fcPosInf) ||
872 (KnownRHS.isKnownNever(fcPosInf) ||
874 (KnownLHS.isKnownNever(fcNegInf) ||
876 (KnownRHS.isKnownNever(fcNegInf) ||
878 const bool NeverExactNegInf =
879 (KnownLHS.isKnownNever(fcPosInf) ||
881 (KnownRHS.isKnownNever(fcPosInf) ||
883 (KnownLHS.isKnownNever(fcNegInf) ||
885 (KnownRHS.isKnownNever(fcNegInf) ||
887 if (NeverZeroMulInf &&
888 (KnownAddend.isKnownNever(fcPosInf) || NeverExactNegInf) &&
889 (KnownAddend.isKnownNever(fcNegInf) || NeverExactPosInf))
890 Known.knownNot(fcNan);
891 }
892
893 return applyOutputDenormalMode(Known, Mode);
894}
895
897 const KnownFPClass &KnownRHS,
898 const KnownFPClass &KnownAddend,
899 DenormalMode Mode) {
900 // fmuladd can lower to either fma(x, y, z) or fadd(fmul(x, y), z). Compute
901 // the intersection of both possibilities.
902 KnownFPClass FMA = fma(KnownLHS, KnownRHS, KnownAddend, Mode);
903 KnownFPClass MulAdd = fadd(fmul(KnownLHS, KnownRHS, Mode), KnownAddend, Mode);
904 return FMA.intersectWith(MulAdd);
905}
906
908 const KnownFPClass &KnownAddend_,
909 DenormalMode Mode) {
910 KnownFPClass KnownSquared = applyInputDenormalMode(KnownSquared_, Mode);
911 KnownFPClass KnownAddend = applyInputDenormalMode(KnownAddend_, Mode);
912
913 KnownFPClass Squared = square(KnownSquared, DenormalMode::getIEEE());
914 KnownFPClass Known = fma_impl(Squared, KnownAddend);
915
916 Known.propagateNonSNaN(KnownSquared, KnownAddend);
917
918 // Only fma(+inf, +inf, -inf) and fma(-inf, -inf, -inf) produce NaN when
919 // squaring.
920 if (KnownSquared.isKnownNeverNaN() && KnownAddend.isKnownNeverNaN() &&
921 (KnownSquared.isKnownNever(fcInf) || KnownAddend.isKnownNever(fcNegInf)))
922 Known.knownNot(fcNan);
923
924 return applyOutputDenormalMode(Known, Mode);
925}
926
928 const KnownFPClass &KnownAddend,
929 DenormalMode Mode) {
930 KnownFPClass FMA = fma_square(KnownSquared, KnownAddend, Mode);
931 KnownFPClass MulAdd = fadd(square(KnownSquared, Mode), KnownAddend, Mode);
932 return FMA.intersectWith(MulAdd);
933}
934
937 Known.knownNot(fcNegative);
938
939 Known.propagateNonNaN(KnownSrc);
940
941 // The following deductions assume that exp10(-1.0) = +0.1 and
942 // exp10(+1.0) = +10.0 are both finite normal values.
943
944 // Zero can only be produced if x < -1.0.
945 if (KnownSrc.isKnownNever(fcNegNormal | fcNegInf))
946 Known.knownNot(fcPosZero);
947
948 // Subnormals can only be produced if x < -1.0 and x is finite.
949 if (KnownSrc.isKnownNever(fcNegNormal))
950 Known.knownNot(fcPosSubnormal);
951
952 // Infinity can only be produced if x > +1.0.
953 if (KnownSrc.isKnownNever(fcPosNormal | fcPosInf))
954 Known.knownNot(fcPosInf);
955
956 return Known;
957}
958
960 bool IsMultiUnitFPType) {
961 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
963
964 // PPCDoubleDouble can represent the exact value of 1.0 + subnormal, and
965 // log(1.0 + subnormal) = subnormal.
966 if (!IsMultiUnitFPType)
967 Known.knownNot(fcNegZero | fcSubnormal);
968
969 Known.propagateNonSNaN(KnownSrc);
970
971 if (KnownSrc.isKnownNeverPosInfinity())
972 Known.knownNot(fcPosInf);
973
974 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
975 Known.knownNot(fcNan);
976
977 if (KnownSrc.isKnownNever(fcZero))
978 Known.knownNot(fcNegInf);
979
980 // This only matters for PPCDoubleDouble.
981 return applyOutputDenormalMode(Known, Mode);
982}
983
985 DenormalMode Mode) {
987 Known.knownNot(fcPosSubnormal);
988
989 if (KnownSrc.isKnownNeverPosInfinity())
990 Known.knownNot(fcPosInf);
991
992 Known.propagateNonSNaN(KnownSrc);
993
994 // Any negative value besides -0 returns a nan.
995 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
996 Known.knownNot(fcNan);
997
998 // The only negative value that can be returned is -0 for -0 inputs.
1000
1001 // If the input denormal mode could be PreserveSign, a negative
1002 // subnormal input could produce a negative zero output.
1003 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
1004 Known.knownNot(fcNegZero);
1005
1006 return Known;
1007}
1008
1011
1012 Known.propagateNonSNaN(KnownSrc);
1013
1014 // Return NaN on infinite inputs.
1015 Known.knownNot(fcInf);
1016 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
1017 Known.knownNot(fcNan);
1018
1019 return Known;
1020}
1021
1023 return sin(KnownSrc);
1024}
1025
1028
1029 // tan never returns Inf (tan(+-Inf) = NaN; tan(finite) = finite).
1030 Known.knownNot(fcInf);
1031
1032 Known.propagateNonSNaN(KnownSrc);
1033
1034 // NaN propagates. tan(+-Inf) is NaN.
1035 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
1036 Known.knownNot(fcNan);
1037
1038 return Known;
1039}
1040
1043
1044 // sinh is sign-preserving: sinh(x) < 0 iff x < 0.
1045 if (KnownSrc.isKnownNever(fcNegative))
1046 Known.knownNot(fcNegative);
1047
1048 // A nonzero positive result requires a nonzero positive input.
1049 // Zero remains possible: sinh(+/-0.0) = +/-0.0, and flushing a subnormal
1050 // may produce +0.0.
1053
1054 Known.propagateNonNaN(KnownSrc);
1055
1056 return Known;
1057}
1058
1061
1062 // cosh(x) >= 1 for all real x; cosh(+-Inf) = +Inf. Never negative,
1063 // zero, or subnormal.
1064 Known.knownNot(fcNegative | fcZero | fcSubnormal);
1065
1066 Known.propagateNonNaN(KnownSrc);
1067
1068 return Known;
1069}
1070
1073
1074 // tanh is bounded to (-1, 1), never Inf.
1075 Known.knownNot(fcInf);
1076
1077 // tanh is sign-preserving: tanh(x) < 0 iff x < 0.
1078 if (KnownSrc.isKnownNever(fcNegSubnormal | fcNegNormal | fcNegInf)) {
1079 Known.knownNot(fcNegSubnormal | fcNegNormal);
1080
1081 // -0.0 is preserved: tanh(-0.0) = -0.0.
1082 if (KnownSrc.isKnownNever(fcNegZero))
1083 Known.knownNot(fcNegZero);
1084 }
1085
1086 // Likewise, tanh(x) > 0 iff x > 0. Zero is not ruled out: tanh(+-0.0) =
1087 // +-0.0, and a flushed subnormal may become +0.0.
1089 Known.knownNot(fcPosSubnormal | fcPosNormal);
1090
1091 Known.propagateNonNaN(KnownSrc);
1092
1093 return Known;
1094}
1095
1098
1099 // asin is bounded to [-pi/2, pi/2], never Inf.
1100 Known.knownNot(fcInf);
1101
1102 Known.propagateNonSNaN(KnownSrc);
1103
1104 // asin is sign-preserving for finite arguments.
1105 if (KnownSrc.isKnownNever(fcNegFinite))
1106 Known.knownNot(fcNegFinite);
1107
1108 if (KnownSrc.isKnownNever(fcPosSubnormal | fcPosNormal))
1109 Known.knownNot(fcPosSubnormal | fcPosNormal);
1110
1111 // NaN propagates. asin(x) is also NaN for |x| > 1, so we cannot rule
1112 // out NaN without knowing the source is in [-1, 1].
1113 return Known;
1114}
1115
1118
1119 // acos(x) is bounded to [0, pi] for -1 <= x <= 1, and is never negative,
1120 // infinite, or subnormal. The smallest non-zero value occurs when x is
1121 // close to 1.0, where acos(x) can be approximated by sqrt(2 * (1 - x)).
1122 // Since sqrt cannot produce a subnormal result, we can conclude that
1123 // acos(x) will also never produce a subnormal result.
1124 Known.knownNot(fcNegative | fcInf | fcSubnormal);
1125
1126 // acos(x) == +0.0 iff x == +1.0
1127 if (KnownSrc.isKnownNever(fcPosNormal))
1128 Known.knownNot(fcZero);
1129
1130 Known.propagateNonSNaN(KnownSrc);
1131
1132 // NaN propagates. acos(x) is also NaN for |x| > 1, so we cannot rule
1133 // out NaN without knowing the source is in [-1, 1].
1134 return Known;
1135}
1136
1139
1140 // atan is bounded to (-pi/2, pi/2), never Inf. atan(+-Inf) = +-pi/2 (finite).
1141 Known.knownNot(fcInf);
1142
1143 // Ruling out Subnormal/Normal from the result requires the
1144 // input to never be finite-nonzero and never inf, since
1145 // atan(+-inf) = +-pi/2
1147 Known.knownNot(fcNegSubnormal | fcNegNormal);
1148
1150 Known.knownNot(fcPosSubnormal | fcPosNormal);
1151
1152 // atan(-0.0) = -0.0. Negative finite inputs may also produce -0.0
1153 // if the result rounds to a negative subnormal that is flushed to zero.
1155 Known.knownNot(fcNegZero);
1156
1157 Known.propagateNonNaN(KnownSrc);
1158
1159 return Known;
1160}
1161
1163 const KnownFPClass &KnownX_,
1164 DenormalMode Mode) {
1165 KnownFPClass KnownY = applyInputDenormalMode(KnownY_, Mode);
1166 KnownFPClass KnownX = applyInputDenormalMode(KnownX_, Mode);
1168
1169 // Even though these deductions are correct, we are ignoring the following
1170 // potentially erroneous cases:
1171 // * atan2(y, inf) is not subnormal
1172 // * atan2(inf, x) is not zero or subnormal
1173
1174 // atan2 result is in (-pi, pi], never Inf.
1175 Known.knownNot(fcInf);
1176
1177 Known.propagateNonNaN(KnownY, KnownX);
1178
1179 // If x <= -0.0, then |atan2(y, x)| >= pi/2
1180 if (KnownX.isKnownNever(fcPositive))
1181 Known.knownNot(fcZero | fcSubnormal);
1182
1183 // If y >= +0.0, then atan2(y, x) >= +0.0
1184 if (KnownY.isKnownNever(fcNegative))
1185 Known.knownNot(fcNegative);
1186
1187 // If y <= -0.0, then atan2(y, x) <= -0.0
1188 if (KnownY.isKnownNever(fcPositive))
1189 Known.knownNot(fcPositive);
1190
1191 return applyOutputDenormalMode(Known, Mode);
1192}
1193
1194static KnownFPClass fpconvert(const KnownFPClass &KnownSrc_,
1195 const fltSemantics &DstSem,
1196 const fltSemantics &SrcSem, DenormalMode Mode) {
1200 auto IsSupported = [](APFloatBase::Semantics SemType) -> bool {
1201 switch (SemType) {
1208 return true;
1209 default:
1210 return false;
1211 }
1212 };
1213
1214 // Return unknown for types we have not validated.
1215 // TODO: Add support for lossless casts to PPCDoubleDouble.
1216 if (!IsSupported(SrcType) || !IsSupported(DstType))
1217 return Known;
1218
1220
1221 // TODO: Until we pass the rounding mode into fpconvert, the rounding mode is
1222 // assumed to be dynamic. This includes potential future rounding modes such
1223 // as roundAwayZero (not the same as roundNearestTiesAway) and roundToOdd
1224 // (jamming).
1225
1226 Known.propagateNonNaN(KnownSrc);
1227
1228 const bool NormalSrcIsFiniteDst = DstSem.maxExponent > SrcSem.maxExponent ||
1229 (DstSem.maxExponent == SrcSem.maxExponent &&
1230 DstSem.precision >= SrcSem.precision);
1231
1232 // True if the dst can represent all non-zero finite values of src.
1233 const bool NonZeroFiniteSrcIsNonZeroInDst =
1234 DstSem.minExponent <= SrcSem.minExponent &&
1235 DstSem.precision >= SrcSem.precision;
1236
1237 // For example: f32 = bf16, f128 = f80
1238 const bool NormalIsNormalAndSubnormalIsSubnormal =
1239 DstSem.minExponent == SrcSem.minExponent &&
1240 DstSem.maxExponent >= SrcSem.maxExponent &&
1241 DstSem.precision >= SrcSem.precision;
1242
1243 // Rule out infinity.
1244 // We are assuming that subnormal values have a magnitude less than 1.0.
1245 if (KnownSrc.isKnownNever(fcPosInf) &&
1246 (KnownSrc.isKnownNever(fcPosNormal) || NormalSrcIsFiniteDst))
1247 Known.knownNot(fcPosInf);
1248 if (KnownSrc.isKnownNever(fcNegInf) &&
1249 (KnownSrc.isKnownNever(fcNegNormal) || NormalSrcIsFiniteDst))
1250 Known.knownNot(fcNegInf);
1251
1252 // Rule out non-zero finite.
1253 if (NormalIsNormalAndSubnormalIsSubnormal) {
1254 // Normal never becomes subnormal, and vice-versa.
1255 if (KnownSrc.isKnownNever(fcPosNormal))
1256 Known.knownNot(fcPosNormal);
1257 if (KnownSrc.isKnownNever(fcNegNormal))
1258 Known.knownNot(fcNegNormal);
1259 if (KnownSrc.isKnownNever(fcPosSubnormal))
1260 Known.knownNot(fcPosSubnormal);
1261 if (KnownSrc.isKnownNever(fcNegSubnormal))
1262 Known.knownNot(fcNegSubnormal);
1263 } else {
1264 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1265 Known.knownNot(fcPosNormal | fcPosSubnormal);
1266 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1267 Known.knownNot(fcNegNormal | fcNegSubnormal);
1268 }
1269
1270 // Source subnormals cannot round to destination normals when the
1271 // destination's minimum normal exponent is larger.
1272 if (DstSem.minExponent > SrcSem.minExponent) {
1273 if (KnownSrc.isKnownNever(fcPosNormal))
1274 Known.knownNot(fcPosNormal);
1275 if (KnownSrc.isKnownNever(fcNegNormal))
1276 Known.knownNot(fcNegNormal);
1277 }
1278
1279 // Rule out subnormal.
1280 if (APFloat::isRepresentableAsNormalIn(SrcSem, DstSem))
1281 Known.knownNot(fcSubnormal);
1282
1283 // Rule out positive zero.
1284 if (KnownSrc.isKnownNever(fcPosZero) &&
1286 NonZeroFiniteSrcIsNonZeroInDst))
1287 Known.knownNot(fcPosZero);
1288
1289 // Rule out negative zero.
1290 if (KnownSrc.isKnownNever(fcNegZero) &&
1292 NonZeroFiniteSrcIsNonZeroInDst))
1293 Known.knownNot(fcNegZero);
1294
1296}
1297
1298// Determine what the input and output denormal modes are for fpconvert from
1299// the denormal modes for the dst and src types.
1300//
1301// TODO: We are currently conservative, and assume DenormalMode::getDynamic() if
1302// the dst or src denormal mode is not IEEE.
1304 DenormalMode SrcMode) {
1305 if (DstMode == DenormalMode::getIEEE() && SrcMode == DenormalMode::getIEEE())
1306 return DenormalMode::getIEEE();
1307 return DenormalMode::getDynamic();
1308}
1309
1311 const fltSemantics &DstTy,
1312 const fltSemantics &SrcTy,
1313 DenormalMode DstMode, DenormalMode SrcMode) {
1314 // Note that fpext may round for some bizarre type combinations.
1315 // Such as ieee_binary256 = fpext(PPCDoubleDouble) if we add support for
1316 // ieee_binary256 in the future. PPCDoubleDouble can represent values such as
1317 // DBL_MAX + DBL_TRUE_MIN which would normally require 2098 bits of precision
1318 // to represent.
1319 return fpconvert(KnownSrc, DstTy, SrcTy,
1320 getConvertDenormalMode(DstMode, SrcMode));
1321}
1322
1324 const fltSemantics &DstTy,
1325 const fltSemantics &SrcTy,
1326 DenormalMode DstMode, DenormalMode SrcMode) {
1327 // TODO: pass rounding mode from fptrunc_round
1328 return fpconvert(KnownSrc, DstTy, SrcTy,
1329 getConvertDenormalMode(DstMode, SrcMode));
1330}
1331
1333 bool MayBeMultiUnitFPType,
1334 DenormalMode Mode) {
1336
1337 // Integer results cannot be subnormal.
1338 Known.knownNot(fcSubnormal);
1339
1340 Known.propagateNonNaN(KnownSrc);
1341
1342 // Pass through infinities, except PPC_FP128 is a special case for intrinsics.
1343 if (!MayBeMultiUnitFPType) {
1344 if (KnownSrc.isKnownNeverPosInfinity())
1345 Known.knownNot(fcPosInf);
1346 if (KnownSrc.isKnownNeverNegInfinity())
1347 Known.knownNot(fcNegInf);
1348 }
1349
1350 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1351 Known.knownNot(fcPosNormal);
1352
1353 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1354 Known.knownNot(fcNegNormal);
1355
1356 // Negative round ups towards zero produce negative zero.
1357 if (KnownSrc.isKnownNever(fcNegFinite))
1358 Known.knownNot(fcNegZero);
1359
1360 // Negative subnormals may flush to positive zero.
1361 if (KnownSrc.isKnownNever(fcPosFinite) &&
1362 (KnownSrc.isKnownNever(fcNegSubnormal) ||
1363 !Mode.inputsMayBePositiveZero()))
1364 Known.knownNot(fcPosZero);
1365
1366 return Known;
1367}
1368
1370 DenormalMode Mode) {
1372 /*MayBeMultiUnitFPType=*/true, Mode);
1373
1374 if (KnownSrc.isKnownNeverPosInfinity())
1375 Known.knownNot(fcPosInf);
1376 if (KnownSrc.isKnownNeverNegInfinity())
1377 Known.knownNot(fcNegInf);
1378
1379 return Known;
1380}
1381
1383 bool IsMultiUnitFPType, DenormalMode Mode) {
1384 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1385
1386 // Applicable for multi-unit floating point types.
1387 if (KnownSrc.isKnownNeverPosInfinity())
1388 Known.knownNot(fcPosInf);
1389
1390 return Known;
1391}
1392
1394 bool IsMultiUnitFPType, DenormalMode Mode) {
1395 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1396
1397 // Applicable for multi-unit floating point types.
1398 if (KnownSrc.isKnownNeverNegInfinity())
1399 Known.knownNot(fcNegInf);
1400
1401 return Known;
1402}
1403
1405 DenormalMode Mode) {
1406 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
1408
1409 Known.knownNot(fcSubnormal);
1410
1411 Known.propagateNonNaN(KnownSrc);
1412
1413 if (KnownSrc.isKnownNeverPosInfinity())
1414 Known.knownNot(fcPosInf);
1415 if (KnownSrc.isKnownNeverNegInfinity())
1416 Known.knownNot(fcNegInf);
1417
1418 if (KnownSrc.isKnownNever(fcPosZero))
1419 Known.knownNot(fcPosZero);
1420 if (KnownSrc.isKnownNever(fcNegZero))
1421 Known.knownNot(fcNegZero);
1422
1423 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1424 Known.knownNot(fcPosNormal);
1425 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1426 Known.knownNot(fcNegNormal);
1427
1428 return Known;
1429}
1430
1432 const APInt &ConstantRangeExpMin,
1433 const APInt &ConstantRangeExpMax,
1434 const fltSemantics &Flt, DenormalMode Mode) {
1436
1437 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
1438
1439 if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
1440 // ldexp(x, 0) -> x
1441 // Here we make sure to properly propagate sNaN and denormals.
1442 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcNan);
1443 Known.propagateNonNaN(KnownSrc);
1444 return applyOutputDenormalMode(Known, Mode);
1445 }
1446
1447 Known.propagateNonNaN(KnownSrc);
1448
1449 // Sign is preserved, but underflows may produce zeroes.
1450 if (KnownSrc.isKnownNever(fcNegative))
1451 Known.knownNot(fcNegative);
1452 else if (KnownSrc.cannotBeOrderedLessThanZero())
1454
1455 if (KnownSrc.isKnownNever(fcPositive))
1456 Known.knownNot(fcPositive);
1457 else if (KnownSrc.cannotBeOrderedGreaterThanZero())
1459
1460 // TODO: determine when it is safe to rule out subnormal for ppcf128.
1461 if (&Flt != &APFloat::PPCDoubleDouble()) {
1462 unsigned Precision = APFloat::semanticsPrecision(Flt);
1463 const int MantissaBits = Precision - 1;
1464 if (ConstantRangeExpMin.sge(MantissaBits))
1465 Known.knownNot(fcSubnormal);
1466 }
1467
1468 if (ConstantRangeExpMax.isNonPositive()) {
1469 // If we know the power is <= 0, can't introduce inf
1470 if (KnownSrc.isKnownNeverPosInfinity())
1471 Known.knownNot(fcPosInf);
1472 if (KnownSrc.isKnownNeverNegInfinity())
1473 Known.knownNot(fcNegInf);
1474 } else if (ConstantRangeExpMin.isNonNegative()) {
1475 // If we know the power is >= 0, can't introduce subnormal or zero
1476 if (KnownSrc.isKnownNeverPosSubnormal())
1477 Known.knownNot(fcPosSubnormal);
1478 if (KnownSrc.isKnownNeverNegSubnormal())
1479 Known.knownNot(fcNegSubnormal);
1480 if (KnownSrc.isKnownNever(fcPosZero))
1481 Known.knownNot(fcPosZero);
1482 if (KnownSrc.isKnownNever(fcNegZero))
1483 Known.knownNot(fcNegZero);
1484 }
1485
1486 return applyOutputDenormalMode(Known, Mode);
1487}
1488
1490 const KnownBits &ExpBits,
1491 const fltSemantics &Flt, DenormalMode Mode) {
1492 return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
1493 ExpBits.getSignedMaxValue(), Flt, Mode);
1494}
1495
1497 const KnownFPClass &KnownRHS) {
1499
1500 Known.propagateNonSNaN(KnownLHS, KnownRHS);
1501
1502 // pow may return NaN if one of the arguments is NaN. NaN may be produced from
1503 // a non-zero-finite-negative base and a non-integer exponent.
1504 if (KnownLHS.isKnownNever(fcNan | fcNegNormal | fcNegSubnormal) &&
1505 KnownRHS.isKnownNeverNaN())
1506 Known.knownNot(fcNan);
1507
1508 // We could rule out negative and subnormal results when exponent is known to
1509 // never be a normal value, but having either argument being known to never be
1510 // normal is unlikely and not worth considering.
1511
1512 // Only a negative base raised to an odd power returns a negative value.
1513 if (KnownLHS.isKnownNever(fcNegative)) {
1514 Known.knownNot(fcNegative);
1515 } else if (KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1516 Known.knownNot(fcNegNormal | fcNegSubnormal);
1517 // See if we can also rule out -0.0 or -inf.
1518 // Here at least one of -0.0 or -inf is a possible base.
1519
1520 // pow(-0.0, odd-positive) = -0.0
1521 // pow(-inf, odd-negative) = -0.0
1522 if ((KnownLHS.isKnownNever(fcNegZero) ||
1523 KnownRHS.isKnownNever(fcPosNormal)) &&
1524 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcNegNormal)))
1525 Known.knownNot(fcNegZero);
1526
1527 // pow(-0.0, odd-negative) = -inf
1528 // pow(-inf, odd-positive) = -inf
1529 if ((KnownLHS.isKnownNever(fcNegZero) ||
1530 KnownRHS.isKnownNever(fcNegNormal)) &&
1531 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosNormal)))
1532 Known.knownNot(fcNegInf);
1533 }
1534
1535 return Known;
1536}
1537
1539 const KnownBits &ExponentKnownBits) {
1541 Known.propagateNonNaN(KnownSrc);
1542
1543 if (ExponentKnownBits.isZero()) {
1544 // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
1545 // return 1.0 or a NaN.
1546 if (KnownSrc.isKnownNever(fcSNan)) {
1547 Known.knownNot(~fcPosNormal);
1548 return Known;
1549 }
1550
1551 Known.knownNot(~(fcPosNormal | fcNan));
1552 return Known;
1553 }
1554
1555 // Given that exp is an integer, here are the
1556 // ways that powi can return a negative value:
1557 //
1558 // powi(x, exp) --> negative if exp is odd and x is negative.
1559 // powi(-0, exp) --> -inf if exp is negative odd.
1560 // powi(-0, exp) --> -0 if exp is positive odd.
1561 // powi(-inf, exp) --> -0 if exp is negative odd.
1562 // powi(-inf, exp) --> -inf if exp is positive odd.
1563 if (KnownSrc.isKnownNever(fcNegative) || ExponentKnownBits.isEven()) {
1564 Known.knownNot(fcNegative);
1565 } else if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1566 Known.knownNot(fcNegNormal | fcNegSubnormal);
1567 // See if we can also rule out -0.0 or -inf.
1568 // Here at least one of -0.0 or -inf is a possible base.
1569
1570 // We already know that ExponentKnownBits.isEven() is false here.
1571 const bool IsKnownNeverOddPositive = ExponentKnownBits.isNegative();
1572 const bool IsKnownNeverOddNegative = ExponentKnownBits.isNonNegative();
1573
1574 // powi(-0.0, odd-positive) = -0.0
1575 // powi(-inf, odd-negative) = -0.0
1576 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddPositive) &&
1577 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddNegative))
1578 Known.knownNot(fcNegZero);
1579
1580 // powi(-0.0, odd-negative) = -inf
1581 // powi(-inf, odd-positive) = -inf
1582 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddNegative) &&
1583 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddPositive))
1584 Known.knownNot(fcNegInf);
1585 }
1586
1587 // powi(x, exp) --> inf
1588 // when:
1589 // * powi(inf, exp), exp > 0
1590 // * powi(+/-0, exp), exp < 0
1591 // * powi(finite, exp), |exp| > 1
1592 // * powi(subnormal, -1)
1593 // TODO:
1594 // 1. This simple all or nothing approach. We can do better
1595 // and cover sign/parity and exp > 1 vs exp < -1 separately.
1596 // 2. powi(0/nan, exp), exp > 0 can be refinable
1597 // to fcNan | fcZero | fcPosNormal.
1598 {
1599 APInt MinExp = ExponentKnownBits.getSignedMinValue();
1600 APInt MaxExp = ExponentKnownBits.getSignedMaxValue();
1601
1602 // powi(inf, exp), exp > 0
1603 bool MayInfSrc =
1604 !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();
1605
1606 // powi(+/-0, exp), exp < 0
1607 bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();
1608
1609 // powi(finite, exp), |exp| > 1
1610 bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
1611 bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
1612 bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;
1613
1614 // powi(subnormal, -1)
1615 bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
1616 bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;
1617
1618 if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
1619 Known.knownNot(fcInf);
1620 }
1621
1622 return Known;
1623}
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 fma_impl(const KnownFPClass &KnownLHS, const KnownFPClass &KnownRHS)
static DenormalMode getConvertDenormalMode(DenormalMode DstMode, DenormalMode SrcMode)
static KnownFPClass fpconvert(const KnownFPClass &KnownSrc_, const fltSemantics &DstSem, const fltSemantics &SrcSem, DenormalMode Mode)
static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS, const KnownFPClass &KnownRHS, RoundingMode RM)
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:335
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:385
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 atan2(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode)
Report known values for atan2.
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 fma(const KnownFPClass &LHS, const KnownFPClass &RHS, const KnownFPClass &Addend, DenormalMode Mode)
Report known values for fma.
static LLVM_ABI KnownFPClass sin(const KnownFPClass &Src)
Report known values for sin.
static constexpr FPClassTest OrderedGreaterThanZeroMask
static constexpr FPClassTest OrderedLessThanZeroMask
static LLVM_ABI KnownFPClass trunc(const KnownFPClass &Src, DenormalMode Mode)
Propagate known class for trunc.
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 fadd_self(const KnownFPClass &Src, DenormalMode Mode)
Report known values for fadd x, x.
static LLVM_ABI KnownFPClass fma_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode)
Report known values for fma squared, squared, addend.
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 frem(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode)
Report known values for frem.
static LLVM_ABI KnownFPClass atan(const KnownFPClass &Src)
Report known values for atan.
static LLVM_ABI KnownFPClass ldexp(const KnownFPClass &Src, const APInt &ConstantRangeMin, const APInt &ConstantRangeMax, const fltSemantics &Flt, DenormalMode Mode)
Propagate known class for ldexp, assuming the exponent is known to be within [ConstantRangeMin,...
static LLVM_ABI KnownFPClass frexp_mant(const KnownFPClass &Src, DenormalMode Mode)
Propagate known class for mantissa component of frexp.
static LLVM_ABI KnownFPClass roundToIntegral(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode)
Propagate known class for rounding intrinsics (rint, nearbyint, round, roundeven).
static LLVM_ABI KnownFPClass fmuladd(const KnownFPClass &LHS, const KnownFPClass &RHS, const KnownFPClass &Addend, DenormalMode Mode)
Report known values for fmuladd.
static LLVM_ABI KnownFPClass ceil(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode)
Propagate known class for ceil.
static LLVM_ABI KnownFPClass fmuladd_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode)
Report known values for fmuladd squared, squared, addend.
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.
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 asin(const KnownFPClass &Src)
Report known values for asin.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
static LLVM_ABI KnownFPClass minMaxLike(const KnownFPClass &LHS, const KnownFPClass &RHS, MinMaxKind Kind, DenormalMode Mode)
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 floor(const KnownFPClass &Src, bool IsMultiUnitFPType, DenormalMode Mode)
Propagate known class for floor.
FPClassTest getKnownFPClasses() const
Floating-point classes the value could be one of.
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 fdiv_self(const KnownFPClass &Src, DenormalMode Mode)
Report known values for fdiv x, x.
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.
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 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)
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 fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode)
Report known values for fdiv.
static LLVM_ABI KnownFPClass canonicalize(const KnownFPClass &Src, DenormalMode Mode)
Apply the canonicalize intrinsic to this value.
static LLVM_ABI KnownFPClass fmul(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode)
Report known values for fmul.
static LLVM_ABI KnownFPClass pow(const KnownFPClass &LHS, const KnownFPClass &RHS)
Propagate known class for pow.
static LLVM_ABI KnownFPClass fsub(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode)
Report known values for fsub.
static LLVM_ABI KnownFPClass sinh(const KnownFPClass &Src)
Report known values for sinh.
static LLVM_ABI KnownFPClass fadd(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode)
Report known values for fadd.
bool isKnownNeverPosSubnormal() const
Return true if it's known this can never be a positive subnormal.
static KnownFPClass square(const KnownFPClass &Src, DenormalMode Mode)
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:1707
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.
RoundingMode
Rounding mode.
@ NearestTiesToEven
roundTiesToEven.
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