LLVM 24.0.0git
KnownFPClass.cpp
Go to the documentation of this file.
1//===- llvm/Support/KnownFPClass.h - Stores known fplcass -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a class for representing known fpclasses used by
10// computeKnownFPClass.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/APFloat.h"
18
19using namespace llvm;
20
22 : KnownFPClassesValue(C.classify()) {
23 setSignBit(C.isNegative());
24}
25
27 DenormalMode Mode) {
28 KnownFPClass Known = KnownSrc;
29 switch (Mode.Input) {
31 return Known;
33 if (KnownSrc.getKnownFPClasses() & fcPosSubnormal)
34 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
35 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
36 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
37 return Known;
39 if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
40 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
41 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
42 Known.setSignBit(std::nullopt);
43 }
44 return Known;
45 default:
46 if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
47 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
48 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
49 Known.setSignBit(std::nullopt);
50 }
51 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
52 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
53 return Known;
54 }
55
56 llvm_unreachable("covered switch over denormal mode");
57}
58
60 DenormalMode Mode) {
61 KnownFPClass Known = KnownSrc;
62 switch (Mode.Output) {
64 return Known;
66 if (KnownSrc.getKnownFPClasses() & fcPosSubnormal)
67 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
68 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
69 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
70 return Known;
72 if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
73 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
74 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
75 Known.setSignBit(std::nullopt);
76 }
77 return Known;
78 default:
79 if (KnownSrc.getKnownFPClasses() & fcSubnormal) {
80 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
81 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
82 Known.setSignBit(std::nullopt);
83 }
84 if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
85 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
86 return Known;
87 }
88
89 llvm_unreachable("covered switch over denormal mode");
90}
91
95
99
103
105 const KnownFPClass &KnownRHS_,
106 MinMaxKind Kind, DenormalMode Mode) {
107 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
108 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
109
111
112 Known.propagateNonNaN(KnownLHS, KnownRHS);
113
114 // The *num functions return the non-NaN operand if only one operand is NaN.
115 // FIXME: minnum/maxnum may return a NaN if either operand is a signaling NaN.
116 if ((KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN()) &&
117 (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
119 Known.knownNot(fcNan);
120
121 switch (Kind) {
122 case MinMaxKind::maxnum: {
123 if (KnownLHS.isKnownNeverNaN())
124 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses(),
125 /*OrderedZeroSign=*/false));
126 if (KnownRHS.isKnownNeverNaN())
127 Known.knownNot(orderedStrictlyLess(KnownRHS.getKnownFPClasses(),
128 /*OrderedZeroSign=*/false));
129 break;
130 }
131 case MinMaxKind::minnum: {
132 if (KnownLHS.isKnownNeverNaN())
134 /*OrderedZeroSign=*/false));
135 if (KnownRHS.isKnownNeverNaN())
137 /*OrderedZeroSign=*/false));
138 break;
139 }
141 if (KnownLHS.isKnownNeverNaN())
142 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses(),
143 /*OrderedZeroSign=*/true));
144 if (KnownRHS.isKnownNeverNaN())
145 Known.knownNot(orderedStrictlyLess(KnownRHS.getKnownFPClasses(),
146 /*OrderedZeroSign=*/true));
147 break;
148 }
150 if (KnownLHS.isKnownNeverNaN())
152 /*OrderedZeroSign=*/true));
153 if (KnownRHS.isKnownNeverNaN())
155 /*OrderedZeroSign=*/true));
156 break;
157 }
158 case MinMaxKind::maximum: {
159 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses(),
160 /*OrderedZeroSign=*/true) |
162 /*OrderedZeroSign=*/true));
163 break;
164 }
165 case MinMaxKind::minimum: {
167 /*OrderedZeroSign=*/true) |
169 /*OrderedZeroSign=*/true));
170 break;
171 }
172 }
173
174 // Remove impossible non-NaN classes.
175 FPClassTest PossibleClasses =
176 KnownLHS.getKnownFPClasses() | KnownRHS.getKnownFPClasses() | fcNan;
177 Known.knownNot(~PossibleClasses);
178
179 return applyOutputDenormalMode(Known, Mode);
180}
181
183 DenormalMode DenormMode) {
185
186 // Canonicalize may flush denormals to zero, so we have to consider the
187 // denormal mode to preserve known-not-0 knowledge.
188 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcZero | fcQNan);
189
190 // Stronger version of propagateNaN
191 // Canonicalize is guaranteed to quiet signaling nans.
192 if (KnownSrc.isKnownNeverNaN())
193 Known.knownNot(fcNan);
194 else
195 Known.knownNot(fcSNan);
196
197 // FIXME: Missing check of IEEE like types.
198
199 // If the parent function flushes denormals, the canonical output cannot be a
200 // denormal.
201 if (DenormMode == DenormalMode::getIEEE()) {
202 if (KnownSrc.isKnownNever(fcPosZero))
203 Known.knownNot(fcPosZero);
204 if (KnownSrc.isKnownNever(fcNegZero))
205 Known.knownNot(fcNegZero);
206 return Known;
207 }
208
209 if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
210 Known.knownNot(fcSubnormal);
211
212 if (DenormMode == DenormalMode::getPreserveSign()) {
213 if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
214 Known.knownNot(fcPosZero);
215 if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
216 Known.knownNot(fcNegZero);
217 return Known;
218 }
219
220 if (DenormMode.Input == DenormalMode::PositiveZero ||
221 (DenormMode.Output == DenormalMode::PositiveZero &&
222 DenormMode.Input == DenormalMode::IEEE)) {
223 // -0.0 is not a subnormal and should not be flushed.
224 if (KnownSrc.isKnownNever(fcNegZero))
225 Known.knownNot(fcNegZero);
226
227 if (KnownSrc.isKnownNever(fcPosZero | fcSubnormal))
228 Known.knownNot(fcPosZero);
229 }
230
231 return Known;
232}
233
235 const KnownBits &Bits) {
236 assert(FltSemantics.sizeInBits == Bits.getBitWidth() &&
237 "Bitcast operand has incorrect bit width");
239
240 // Conflicting known bits do not describe a concrete value. Return unknown.
241 if (Bits.hasConflict())
242 return Known;
243
244 // Return unknown for types we have not validated.
245 auto IsSupported = [](const fltSemantics &Semantics) {
246 switch (APFloat::SemanticsToEnum(Semantics)) {
253 return true;
254 default:
255 return false;
256 }
257 };
258 if (!IsSupported(FltSemantics))
259 return Known;
260
261 // Transfer information from the sign bit.
262 if (Bits.isNonNegative())
263 Known.signBitMustBeZero();
264 else if (Bits.isNegative())
265 Known.signBitMustBeOne();
266
267 switch (APFloatBase::SemanticsToEnum(FltSemantics)) {
273 const unsigned MantissaBits = FltSemantics.precision - 1;
274 const APInt ExponentMask = APInt::getBitsSet(
275 FltSemantics.sizeInBits, MantissaBits, FltSemantics.sizeInBits - 1);
276 const APInt MantissaMask =
277 APInt::getLowBitsSet(FltSemantics.sizeInBits, MantissaBits);
278
279 const bool ExponentKnownAllZeros =
280 (Bits.Zero & ExponentMask) == ExponentMask;
281 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
282 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
283 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
284
285 const bool MantissaKnownAllZeros =
286 (Bits.Zero & MantissaMask) == MantissaMask;
287 const bool MantissaKnownNotAllZeros = !(Bits.One & MantissaMask).isZero();
288
289 // Zero and subnormal require an exponent with all zero bits.
290 if (ExponentKnownNotAllZeros)
291 Known.knownNot(fcZero | fcSubnormal);
292
293 // Infinity and NaN require an exponent with all one bits.
294 if (ExponentKnownNotAllOnes)
295 Known.knownNot(fcInf | fcNan);
296
297 // Normal values have an exponent that is not all zeros or all ones.
298 if (ExponentKnownAllZeros || ExponentKnownAllOnes)
299 Known.knownNot(fcNormal);
300
301 // Zero and infinity require a mantissa with all zero bits.
302 if (MantissaKnownNotAllZeros)
303 Known.knownNot(fcZero | fcInf);
304
305 // Subnormal and NaN require a non-zero mantissa.
306 if (MantissaKnownAllZeros)
307 Known.knownNot(fcSubnormal | fcNan);
308
309 const bool QuietBitKnownSet = Bits.One[MantissaBits - 1];
310 const bool QuietBitKnownClear = Bits.Zero[MantissaBits - 1];
311
312 if (QuietBitKnownSet)
313 Known.knownNot(fcSNan);
314 else if (QuietBitKnownClear)
315 Known.knownNot(fcQNan);
316
317 break;
318 }
320 // Layout of the x87 floating point type:
321 // [0:62] fraction
322 // [63] explicit integer bit
323 // [64:78] exponent
324 // [79] sign bit
325 // APFloat treats the x87 pseudo encodings as documented in
326 // fltSemantics::hasExplicitIntegerBit.
327 constexpr unsigned BitWidth = 80;
328 constexpr unsigned FractionBits = 63;
329 constexpr unsigned IntegerBitIndex = FractionBits;
330 const APInt FractionMask = APInt::getLowBitsSet(BitWidth, FractionBits);
331 const APInt ExponentMask =
332 APInt::getBitsSet(BitWidth, FractionBits + 1, BitWidth - 1);
333
334 const bool ExponentKnownAllZeros =
335 (Bits.Zero & ExponentMask) == ExponentMask;
336 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
337 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
338 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
339 const bool FractionKnownAllZeros =
340 (Bits.Zero & FractionMask) == FractionMask;
341 const bool FractionKnownNotAllZeros = !(Bits.One & FractionMask).isZero();
342 const bool IntegerBitKnownSet = Bits.One[IntegerBitIndex];
343 const bool IntegerBitKnownClear = Bits.Zero[IntegerBitIndex];
344
345 // zero and subnormal require an exponent with all zero bits and a cleared
346 // integer bit.
347 if (ExponentKnownNotAllZeros || IntegerBitKnownSet)
348 Known.knownNot(fcZero | fcSubnormal);
349
350 // Zero requires a zero fraction.
351 if (FractionKnownNotAllZeros)
352 Known.knownNot(fcZero);
353
354 // Infinity requires an exponent with all one bits, a set integer bit, and
355 // a zero fraction.
356 if (ExponentKnownNotAllOnes || IntegerBitKnownClear ||
357 FractionKnownNotAllZeros)
358 Known.knownNot(fcInf);
359
360 // A normal x87 value has its integer bit set. A zero exponent with that
361 // bit set is the x87 pseudodenormal encoding, which APFloat treats as
362 // normal.
363 if (IntegerBitKnownClear || ExponentKnownAllOnes)
364 Known.knownNot(fcNormal);
365
366 // A subnormal has a nonzero fraction; NaNs are possible with a zero
367 // fraction through pseudoinfinity and unnormal encodings.
368 if (FractionKnownAllZeros)
369 Known.knownNot(fcSubnormal);
370
371 // We can rule out NaN if the value has all exponent bits set to zero, or
372 // if the value is a canonical normal or infinity.
373 if (ExponentKnownAllZeros ||
374 (IntegerBitKnownSet &&
375 (ExponentKnownNotAllOnes || FractionKnownAllZeros)))
376 Known.knownNot(fcNan);
377
378 const bool QuietBitKnownSet = Bits.One[FractionBits - 1];
379 const bool QuietBitKnownClear = Bits.Zero[FractionBits - 1];
380
381 if (QuietBitKnownSet)
382 Known.knownNot(fcSNan);
383 else if (QuietBitKnownClear)
384 Known.knownNot(fcQNan);
385
386 break;
387 }
388 default:
389 llvm_unreachable("unhandled supported type");
390 }
391
392 return Known;
393}
394
396 KnownBits Known(FltSemantics.sizeInBits);
397 const FPClassTest FPClasses = getKnownFPClasses();
398
399 // Return unknown if poison.
400 if (FPClasses == fcNone)
401 return Known;
402
403 // Return unknown for types we have not validated.
404 auto IsSupported = [](const fltSemantics &Semantics) {
405 switch (APFloat::SemanticsToEnum(Semantics)) {
412 return true;
413 default:
414 return false;
415 }
416 };
417 if (!IsSupported(FltSemantics))
418 return Known;
419
420 switch (APFloat::SemanticsToEnum(FltSemantics)) {
426 // For ieee types, we cannot deduce anything if the source could be normal.
427 if (FPClasses & fcNormal)
428 break;
429
430 Known.setAllConflict();
431
432 const unsigned BitWidth = FltSemantics.sizeInBits;
433 const unsigned MantissaBits = FltSemantics.precision - 1;
434 const unsigned ExponentBits = BitWidth - MantissaBits - 1;
435
436 APInt MantissaMask = APInt::getLowBitsSet(BitWidth, MantissaBits);
437 APInt ExponentMask =
438 APInt::getBitsSet(BitWidth, MantissaBits, MantissaBits + ExponentBits);
439
440 const unsigned QuietBitIndex = MantissaBits - 1;
441 APInt PayloadMask = MantissaMask;
442 PayloadMask.clearBit(QuietBitIndex);
443
444 if (FPClasses & fcNan) {
445 // Exponent bits cannot be zeros.
446 Known.Zero &= ~ExponentMask;
447 // No individual payload bit is known.
448 Known.Zero &= ~PayloadMask;
449 Known.One &= ~PayloadMask;
450
451 if (FPClasses & fcQNan)
452 Known.Zero.clearBit(QuietBitIndex);
453 if (FPClasses & fcSNan)
454 Known.One.clearBit(QuietBitIndex);
455 }
456 if (FPClasses & fcInf) {
457 // Exponent bits cannot be zeros.
458 Known.Zero &= ~ExponentMask;
459 // Mantissa bits cannot be ones.
460 Known.One &= ~MantissaMask;
461 }
462 if (FPClasses & fcSubnormal) {
463 // Exponent bits cannot be ones.
464 Known.One &= ~ExponentMask;
465 // Unknown mantissa.
466 Known.One &= ~MantissaMask;
467 Known.Zero &= ~MantissaMask;
468 }
469 if (FPClasses & fcZero) {
470 // Exponent bits cannot be ones.
471 Known.One &= ~ExponentMask;
472 // Mantissa cannot be ones.
473 Known.One &= ~MantissaMask;
474 }
475
476 break;
477 }
480 break;
481
482 Known.setAllConflict();
483
484 if (FPClasses & fcInf)
485 Known = Known.intersectWith(KnownBits::makeConstant(
486 APFloat::getInf(FltSemantics).bitcastToAPInt()));
487
488 if (FPClasses & fcZero)
489 Known = Known.intersectWith(
491
492 break;
493 }
494 default:
495 llvm_unreachable("unhandled supported semantics");
496 }
497
498 Known.Zero.clearSignBit();
499 Known.One.clearSignBit();
500 if (std::optional<bool> Sign = getSignBit()) {
501 if (*Sign)
502 Known.makeNegative();
503 else
504 Known.makeNonNegative();
505 }
506
507 return Known;
508}
509
510// Handle known sign bit and nan cases for fadd, fsub, and fma.
511static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
512 const KnownFPClass &KnownRHS, bool IsFMA) {
514
515 // Adding positive and negative infinity produces NaN, but only if both
516 // opposite-sign infinity combinations are possible.
517 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
518 (KnownLHS.isKnownNever(fcPosInf) || KnownRHS.isKnownNever(fcNegInf)) &&
519 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosInf)))
520 Known.knownNot(fcNan);
521
522 if (KnownLHS.cannotBeOrderedLessThanZero() &&
523 KnownRHS.cannotBeOrderedLessThanZero()) {
525
526 // This can't underflow if one of the operands is known normal.
527 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
529 Known.knownNot(fcZero | fcPosSubnormal);
530 }
531
532 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
535
536 // This can't underflow if one of the operands is known normal.
537 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
539 Known.knownNot(fcZero | fcNegSubnormal);
540 }
541
542 if (!IsFMA) {
543 // (fadd x, +0.0) is guaranteed to return +0.0, not -0.0.
544 if (KnownLHS.isKnownNever(fcNegZero) || KnownRHS.isKnownNever(fcNegZero))
545 Known.knownNot(fcNegZero);
546
547 Known.propagateNonSNaN(KnownLHS, KnownRHS);
548 }
549
550 return Known;
551}
552
554 const KnownFPClass &KnownRHS_,
555 DenormalMode Mode) {
556 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
557 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
558
559 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, /*IsFMA=*/false);
560
561 return applyOutputDenormalMode(Known, Mode);
562}
563
565 DenormalMode Mode) {
566 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
567
568 KnownFPClass Known = fadd_impl(KnownSrc, KnownSrc, /*IsFMA=*/false);
569
570 if (KnownSrc.isKnownNever(fcPosSubnormal))
571 Known.knownNot(fcPosSubnormal);
572 if (KnownSrc.isKnownNever(fcNegSubnormal))
573 Known.knownNot(fcNegSubnormal);
574
575 // Doubling 0 will give the same 0.
576 if (KnownSrc.isKnownNever(fcPosZero))
577 Known.knownNot(fcPosZero);
578
579 return applyOutputDenormalMode(Known, Mode);
580}
581
583 const KnownFPClass &KnownRHS_,
584 DenormalMode Mode) {
585 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
586 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
587
588 // fsub(x, y) == fadd(x, -y) as long as we negate after subnormals are
589 // flushed.
590 KnownRHS.fneg();
591
592 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, /*IsFMA=*/false);
593
594 return applyOutputDenormalMode(Known, Mode);
595}
596
598 const KnownFPClass &KnownRHS_,
599 DenormalMode Mode) {
600 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
601 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
602
604
605 Known.propagateNonSNaN(KnownLHS, KnownRHS);
606
607 // +X * +Y or -X * -Y => +Q
608 // +X * -Y or -X * +Y => -Q
609 if ((KnownLHS.isKnownNever(fcNegative) &&
610 KnownRHS.isKnownNever(fcNegative)) ||
611 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
612 Known.knownNot(fcNegative);
613 if ((KnownLHS.isKnownNever(fcPositive) &&
614 KnownRHS.isKnownNever(fcNegative)) ||
615 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
616 Known.knownNot(fcPositive);
617
618 // Inf * Y => Inf or NaN
619 if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
620 KnownRHS.isKnownAlways(fcInf | fcNan))
621 Known.knownNot(fcNormal | fcSubnormal | fcZero);
622
623 // 0 * Y => 0 or NaN
624 if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
625 KnownLHS.isKnownAlways(fcZero | fcNan))
626 Known.knownNot(fcNormal | fcSubnormal | fcInf);
627
628 // 0 * +/-inf => NaN
629 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
630 (KnownRHS.isKnownNeverInfinity() || KnownLHS.isKnownNeverZero()) &&
631 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverZero()))
632 Known.knownNot(fcNan);
633
634 return applyOutputDenormalMode(Known, Mode);
635}
636
637// TODO: This generalizes to known ranges
639 const APFloat &CRHS, DenormalMode Mode) {
640 // Match denormal scaling pattern, similar to the case in ldexp. If the
641 // constant's exponent is sufficiently large, the result cannot be subnormal.
642
643 const fltSemantics &Flt = CRHS.getSemantics();
644 unsigned Precision = APFloat::semanticsPrecision(Flt);
645 const int MantissaBits = Precision - 1;
646
647 int MinKnownExponent = ilogb(CRHS);
648 bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);
649
650 KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
651 if (CannotBeSubnormal)
652 Known.knownNot(fcSubnormal);
653
654 // Multiply of values <= 1 cannot introduce overflow.
655 if (KnownLHS.isKnownNever(fcInf)) {
656 if (MinKnownExponent < 0)
657 Known.knownNot(fcInf);
658 else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
659 Flt)) == APFloat::cmpEqual)
660 Known.knownNot(fcInf);
661 }
662
663 return Known;
664}
665
667 const KnownFPClass &KnownRHS_,
668 DenormalMode Mode) {
669 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
670 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
671
673
674 Known.propagateNonSNaN(KnownLHS, KnownRHS);
675
676 // Only 0/0, Inf/Inf produce NaN.
677 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
678 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
679 (KnownLHS.isKnownNeverZero() || KnownRHS.isKnownNeverZero())) {
680 Known.knownNot(fcNan);
681 }
682
683 // X / -0.0 => -Inf (or NaN)
684 // +X / +Y or -X / -Y => +Q
685 // +X / -Y or -X / +Y => -Q
686 if ((KnownLHS.isKnownNever(fcNegative) &&
687 KnownRHS.isKnownNever(fcNegative)) ||
688 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
689 Known.knownNot(fcNegative);
690 if ((KnownLHS.isKnownNever(fcPositive) &&
691 KnownRHS.isKnownNever(fcNegative)) ||
692 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
693 Known.knownNot(fcPositive);
694
695 // Normal and subnormal results require two non-zero finite operands.
696 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
700 Known.knownNot(fcNegNormal | fcNegSubnormal);
701 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
705 Known.knownNot(fcPosNormal | fcPosSubnormal);
706
707 // 0 / X => 0 or NaN
708 if (KnownLHS.isKnownAlways(fcZero))
709 Known.knownNot(fcSubnormal | fcNormal | fcInf);
710
711 // X / 0 => NaN or Inf
712 if (KnownRHS.isKnownAlways(fcZero))
713 Known.knownNot(fcFinite);
714
715 return applyOutputDenormalMode(Known, Mode);
716}
717
719 DenormalMode Mode) {
720 // X / X is always exactly 1.0 or a NaN.
722
723 Known.propagateNonSNaN(KnownSrc);
724
725 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
726 Known.knownNot(fcNan);
727
728 return Known;
729}
730
732 const KnownFPClass &KnownRHS,
733 DenormalMode Mode) {
735
736 // We are assuming that frem(x, Inf) is already handled elsewhere.
737
738 Known.knownNot(fcInf);
739
740 Known.propagateNonSNaN(KnownLHS, KnownRHS);
741
742 // frem(Inf, x) and frem(x, 0) produce NaN.
743 if (KnownLHS.isKnownNeverInfOrNaN() && KnownRHS.isKnownNeverNaN() &&
744 KnownRHS.isKnownNeverLogicalZero(Mode)) {
745 Known.knownNot(fcNan);
746 }
747
748 // The sign for frem is the same as the first operand.
750 Known.knownNot(fcPosNormal | fcPosSubnormal);
752 Known.knownNot(fcNegNormal | fcNegSubnormal);
753
754 // A negative zero result requires a negative finite first operand.
755 if (KnownLHS.isKnownNever(fcNegFinite))
756 Known.knownNot(fcNegZero);
757
758 // A positive zero result can additionally come from a negative finite
759 // result being flushed to positive zero.
760 if (KnownLHS.isKnownNever(fcPosFinite) &&
761 KnownLHS.isKnownNeverLogicalPosZero(Mode) &&
762 (!Mode.outputsMayBePositiveZero() ||
764 Known.knownNot(fcPosZero);
765
766 return Known;
767}
768
770 DenormalMode Mode) {
771 // X % X is always exactly [+-]0.0 or a NaN.
773
774 Known.propagateNonSNaN(KnownSrc);
775
776 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
777 Known.knownNot(fcNan);
778
779 // The sign of a zero result is the sign of the finite non-zero input.
780 // We do not have to worry about subnormal values flushing to zero, since
781 // frem(+-0.0, +-0.0) = NaN.
783 Known.knownNot(fcPosZero);
785 Known.knownNot(fcNegZero);
786
787 return Known;
788}
789
791 const KnownFPClass &KnownRHS,
792 const KnownFPClass &KnownAddend,
793 DenormalMode Mode) {
794 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, Mode);
795
796 // FMA differs from the base fmul + fadd handling only in the treatment of -0
797 // results.
798 //
799 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
800 // unlike for a separate fadd.
801 KnownFPClass Known = fadd_impl(Mul, KnownAddend, /*IsFMA=*/true);
802
803 // propagateNonSNaN for 3 arguments.
804 if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
805 KnownAddend.isKnownNever(fcSNan))
806 Known.knownNot(fcSNan);
807
808 return Known;
809}
810
812 const KnownFPClass &KnownRHS,
813 const KnownFPClass &KnownAddend,
814 DenormalMode Mode) {
815 // fmuladd can lower to either fma(x, y, z) or fadd(fmul(x, y), z). Compute
816 // the intersection of both possibilities.
817 KnownFPClass FMA = fma(KnownLHS, KnownRHS, KnownAddend, Mode);
818 KnownFPClass MulAdd = fadd(fmul(KnownLHS, KnownRHS, Mode), KnownAddend, Mode);
819 return FMA.intersectWith(MulAdd);
820}
821
823 const KnownFPClass &KnownAddend,
824 DenormalMode Mode) {
825 KnownFPClass Squared = square(KnownSquared, Mode);
826 KnownFPClass Known = fadd_impl(Squared, KnownAddend, /*IsFMA=*/true);
827
828 // Since we know the squared input must be positive, the add of opposite sign
829 // infinities nan hazard only applies for negative inf.
830 //
831 // TODO: Alternatively to proving addend is not -inf, we could know Squared is
832 // not pinf. Other than the degenerate always-subnormal input case, we can't
833 // prove that without a known range.
834 if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
835 Known.knownNot(fcNan);
836
837 Known.propagateNonSNaN(KnownSquared, KnownAddend);
838
839 return Known;
840}
841
843 const KnownFPClass &KnownAddend,
844 DenormalMode Mode) {
845 KnownFPClass FMA = fma_square(KnownSquared, KnownAddend, Mode);
846 KnownFPClass MulAdd = fadd(square(KnownSquared, Mode), KnownAddend, Mode);
847 return FMA.intersectWith(MulAdd);
848}
849
852 Known.knownNot(fcNegative);
853
854 Known.propagateNonNaN(KnownSrc);
855
856 // The following deductions assume that exp10(-1.0) = +0.1 and
857 // exp10(+1.0) = +10.0 are both finite normal values.
858
859 // Zero can only be produced if x < -1.0.
860 if (KnownSrc.isKnownNever(fcNegNormal | fcNegInf))
861 Known.knownNot(fcPosZero);
862
863 // Subnormals can only be produced if x < -1.0 and x is finite.
864 if (KnownSrc.isKnownNever(fcNegNormal))
865 Known.knownNot(fcPosSubnormal);
866
867 // Infinity can only be produced if x > +1.0.
868 if (KnownSrc.isKnownNever(fcPosNormal | fcPosInf))
869 Known.knownNot(fcPosInf);
870
871 return Known;
872}
873
875 bool IsMultiUnitFPType) {
877
878 // PPCDoubleDouble can represent the exact value of 1.0 + subnormal, and
879 // log(1.0 + subnormal) = subnormal.
880 if (!IsMultiUnitFPType)
881 Known.knownNot(fcNegZero | fcSubnormal);
882
883 Known.propagateNonSNaN(KnownSrc);
884
885 if (KnownSrc.isKnownNeverPosInfinity())
886 Known.knownNot(fcPosInf);
887
888 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
889 Known.knownNot(fcNan);
890
891 if (KnownSrc.isKnownNeverLogicalZero(Mode))
892 Known.knownNot(fcNegInf);
893
894 return Known;
895}
896
898 DenormalMode Mode) {
900 Known.knownNot(fcPosSubnormal);
901
902 if (KnownSrc.isKnownNeverPosInfinity())
903 Known.knownNot(fcPosInf);
904
905 Known.propagateNonSNaN(KnownSrc);
906
907 // Any negative value besides -0 returns a nan.
908 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
909 Known.knownNot(fcNan);
910
911 // The only negative value that can be returned is -0 for -0 inputs.
913
914 // If the input denormal mode could be PreserveSign, a negative
915 // subnormal input could produce a negative zero output.
916 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
917 Known.knownNot(fcNegZero);
918
919 return Known;
920}
921
924
925 Known.propagateNonSNaN(KnownSrc);
926
927 // Return NaN on infinite inputs.
928 Known.knownNot(fcInf);
929 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
930 Known.knownNot(fcNan);
931
932 return Known;
933}
934
936 return sin(KnownSrc);
937}
938
941
942 // tan never returns Inf (tan(+-Inf) = NaN; tan(finite) = finite).
943 Known.knownNot(fcInf);
944
945 Known.propagateNonSNaN(KnownSrc);
946
947 // NaN propagates. tan(+-Inf) is NaN.
948 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
949 Known.knownNot(fcNan);
950
951 return Known;
952}
953
956
957 // sinh is sign-preserving: sinh(x) < 0 iff x < 0.
958 if (KnownSrc.isKnownNever(fcNegative))
959 Known.knownNot(fcNegative);
960
961 // A nonzero positive result requires a nonzero positive input.
962 // Zero remains possible: sinh(+/-0.0) = +/-0.0, and flushing a subnormal
963 // may produce +0.0.
966
967 Known.propagateNonNaN(KnownSrc);
968
969 return Known;
970}
971
974
975 // cosh(x) >= 1 for all real x; cosh(+-Inf) = +Inf. Never negative,
976 // zero, or subnormal.
977 Known.knownNot(fcNegative | fcZero | fcSubnormal);
978
979 Known.propagateNonNaN(KnownSrc);
980
981 return Known;
982}
983
986
987 // tanh is bounded to (-1, 1), never Inf.
988 Known.knownNot(fcInf);
989
990 // tanh is sign-preserving: tanh(x) < 0 iff x < 0.
992 Known.knownNot(fcNegSubnormal | fcNegNormal);
993
994 // -0.0 is preserved: tanh(-0.0) = -0.0.
995 if (KnownSrc.isKnownNeverNegZero())
996 Known.knownNot(fcNegZero);
997 }
998
999 // Likewise, tanh(x) > 0 iff x > 0. Zero is not ruled out: tanh(+-0.0) =
1000 // +-0.0, and a flushed subnormal may become +0.0.
1002 Known.knownNot(fcPosSubnormal | fcPosNormal);
1003
1004 Known.propagateNonNaN(KnownSrc);
1005
1006 return Known;
1007}
1008
1011
1012 // asin is bounded to [-pi/2, pi/2], never Inf.
1013 Known.knownNot(fcInf);
1014
1015 Known.propagateNonSNaN(KnownSrc);
1016
1017 // asin is sign-preserving for finite arguments.
1018 if (KnownSrc.isKnownNever(fcNegFinite))
1019 Known.knownNot(fcNegFinite);
1020
1021 if (KnownSrc.isKnownNever(fcPosSubnormal | fcPosNormal))
1022 Known.knownNot(fcPosSubnormal | fcPosNormal);
1023
1024 // NaN propagates. asin(x) is also NaN for |x| > 1, so we cannot rule
1025 // out NaN without knowing the source is in [-1, 1].
1026 return Known;
1027}
1028
1031
1032 // acos(x) is bounded to [0, pi] for -1 <= x <= 1, and is never negative,
1033 // infinite, or subnormal. The smallest non-zero value occurs when x is
1034 // close to 1.0, where acos(x) can be approximated by sqrt(2 * (1 - x)).
1035 // Since sqrt cannot produce a subnormal result, we can conclude that
1036 // acos(x) will also never produce a subnormal result.
1037 Known.knownNot(fcNegative | fcInf | fcSubnormal);
1038
1039 // acos(x) == +0.0 iff x == +1.0
1040 if (KnownSrc.isKnownNever(fcPosNormal))
1041 Known.knownNot(fcZero);
1042
1043 Known.propagateNonSNaN(KnownSrc);
1044
1045 // NaN propagates. acos(x) is also NaN for |x| > 1, so we cannot rule
1046 // out NaN without knowing the source is in [-1, 1].
1047 return Known;
1048}
1049
1052
1053 // atan is bounded to (-pi/2, pi/2), never Inf. atan(+-Inf) = +-pi/2 (finite).
1054 Known.knownNot(fcInf);
1055
1056 // Ruling out Subnormal/Normal from the result requires the
1057 // input to never be finite-nonzero and never inf, since
1058 // atan(+-inf) = +-pi/2
1060 Known.knownNot(fcNegSubnormal | fcNegNormal);
1061
1063 Known.knownNot(fcPosSubnormal | fcPosNormal);
1064
1065 // atan(-0.0) = -0.0. Negative finite inputs may also produce -0.0
1066 // if the result rounds to a negative subnormal that is flushed to zero.
1068 Known.knownNot(fcNegZero);
1069
1070 Known.propagateNonNaN(KnownSrc);
1071
1072 return Known;
1073}
1074
1076 const KnownFPClass &KnownX_,
1077 DenormalMode Mode) {
1078 KnownFPClass KnownY = applyInputDenormalMode(KnownY_, Mode);
1079 KnownFPClass KnownX = applyInputDenormalMode(KnownX_, Mode);
1081
1082 // Even though these deductions are correct, we are ignoring the following
1083 // potentially erroneous cases:
1084 // * atan2(y, inf) is not subnormal
1085 // * atan2(inf, x) is not zero or subnormal
1086
1087 // atan2 result is in (-pi, pi], never Inf.
1088 Known.knownNot(fcInf);
1089
1090 Known.propagateNonNaN(KnownY, KnownX);
1091
1092 // If x <= -0.0, then |atan2(y, x)| >= pi/2
1093 if (KnownX.isKnownNever(fcPositive))
1094 Known.knownNot(fcZero | fcSubnormal);
1095
1096 // If y >= +0.0, then atan2(y, x) >= +0.0
1097 if (KnownY.isKnownNever(fcNegative))
1098 Known.knownNot(fcNegative);
1099
1100 // If y <= -0.0, then atan2(y, x) <= -0.0
1101 if (KnownY.isKnownNever(fcPositive))
1102 Known.knownNot(fcPositive);
1103
1104 return applyOutputDenormalMode(Known, Mode);
1105}
1106
1108 const fltSemantics &DstTy,
1109 const fltSemantics &SrcTy) {
1110 // Infinity, nan and zero propagate from source.
1111 KnownFPClass Known = KnownSrc;
1112
1113 // All subnormal inputs should be in the normal range in the result type.
1114 if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
1115 if (Known.getKnownFPClasses() & fcPosSubnormal)
1116 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosNormal);
1117 if (Known.getKnownFPClasses() & fcNegSubnormal)
1118 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegNormal);
1119 Known.knownNot(fcSubnormal);
1120 }
1121
1122 // Sign bit of a nan isn't guaranteed.
1123 if (!Known.isKnownNeverNaN())
1124 Known.setSignBit(std::nullopt);
1125
1126 return Known;
1127}
1128
1131
1132 // Sign should be preserved
1133 // TODO: Handle cannot be ordered greater than zero
1134 if (KnownSrc.cannotBeOrderedLessThanZero())
1136
1137 Known.propagateNonNaN(KnownSrc);
1138
1139 // Infinity needs a range check.
1140 return Known;
1141}
1142
1144 bool MayBeMultiUnitFPType,
1145 DenormalMode Mode) {
1147
1148 // Integer results cannot be subnormal.
1149 Known.knownNot(fcSubnormal);
1150
1151 Known.propagateNonNaN(KnownSrc);
1152
1153 // Pass through infinities, except PPC_FP128 is a special case for intrinsics.
1154 if (!MayBeMultiUnitFPType) {
1155 if (KnownSrc.isKnownNeverPosInfinity())
1156 Known.knownNot(fcPosInf);
1157 if (KnownSrc.isKnownNeverNegInfinity())
1158 Known.knownNot(fcNegInf);
1159 }
1160
1161 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1162 Known.knownNot(fcPosNormal);
1163
1164 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1165 Known.knownNot(fcNegNormal);
1166
1167 // Negative round ups towards zero produce negative zero.
1168 if (KnownSrc.isKnownNever(fcNegFinite))
1169 Known.knownNot(fcNegZero);
1170
1171 // Negative subnormals may flush to positive zero.
1172 if (KnownSrc.isKnownNever(fcPosFinite) &&
1173 (KnownSrc.isKnownNever(fcNegSubnormal) ||
1174 !Mode.inputsMayBePositiveZero()))
1175 Known.knownNot(fcPosZero);
1176
1177 return Known;
1178}
1179
1181 DenormalMode Mode) {
1183 /*MayBeMultiUnitFPType=*/true, Mode);
1184
1185 if (KnownSrc.isKnownNeverPosInfinity())
1186 Known.knownNot(fcPosInf);
1187 if (KnownSrc.isKnownNeverNegInfinity())
1188 Known.knownNot(fcNegInf);
1189
1190 return Known;
1191}
1192
1194 bool IsMultiUnitFPType, DenormalMode Mode) {
1195 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1196
1197 // Applicable for multi-unit floating point types.
1198 if (KnownSrc.isKnownNeverPosInfinity())
1199 Known.knownNot(fcPosInf);
1200
1201 return Known;
1202}
1203
1205 bool IsMultiUnitFPType, DenormalMode Mode) {
1206 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1207
1208 // Applicable for multi-unit floating point types.
1209 if (KnownSrc.isKnownNeverNegInfinity())
1210 Known.knownNot(fcNegInf);
1211
1212 return Known;
1213}
1214
1216 DenormalMode Mode) {
1218
1219 Known.knownNot(fcSubnormal);
1220
1221 Known.propagateNonNaN(KnownSrc);
1222
1223 if (KnownSrc.isKnownNeverPosInfinity())
1224 Known.knownNot(fcPosInf);
1225
1226 if (KnownSrc.isKnownNeverNegInfinity())
1227 Known.knownNot(fcNegInf);
1228
1229 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
1230 Known.knownNot(fcPosZero);
1231
1232 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
1233 Known.knownNot(fcNegZero);
1234
1235 // TODO: These deductions can be improved if subnormal inputs are guaranteed
1236 // to be flushed to zero.
1237 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1238 Known.knownNot(fcPosNormal);
1239
1240 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1241 Known.knownNot(fcNegNormal);
1242
1243 return Known;
1244}
1245
1247 const APInt &ConstantRangeExpMin,
1248 const APInt &ConstantRangeExpMax,
1249 const fltSemantics &Flt, DenormalMode Mode) {
1251
1252 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
1253
1254 if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
1255 // ldexp(x, 0) -> x
1256 // Here we make sure to properly propagate sNaN and denormals.
1257 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcNan);
1258 Known.propagateNonNaN(KnownSrc);
1259 return applyOutputDenormalMode(Known, Mode);
1260 }
1261
1262 Known.propagateNonNaN(KnownSrc);
1263
1264 // Sign is preserved, but underflows may produce zeroes.
1265 if (KnownSrc.isKnownNever(fcNegative))
1266 Known.knownNot(fcNegative);
1267 else if (KnownSrc.cannotBeOrderedLessThanZero())
1269
1270 if (KnownSrc.isKnownNever(fcPositive))
1271 Known.knownNot(fcPositive);
1272 else if (KnownSrc.cannotBeOrderedGreaterThanZero())
1274
1275 // TODO: determine when it is safe to rule out subnormal for ppcf128.
1276 if (&Flt != &APFloat::PPCDoubleDouble()) {
1277 unsigned Precision = APFloat::semanticsPrecision(Flt);
1278 const int MantissaBits = Precision - 1;
1279 if (ConstantRangeExpMin.sge(MantissaBits))
1280 Known.knownNot(fcSubnormal);
1281 }
1282
1283 if (ConstantRangeExpMax.isNonPositive()) {
1284 // If we know the power is <= 0, can't introduce inf
1285 if (KnownSrc.isKnownNeverPosInfinity())
1286 Known.knownNot(fcPosInf);
1287 if (KnownSrc.isKnownNeverNegInfinity())
1288 Known.knownNot(fcNegInf);
1289 } else if (ConstantRangeExpMin.isNonNegative()) {
1290 // If we know the power is >= 0, can't introduce subnormal or zero
1291 if (KnownSrc.isKnownNeverPosSubnormal())
1292 Known.knownNot(fcPosSubnormal);
1293 if (KnownSrc.isKnownNeverNegSubnormal())
1294 Known.knownNot(fcNegSubnormal);
1295 if (KnownSrc.isKnownNeverPosZero())
1296 Known.knownNot(fcPosZero);
1297 if (KnownSrc.isKnownNeverNegZero())
1298 Known.knownNot(fcNegZero);
1299 }
1300
1301 return applyOutputDenormalMode(Known, Mode);
1302}
1303
1305 const KnownBits &ExpBits,
1306 const fltSemantics &Flt, DenormalMode Mode) {
1307 return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
1308 ExpBits.getSignedMaxValue(), Flt, Mode);
1309}
1310
1312 const KnownFPClass &KnownRHS) {
1314
1315 Known.propagateNonSNaN(KnownLHS, KnownRHS);
1316
1317 // pow may return NaN if one of the arguments is NaN. NaN may be produced from
1318 // a non-zero-finite-negative base and a non-integer exponent.
1319 if (KnownLHS.isKnownNever(fcNan | fcNegNormal | fcNegSubnormal) &&
1320 KnownRHS.isKnownNeverNaN())
1321 Known.knownNot(fcNan);
1322
1323 // We could rule out negative and subnormal results when exponent is known to
1324 // never be a normal value, but having either argument being known to never be
1325 // normal is unlikely and not worth considering.
1326
1327 // Only a negative base raised to an odd power returns a negative value.
1328 if (KnownLHS.isKnownNever(fcNegative)) {
1329 Known.knownNot(fcNegative);
1330 } else if (KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1331 Known.knownNot(fcNegNormal | fcNegSubnormal);
1332 // See if we can also rule out -0.0 or -inf.
1333 // Here at least one of -0.0 or -inf is a possible base.
1334
1335 // pow(-0.0, odd-positive) = -0.0
1336 // pow(-inf, odd-negative) = -0.0
1337 if ((KnownLHS.isKnownNever(fcNegZero) ||
1338 KnownRHS.isKnownNever(fcPosNormal)) &&
1339 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcNegNormal)))
1340 Known.knownNot(fcNegZero);
1341
1342 // pow(-0.0, odd-negative) = -inf
1343 // pow(-inf, odd-positive) = -inf
1344 if ((KnownLHS.isKnownNever(fcNegZero) ||
1345 KnownRHS.isKnownNever(fcNegNormal)) &&
1346 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosNormal)))
1347 Known.knownNot(fcNegInf);
1348 }
1349
1350 return Known;
1351}
1352
1354 const KnownBits &ExponentKnownBits) {
1356 Known.propagateNonNaN(KnownSrc);
1357
1358 if (ExponentKnownBits.isZero()) {
1359 // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
1360 // return 1.0 or a NaN.
1361 if (KnownSrc.isKnownNever(fcSNan)) {
1362 Known.knownNot(~fcPosNormal);
1363 return Known;
1364 }
1365
1366 Known.knownNot(~(fcPosNormal | fcNan));
1367 return Known;
1368 }
1369
1370 // Given that exp is an integer, here are the
1371 // ways that powi can return a negative value:
1372 //
1373 // powi(x, exp) --> negative if exp is odd and x is negative.
1374 // powi(-0, exp) --> -inf if exp is negative odd.
1375 // powi(-0, exp) --> -0 if exp is positive odd.
1376 // powi(-inf, exp) --> -0 if exp is negative odd.
1377 // powi(-inf, exp) --> -inf if exp is positive odd.
1378 if (KnownSrc.isKnownNever(fcNegative) || ExponentKnownBits.isEven()) {
1379 Known.knownNot(fcNegative);
1380 } else if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1381 Known.knownNot(fcNegNormal | fcNegSubnormal);
1382 // See if we can also rule out -0.0 or -inf.
1383 // Here at least one of -0.0 or -inf is a possible base.
1384
1385 // We already know that ExponentKnownBits.isEven() is false here.
1386 const bool IsKnownNeverOddPositive = ExponentKnownBits.isNegative();
1387 const bool IsKnownNeverOddNegative = ExponentKnownBits.isNonNegative();
1388
1389 // powi(-0.0, odd-positive) = -0.0
1390 // powi(-inf, odd-negative) = -0.0
1391 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddPositive) &&
1392 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddNegative))
1393 Known.knownNot(fcNegZero);
1394
1395 // powi(-0.0, odd-negative) = -inf
1396 // powi(-inf, odd-positive) = -inf
1397 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddNegative) &&
1398 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddPositive))
1399 Known.knownNot(fcNegInf);
1400 }
1401
1402 // powi(x, exp) --> inf
1403 // when:
1404 // * powi(inf, exp), exp > 0
1405 // * powi(+/-0, exp), exp < 0
1406 // * powi(finite, exp), |exp| > 1
1407 // * powi(subnormal, -1)
1408 // TODO:
1409 // 1. This simple all or nothing approach. We can do better
1410 // and cover sign/parity and exp > 1 vs exp < -1 separately.
1411 // 2. powi(0/nan, exp), exp > 0 can be refinable
1412 // to fcNan | fcZero | fcPosNormal.
1413 {
1414 APInt MinExp = ExponentKnownBits.getSignedMinValue();
1415 APInt MaxExp = ExponentKnownBits.getSignedMaxValue();
1416
1417 // powi(inf, exp), exp > 0
1418 bool MayInfSrc =
1419 !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();
1420
1421 // powi(+/-0, exp), exp < 0
1422 bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();
1423
1424 // powi(finite, exp), |exp| > 1
1425 bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
1426 bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
1427 bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;
1428
1429 // powi(subnormal, -1)
1430 bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
1431 bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;
1432
1433 if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
1434 Known.knownNot(fcInf);
1435 }
1436
1437 return Known;
1438}
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 bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition Lint.cpp:540
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
#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 getIEEE()
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
Definition KnownBits.h:315
bool isNonNegative() const
Returns true if this value is known to be non-negative.
Definition KnownBits.h:106
bool isZero() const
Returns true if value is all zero.
Definition KnownBits.h:78
APInt getSignedMaxValue() const
Return the maximal signed value possible given these KnownBits.
Definition KnownBits.h:152
bool isEven() const
Return if the value is known even (the low bit is 0).
Definition KnownBits.h:162
bool isNegative() const
Returns true if this value is known to be negative.
Definition KnownBits.h:103
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
Definition KnownBits.h:136
bool isKnownNeverInfOrNaN() const
Return true if it's known this can never be an infinity or nan.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
KnownFPClass(FPClassTest Known=fcAllFlags, std::optional< bool > Sign={})
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
FPClassTest KnownFPClassesValue
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.
bool isKnownNeverZero() const
Return true if it's known this can never be a zero.
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.
bool isKnownAlways(FPClassTest Mask) const
static LLVM_ABI KnownFPClass canonicalize(const KnownFPClass &Src, DenormalMode DenormMode=DenormalMode::getDynamic())
Apply the canonicalize intrinsic to this value.
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a zero.
static LLVM_ABI KnownFPClass 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.
static LLVM_ABI KnownFPClass cos(const KnownFPClass &Src)
Report known values for cos.
static LLVM_ABI KnownFPClass cosh(const KnownFPClass &Src)
Report known values for cosh.
static LLVM_ABI KnownFPClass minMaxLike(const KnownFPClass &LHS, const KnownFPClass &RHS, MinMaxKind Kind, DenormalMode DenormMode=DenormalMode::getDynamic())
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.
bool isKnownNeverPosZero() const
Return true if it's known this can never be a literal positive zero.
static LLVM_ABI KnownFPClass exp(const KnownFPClass &Src)
Report known values for exp, exp2 and exp10.
static LLVM_ABI KnownFPClass frexp_mant(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for mantissa component of frexp.
static LLVM_ABI KnownFPClass asin(const KnownFPClass &Src)
Report known values for asin.
bool isKnownNeverNaN() const
Return true if it's known this can never be a nan.
bool isKnownNever(FPClassTest Mask) const
Return true if it's known this can never be one of the mask entries.
std::optional< bool > getSignBit() const
std::nullopt if the sign bit is unknown, true if the sign bit is definitely set or false if the sign ...
static LLVM_ABI KnownFPClass fpext(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy)
Propagate known class for fpext.
FPClassTest getKnownFPClasses() const
Floating-point classes the value could be one of.
bool isKnownNeverNegZero() const
Return true if it's known this can never be a negative zero.
static LLVM_ABI KnownFPClass 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.
static LLVM_ABI KnownFPClass fptrunc(const KnownFPClass &KnownSrc)
Propagate known class for fptrunc.
bool cannotBeOrderedLessThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never less than -...
static LLVM_ABI KnownFPClass sqrt(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for sqrt.
LLVM_ABI bool isKnownNeverLogicalPosZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a positive zero.
bool isKnownNeverPosInfinity() const
Return true if it's known this can never be +infinity.
static LLVM_ABI KnownFPClass fadd(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd.
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,...
void setSignBit(std::optional< bool > Sign)
static LLVM_ABI KnownFPClass sinh(const KnownFPClass &Src)
Report known values for sinh.
bool isKnownNeverPosSubnormal() const
Return true if it's known this can never be a positive subnormal.
static LLVM_ABI KnownFPClass tanh(const KnownFPClass &Src)
Report known values for tanh.
unsigned int sizeInBits
Definition APFloat.h:1037
unsigned int precision
Definition APFloat.h:1034