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 &RHS_, MinMaxKind Kind,
106 DenormalMode Mode) {
107 KnownFPClass KnownLHS = LHS_;
108 KnownFPClass KnownRHS = RHS_;
109
110 bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
111 KnownFPClass Known = KnownLHS | KnownRHS;
112
113 // If either operand is not NaN, the result is not NaN.
114 if (NeverNaN &&
115 (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
117 Known.knownNot(fcNan);
118
119 if (Kind == MinMaxKind::maxnum || Kind == MinMaxKind::maximumnum) {
120 if (KnownLHS.isKnownNeverNaN())
121 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses()));
122 if (KnownRHS.isKnownNeverNaN())
123 Known.knownNot(orderedStrictlyLess(KnownRHS.getKnownFPClasses()));
124 } else if (Kind == MinMaxKind::maximum) {
125 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses()) |
127 } else if (Kind == MinMaxKind::minnum || Kind == MinMaxKind::minimumnum) {
128 if (KnownLHS.isKnownNeverNaN())
129 Known.knownNot(orderedStrictlyGreater(KnownLHS.getKnownFPClasses()));
130 if (KnownRHS.isKnownNeverNaN())
131 Known.knownNot(orderedStrictlyGreater(KnownRHS.getKnownFPClasses()));
132 } else if (Kind == MinMaxKind::minimum) {
133 Known.knownNot(orderedStrictlyGreater(KnownLHS.getKnownFPClasses()) |
135 } else
136 llvm_unreachable("unhandled intrinsic");
137
138 // Fixup zero handling if denormals could be returned as a zero.
139 //
140 // As there's no spec for denormal flushing, be conservative with the
141 // treatment of denormals that could be flushed to zero. For older
142 // subtargets on AMDGPU the min/max instructions would not flush the
143 // output and return the original value.
144 //
145 if ((Known.getKnownFPClasses() & fcZero) != fcNone &&
146 !Known.isKnownNeverSubnormal()) {
147 if (Mode != DenormalMode::getIEEE())
148 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcZero);
149 }
150
151 if (Known.isKnownNeverNaN()) {
152 if (KnownLHS.getSignBit() && KnownRHS.getSignBit() &&
153 *KnownLHS.getSignBit() == *KnownRHS.getSignBit()) {
154 if (*KnownLHS.getSignBit())
155 Known.signBitMustBeOne();
156 else
157 Known.signBitMustBeZero();
158 } else if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::minimum ||
159 Kind == MinMaxKind::maximumnum ||
160 Kind == MinMaxKind::minimumnum) ||
161 // FIXME: Should be using logical zero versions
162 ((KnownLHS.isKnownNeverNegZero() ||
163 KnownRHS.isKnownNeverPosZero()) &&
164 (KnownLHS.isKnownNeverPosZero() ||
165 KnownRHS.isKnownNeverNegZero()))) {
166 // Don't take sign bit from NaN operands.
167 if (!KnownLHS.isKnownNeverNaN())
168 KnownLHS.setSignBit(std::nullopt);
169 if (!KnownRHS.isKnownNeverNaN())
170 KnownRHS.setSignBit(std::nullopt);
171 if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::maximumnum ||
172 Kind == MinMaxKind::maxnum) &&
173 (KnownLHS.getSignBit() == false || KnownRHS.getSignBit() == false))
174 Known.signBitMustBeZero();
175 else if ((Kind == MinMaxKind::minimum || Kind == MinMaxKind::minimumnum ||
176 Kind == MinMaxKind::minnum) &&
177 (KnownLHS.getSignBit() == true || KnownRHS.getSignBit() == true))
178 Known.signBitMustBeOne();
179 }
180 }
181
182 return Known;
183}
184
186 DenormalMode DenormMode) {
188
189 // Canonicalize may flush denormals to zero, so we have to consider the
190 // denormal mode to preserve known-not-0 knowledge.
191 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcZero | fcQNan);
192
193 // Stronger version of propagateNaN
194 // Canonicalize is guaranteed to quiet signaling nans.
195 if (KnownSrc.isKnownNeverNaN())
196 Known.knownNot(fcNan);
197 else
198 Known.knownNot(fcSNan);
199
200 // FIXME: Missing check of IEEE like types.
201
202 // If the parent function flushes denormals, the canonical output cannot be a
203 // denormal.
204 if (DenormMode == DenormalMode::getIEEE()) {
205 if (KnownSrc.isKnownNever(fcPosZero))
206 Known.knownNot(fcPosZero);
207 if (KnownSrc.isKnownNever(fcNegZero))
208 Known.knownNot(fcNegZero);
209 return Known;
210 }
211
212 if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
213 Known.knownNot(fcSubnormal);
214
215 if (DenormMode == DenormalMode::getPreserveSign()) {
216 if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
217 Known.knownNot(fcPosZero);
218 if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
219 Known.knownNot(fcNegZero);
220 return Known;
221 }
222
223 if (DenormMode.Input == DenormalMode::PositiveZero ||
224 (DenormMode.Output == DenormalMode::PositiveZero &&
225 DenormMode.Input == DenormalMode::IEEE)) {
226 // -0.0 is not a subnormal and should not be flushed.
227 if (KnownSrc.isKnownNever(fcNegZero))
228 Known.knownNot(fcNegZero);
229
230 if (KnownSrc.isKnownNever(fcPosZero | fcSubnormal))
231 Known.knownNot(fcPosZero);
232 }
233
234 return Known;
235}
236
238 const KnownBits &Bits) {
239 assert(FltSemantics.sizeInBits == Bits.getBitWidth() &&
240 "Bitcast operand has incorrect bit width");
242
243 // Conflicting known bits do not describe a concrete value. Return unknown.
244 if (Bits.hasConflict())
245 return Known;
246
247 // Return unknown for types we have not validated.
248 auto IsSupported = [](const fltSemantics &Semantics) {
249 switch (APFloat::SemanticsToEnum(Semantics)) {
256 return true;
257 default:
258 return false;
259 }
260 };
261 if (!IsSupported(FltSemantics))
262 return Known;
263
264 // Transfer information from the sign bit.
265 if (Bits.isNonNegative())
266 Known.signBitMustBeZero();
267 else if (Bits.isNegative())
268 Known.signBitMustBeOne();
269
270 switch (APFloatBase::SemanticsToEnum(FltSemantics)) {
276 const unsigned MantissaBits = FltSemantics.precision - 1;
277 const APInt ExponentMask = APInt::getBitsSet(
278 FltSemantics.sizeInBits, MantissaBits, FltSemantics.sizeInBits - 1);
279 const APInt MantissaMask =
280 APInt::getLowBitsSet(FltSemantics.sizeInBits, MantissaBits);
281
282 const bool ExponentKnownAllZeros =
283 (Bits.Zero & ExponentMask) == ExponentMask;
284 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
285 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
286 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
287
288 const bool MantissaKnownAllZeros =
289 (Bits.Zero & MantissaMask) == MantissaMask;
290 const bool MantissaKnownNotAllZeros = !(Bits.One & MantissaMask).isZero();
291
292 // Zero and subnormal require an exponent with all zero bits.
293 if (ExponentKnownNotAllZeros)
294 Known.knownNot(fcZero | fcSubnormal);
295
296 // Infinity and NaN require an exponent with all one bits.
297 if (ExponentKnownNotAllOnes)
298 Known.knownNot(fcInf | fcNan);
299
300 // Normal values have an exponent that is not all zeros or all ones.
301 if (ExponentKnownAllZeros || ExponentKnownAllOnes)
302 Known.knownNot(fcNormal);
303
304 // Zero and infinity require a mantissa with all zero bits.
305 if (MantissaKnownNotAllZeros)
306 Known.knownNot(fcZero | fcInf);
307
308 // Subnormal and NaN require a non-zero mantissa.
309 if (MantissaKnownAllZeros)
310 Known.knownNot(fcSubnormal | fcNan);
311
312 const bool QuietBitKnownSet = Bits.One[MantissaBits - 1];
313 const bool QuietBitKnownClear = Bits.Zero[MantissaBits - 1];
314
315 if (QuietBitKnownSet)
316 Known.knownNot(fcSNan);
317 else if (QuietBitKnownClear)
318 Known.knownNot(fcQNan);
319
320 break;
321 }
323 // Layout of the x87 floating point type:
324 // [0:62] fraction
325 // [63] explicit integer bit
326 // [64:78] exponent
327 // [79] sign bit
328 // APFloat treats the x87 pseudo encodings as documented in
329 // fltSemantics::hasExplicitIntegerBit.
330 constexpr unsigned BitWidth = 80;
331 constexpr unsigned FractionBits = 63;
332 constexpr unsigned IntegerBitIndex = FractionBits;
333 const APInt FractionMask = APInt::getLowBitsSet(BitWidth, FractionBits);
334 const APInt ExponentMask =
335 APInt::getBitsSet(BitWidth, FractionBits + 1, BitWidth - 1);
336
337 const bool ExponentKnownAllZeros =
338 (Bits.Zero & ExponentMask) == ExponentMask;
339 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
340 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
341 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
342 const bool FractionKnownAllZeros =
343 (Bits.Zero & FractionMask) == FractionMask;
344 const bool FractionKnownNotAllZeros = !(Bits.One & FractionMask).isZero();
345 const bool IntegerBitKnownSet = Bits.One[IntegerBitIndex];
346 const bool IntegerBitKnownClear = Bits.Zero[IntegerBitIndex];
347
348 // zero and subnormal require an exponent with all zero bits and a cleared
349 // integer bit.
350 if (ExponentKnownNotAllZeros || IntegerBitKnownSet)
351 Known.knownNot(fcZero | fcSubnormal);
352
353 // Zero requires a zero fraction.
354 if (FractionKnownNotAllZeros)
355 Known.knownNot(fcZero);
356
357 // Infinity requires an exponent with all one bits, a set integer bit, and
358 // a zero fraction.
359 if (ExponentKnownNotAllOnes || IntegerBitKnownClear ||
360 FractionKnownNotAllZeros)
361 Known.knownNot(fcInf);
362
363 // A normal x87 value has its integer bit set. A zero exponent with that
364 // bit set is the x87 pseudodenormal encoding, which APFloat treats as
365 // normal.
366 if (IntegerBitKnownClear || ExponentKnownAllOnes)
367 Known.knownNot(fcNormal);
368
369 // A subnormal has a nonzero fraction; NaNs are possible with a zero
370 // fraction through pseudoinfinity and unnormal encodings.
371 if (FractionKnownAllZeros)
372 Known.knownNot(fcSubnormal);
373
374 // We can rule out NaN if the value has all exponent bits set to zero, or
375 // if the value is a canonical normal or infinity.
376 if (ExponentKnownAllZeros ||
377 (IntegerBitKnownSet &&
378 (ExponentKnownNotAllOnes || FractionKnownAllZeros)))
379 Known.knownNot(fcNan);
380
381 const bool QuietBitKnownSet = Bits.One[FractionBits - 1];
382 const bool QuietBitKnownClear = Bits.Zero[FractionBits - 1];
383
384 if (QuietBitKnownSet)
385 Known.knownNot(fcSNan);
386 else if (QuietBitKnownClear)
387 Known.knownNot(fcQNan);
388
389 break;
390 }
391 default:
392 llvm_unreachable("unhandled supported type");
393 }
394
395 return Known;
396}
397
399 KnownBits Known(FltSemantics.sizeInBits);
400 const FPClassTest FPClasses = getKnownFPClasses();
401
402 // Return unknown if poison.
403 if (FPClasses == fcNone)
404 return Known;
405
406 // Return unknown for types we have not validated.
407 auto IsSupported = [](const fltSemantics &Semantics) {
408 switch (APFloat::SemanticsToEnum(Semantics)) {
415 return true;
416 default:
417 return false;
418 }
419 };
420 if (!IsSupported(FltSemantics))
421 return Known;
422
423 switch (APFloat::SemanticsToEnum(FltSemantics)) {
429 // For ieee types, we cannot deduce anything if the source could be normal.
430 if (FPClasses & fcNormal)
431 break;
432
433 Known.setAllConflict();
434
435 const unsigned BitWidth = FltSemantics.sizeInBits;
436 const unsigned MantissaBits = FltSemantics.precision - 1;
437 const unsigned ExponentBits = BitWidth - MantissaBits - 1;
438
439 APInt MantissaMask = APInt::getLowBitsSet(BitWidth, MantissaBits);
440 APInt ExponentMask =
441 APInt::getBitsSet(BitWidth, MantissaBits, MantissaBits + ExponentBits);
442
443 const unsigned QuietBitIndex = MantissaBits - 1;
444 APInt PayloadMask = MantissaMask;
445 PayloadMask.clearBit(QuietBitIndex);
446
447 if (FPClasses & fcNan) {
448 // Exponent bits cannot be zeros.
449 Known.Zero &= ~ExponentMask;
450 // No individual payload bit is known.
451 Known.Zero &= ~PayloadMask;
452 Known.One &= ~PayloadMask;
453
454 if (FPClasses & fcQNan)
455 Known.Zero.clearBit(QuietBitIndex);
456 if (FPClasses & fcSNan)
457 Known.One.clearBit(QuietBitIndex);
458 }
459 if (FPClasses & fcInf) {
460 // Exponent bits cannot be zeros.
461 Known.Zero &= ~ExponentMask;
462 // Mantissa bits cannot be ones.
463 Known.One &= ~MantissaMask;
464 }
465 if (FPClasses & fcSubnormal) {
466 // Exponent bits cannot be ones.
467 Known.One &= ~ExponentMask;
468 // Unknown mantissa.
469 Known.One &= ~MantissaMask;
470 Known.Zero &= ~MantissaMask;
471 }
472 if (FPClasses & fcZero) {
473 // Exponent bits cannot be ones.
474 Known.One &= ~ExponentMask;
475 // Mantissa cannot be ones.
476 Known.One &= ~MantissaMask;
477 }
478
479 break;
480 }
483 break;
484
485 Known.setAllConflict();
486
487 if (FPClasses & fcInf)
488 Known = Known.intersectWith(KnownBits::makeConstant(
489 APFloat::getInf(FltSemantics).bitcastToAPInt()));
490
491 if (FPClasses & fcZero)
492 Known = Known.intersectWith(
494
495 break;
496 }
497 default:
498 llvm_unreachable("unhandled supported semantics");
499 }
500
501 Known.Zero.clearSignBit();
502 Known.One.clearSignBit();
503 if (std::optional<bool> Sign = getSignBit()) {
504 if (*Sign)
505 Known.makeNegative();
506 else
507 Known.makeNonNegative();
508 }
509
510 return Known;
511}
512
513// Handle known sign bit and nan cases for fadd.
514static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
515 const KnownFPClass &KnownRHS, DenormalMode Mode) {
517
518 // Adding positive and negative infinity produces NaN, but only if both
519 // opposite-sign infinity combinations are possible.
520 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
521 (KnownLHS.isKnownNever(fcPosInf) || KnownRHS.isKnownNever(fcNegInf)) &&
522 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosInf)))
523 Known.knownNot(fcNan);
524
525 if (KnownLHS.cannotBeOrderedLessThanZero() &&
526 KnownRHS.cannotBeOrderedLessThanZero()) {
528
529 // This can't underflow if one of the operands is known normal.
530 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
532 Known.knownNot(fcZero | fcPosSubnormal);
533 }
534
535 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
538
539 // This can't underflow if one of the operands is known normal.
540 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
542 Known.knownNot(fcZero | fcNegSubnormal);
543 }
544
545 return Known;
546}
547
549 const KnownFPClass &KnownRHS,
550 DenormalMode Mode) {
551 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, Mode);
552
553 // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
554 if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
555 KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
556 // Make sure output negative denormal can't flush to -0
557 (Mode.Output == DenormalMode::IEEE ||
558 Mode.Output == DenormalMode::PositiveZero))
559 Known.knownNot(fcNegZero);
560
561 Known.propagateNonSNaN(KnownLHS, KnownRHS);
562
563 return Known;
564}
565
567 DenormalMode Mode) {
568 KnownFPClass Known = fadd(KnownSrc, KnownSrc, Mode);
569
570 // Doubling 0 will give the same 0.
571 if (KnownSrc.isKnownNeverLogicalPosZero(Mode) &&
572 (Mode.Output == DenormalMode::IEEE ||
573 (Mode.Output == DenormalMode::PreserveSign &&
574 KnownSrc.isKnownNeverPosSubnormal()) ||
575 (Mode.Output == DenormalMode::PositiveZero &&
576 KnownSrc.isKnownNeverSubnormal())))
577 Known.knownNot(fcPosZero);
578
579 return Known;
580}
581
583 const KnownFPClass &KnownRHS,
584 DenormalMode Mode) {
585 return fadd(KnownLHS, fneg(KnownRHS), 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 Known.propagateNonSNaN(KnownLHS, KnownRHS);
597
598 // +X * +Y or -X * -Y => +Q
599 // +X * -Y or -X * +Y => -Q
600 if ((KnownLHS.isKnownNever(fcNegative) &&
601 KnownRHS.isKnownNever(fcNegative)) ||
602 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
603 Known.knownNot(fcNegative);
604 if ((KnownLHS.isKnownNever(fcPositive) &&
605 KnownRHS.isKnownNever(fcNegative)) ||
606 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
607 Known.knownNot(fcPositive);
608
609 // Inf * Y => Inf or NaN
610 if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
611 KnownRHS.isKnownAlways(fcInf | fcNan))
612 Known.knownNot(fcNormal | fcSubnormal | fcZero);
613
614 // 0 * Y => 0 or NaN
615 if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
616 KnownLHS.isKnownAlways(fcZero | fcNan))
617 Known.knownNot(fcNormal | fcSubnormal | fcInf);
618
619 // 0 * +/-inf => NaN
620 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
621 (KnownRHS.isKnownNeverInfinity() || KnownLHS.isKnownNeverZero()) &&
622 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverZero()))
623 Known.knownNot(fcNan);
624
625 return applyOutputDenormalMode(Known, Mode);
626}
627
628// TODO: This generalizes to known ranges
630 const APFloat &CRHS, DenormalMode Mode) {
631 // Match denormal scaling pattern, similar to the case in ldexp. If the
632 // constant's exponent is sufficiently large, the result cannot be subnormal.
633
634 const fltSemantics &Flt = CRHS.getSemantics();
635 unsigned Precision = APFloat::semanticsPrecision(Flt);
636 const int MantissaBits = Precision - 1;
637
638 int MinKnownExponent = ilogb(CRHS);
639 bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);
640
641 KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
642 if (CannotBeSubnormal)
643 Known.knownNot(fcSubnormal);
644
645 // Multiply of values <= 1 cannot introduce overflow.
646 if (KnownLHS.isKnownNever(fcInf)) {
647 if (MinKnownExponent < 0)
648 Known.knownNot(fcInf);
649 else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
650 Flt)) == APFloat::cmpEqual)
651 Known.knownNot(fcInf);
652 }
653
654 return Known;
655}
656
658 const KnownFPClass &KnownRHS_,
659 DenormalMode Mode) {
660 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
661 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
662
664
665 Known.propagateNonSNaN(KnownLHS, KnownRHS);
666
667 // Only 0/0, Inf/Inf produce NaN.
668 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
669 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
670 (KnownLHS.isKnownNeverZero() || KnownRHS.isKnownNeverZero())) {
671 Known.knownNot(fcNan);
672 }
673
674 // X / -0.0 => -Inf (or NaN)
675 // +X / +Y or -X / -Y => +Q
676 // +X / -Y or -X / +Y => -Q
677 if ((KnownLHS.isKnownNever(fcNegative) &&
678 KnownRHS.isKnownNever(fcNegative)) ||
679 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
680 Known.knownNot(fcNegative);
681 if ((KnownLHS.isKnownNever(fcPositive) &&
682 KnownRHS.isKnownNever(fcNegative)) ||
683 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
684 Known.knownNot(fcPositive);
685
686 // Normal and subnormal results require two non-zero finite operands.
687 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
691 Known.knownNot(fcNegNormal | fcNegSubnormal);
692 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
696 Known.knownNot(fcPosNormal | fcPosSubnormal);
697
698 // 0 / X => 0 or NaN
699 if (KnownLHS.isKnownAlways(fcZero))
700 Known.knownNot(fcSubnormal | fcNormal | fcInf);
701
702 // X / 0 => NaN or Inf
703 if (KnownRHS.isKnownAlways(fcZero))
704 Known.knownNot(fcFinite);
705
706 return applyOutputDenormalMode(Known, Mode);
707}
708
710 DenormalMode Mode) {
711 // X / X is always exactly 1.0 or a NaN.
713
714 Known.propagateNonSNaN(KnownSrc);
715
716 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
717 Known.knownNot(fcNan);
718
719 return Known;
720}
721
723 const KnownFPClass &KnownRHS,
724 DenormalMode Mode) {
726
727 // We are assuming that frem(x, Inf) is already handled elsewhere.
728
729 Known.knownNot(fcInf);
730
731 Known.propagateNonSNaN(KnownLHS, KnownRHS);
732
733 // frem(Inf, x) and frem(x, 0) produce NaN.
734 if (KnownLHS.isKnownNeverInfOrNaN() && KnownRHS.isKnownNeverNaN() &&
735 KnownRHS.isKnownNeverLogicalZero(Mode)) {
736 Known.knownNot(fcNan);
737 }
738
739 // The sign for frem is the same as the first operand.
741 Known.knownNot(fcPosNormal | fcPosSubnormal);
743 Known.knownNot(fcNegNormal | fcNegSubnormal);
744
745 // A negative zero result requires a negative finite first operand.
746 if (KnownLHS.isKnownNever(fcNegFinite))
747 Known.knownNot(fcNegZero);
748
749 // A positive zero result can additionally come from a negative finite
750 // result being flushed to positive zero.
751 if (KnownLHS.isKnownNever(fcPosFinite) &&
752 KnownLHS.isKnownNeverLogicalPosZero(Mode) &&
753 (!Mode.outputsMayBePositiveZero() ||
755 Known.knownNot(fcPosZero);
756
757 return Known;
758}
759
761 DenormalMode Mode) {
762 // X % X is always exactly [+-]0.0 or a NaN.
764
765 Known.propagateNonSNaN(KnownSrc);
766
767 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
768 Known.knownNot(fcNan);
769
770 // The sign of a zero result is the sign of the finite non-zero input.
771 // We do not have to worry about subnormal values flushing to zero, since
772 // frem(+-0.0, +-0.0) = NaN.
774 Known.knownNot(fcPosZero);
776 Known.knownNot(fcNegZero);
777
778 return Known;
779}
780
782 const KnownFPClass &KnownRHS,
783 const KnownFPClass &KnownAddend,
784 DenormalMode Mode) {
785 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, Mode);
786
787 // FMA differs from the base fmul + fadd handling only in the treatment of -0
788 // results.
789 //
790 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
791 // unlike for a separate fadd.
792 KnownFPClass Known = fadd_impl(Mul, KnownAddend, Mode);
793
794 // propagateNonSNaN for 3 arguments.
795 if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
796 KnownAddend.isKnownNever(fcSNan))
797 Known.knownNot(fcSNan);
798
799 return Known;
800}
801
803 const KnownFPClass &KnownAddend,
804 DenormalMode Mode) {
805 KnownFPClass Squared = square(KnownSquared, Mode);
806 KnownFPClass Known = fadd_impl(Squared, KnownAddend, Mode);
807
808 // Since we know the squared input must be positive, the add of opposite sign
809 // infinities nan hazard only applies for negative inf.
810 //
811 // TODO: Alternatively to proving addend is not -inf, we could know Squared is
812 // not pinf. Other than the degenerate always-subnormal input case, we can't
813 // prove that without a known range.
814 if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
815 Known.knownNot(fcNan);
816
817 Known.propagateNonSNaN(KnownSquared, KnownAddend);
818
819 return Known;
820}
821
824 Known.knownNot(fcNegative);
825
826 Known.propagateNonNaN(KnownSrc);
827
828 // The following deductions assume that exp10(-1.0) = +0.1 and
829 // exp10(+1.0) = +10.0 are both finite normal values.
830
831 // Zero can only be produced if x < -1.0.
832 if (KnownSrc.isKnownNever(fcNegNormal | fcNegInf))
833 Known.knownNot(fcPosZero);
834
835 // Subnormals can only be produced if x < -1.0 and x is finite.
836 if (KnownSrc.isKnownNever(fcNegNormal))
837 Known.knownNot(fcPosSubnormal);
838
839 // Infinity can only be produced if x > +1.0.
840 if (KnownSrc.isKnownNever(fcPosNormal | fcPosInf))
841 Known.knownNot(fcPosInf);
842
843 return Known;
844}
845
847 bool IsMultiUnitFPType) {
849
850 // PPCDoubleDouble can represent the exact value of 1.0 + subnormal, and
851 // log(1.0 + subnormal) = subnormal.
852 if (!IsMultiUnitFPType)
853 Known.knownNot(fcNegZero | fcSubnormal);
854
855 Known.propagateNonSNaN(KnownSrc);
856
857 if (KnownSrc.isKnownNeverPosInfinity())
858 Known.knownNot(fcPosInf);
859
860 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
861 Known.knownNot(fcNan);
862
863 if (KnownSrc.isKnownNeverLogicalZero(Mode))
864 Known.knownNot(fcNegInf);
865
866 return Known;
867}
868
870 DenormalMode Mode) {
872 Known.knownNot(fcPosSubnormal);
873
874 if (KnownSrc.isKnownNeverPosInfinity())
875 Known.knownNot(fcPosInf);
876
877 Known.propagateNonSNaN(KnownSrc);
878
879 // Any negative value besides -0 returns a nan.
880 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
881 Known.knownNot(fcNan);
882
883 // The only negative value that can be returned is -0 for -0 inputs.
885
886 // If the input denormal mode could be PreserveSign, a negative
887 // subnormal input could produce a negative zero output.
888 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
889 Known.knownNot(fcNegZero);
890
891 return Known;
892}
893
896
897 Known.propagateNonSNaN(KnownSrc);
898
899 // Return NaN on infinite inputs.
900 Known.knownNot(fcInf);
901 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
902 Known.knownNot(fcNan);
903
904 return Known;
905}
906
908 return sin(KnownSrc);
909}
910
913
914 // tan never returns Inf (tan(+-Inf) = NaN; tan(finite) = finite).
915 Known.knownNot(fcInf);
916
917 Known.propagateNonSNaN(KnownSrc);
918
919 // NaN propagates. tan(+-Inf) is NaN.
920 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
921 Known.knownNot(fcNan);
922
923 return Known;
924}
925
928
929 // sinh is sign-preserving: sinh(x) < 0 iff x < 0.
930 if (KnownSrc.isKnownNever(fcNegative))
931 Known.knownNot(fcNegative);
932
933 // A nonzero positive result requires a nonzero positive input.
934 // Zero remains possible: sinh(+/-0.0) = +/-0.0, and flushing a subnormal
935 // may produce +0.0.
938
939 Known.propagateNonNaN(KnownSrc);
940
941 return Known;
942}
943
946
947 // cosh(x) >= 1 for all real x; cosh(+-Inf) = +Inf. Never negative,
948 // zero, or subnormal.
949 Known.knownNot(fcNegative | fcZero | fcSubnormal);
950
951 Known.propagateNonNaN(KnownSrc);
952
953 return Known;
954}
955
958
959 // tanh is bounded to (-1, 1), never Inf.
960 Known.knownNot(fcInf);
961
962 // tanh is sign-preserving: tanh(x) < 0 iff x < 0.
964 Known.knownNot(fcNegSubnormal | fcNegNormal);
965
966 // -0.0 is preserved: tanh(-0.0) = -0.0.
967 if (KnownSrc.isKnownNeverNegZero())
968 Known.knownNot(fcNegZero);
969 }
970
971 // Likewise, tanh(x) > 0 iff x > 0. Zero is not ruled out: tanh(+-0.0) =
972 // +-0.0, and a flushed subnormal may become +0.0.
974 Known.knownNot(fcPosSubnormal | fcPosNormal);
975
976 Known.propagateNonNaN(KnownSrc);
977
978 return Known;
979}
980
983
984 // asin is bounded to [-pi/2, pi/2], never Inf.
985 Known.knownNot(fcInf);
986
987 Known.propagateNonSNaN(KnownSrc);
988
989 // asin is sign-preserving for finite arguments.
990 if (KnownSrc.isKnownNever(fcNegFinite))
991 Known.knownNot(fcNegFinite);
992
993 // NaN propagates. asin(x) is also NaN for |x| > 1, so we cannot rule
994 // out NaN without knowing the source is in [-1, 1].
995 return Known;
996}
997
1000
1001 // acos(x) is bounded to [0, pi] for -1 <= x <= 1, and is never negative,
1002 // infinite, or subnormal. The smallest non-zero value occurs when x is
1003 // close to 1.0, where acos(x) can be approximated by sqrt(2 * (1 - x)).
1004 // Since sqrt cannot produce a subnormal result, we can conclude that
1005 // acos(x) will also never produce a subnormal result.
1006 Known.knownNot(fcNegative | fcInf | fcSubnormal);
1007
1008 // acos(x) == +0.0 iff x == +1.0
1009 if (KnownSrc.isKnownNever(fcPosNormal))
1010 Known.knownNot(fcZero);
1011
1012 Known.propagateNonSNaN(KnownSrc);
1013
1014 // NaN propagates. acos(x) is also NaN for |x| > 1, so we cannot rule
1015 // out NaN without knowing the source is in [-1, 1].
1016 return Known;
1017}
1018
1021
1022 // atan is bounded to (-pi/2, pi/2), never Inf. atan(+-Inf) = +-pi/2 (finite).
1023 Known.knownNot(fcInf);
1024
1025 // Ruling out Subnormal/Normal from the result requires the
1026 // input to never be finite-nonzero and never inf, since
1027 // atan(+-inf) = +-pi/2
1029 Known.knownNot(fcNegSubnormal | fcNegNormal);
1030
1032 Known.knownNot(fcPosSubnormal | fcPosNormal);
1033
1034 // atan(-0.0) = -0.0. Negative finite inputs may also produce -0.0
1035 // if the result rounds to a negative subnormal that is flushed to zero.
1037 Known.knownNot(fcNegZero);
1038
1039 Known.propagateNonNaN(KnownSrc);
1040
1041 return Known;
1042}
1043
1045 const KnownFPClass &KnownX_,
1046 DenormalMode Mode) {
1047 KnownFPClass KnownY = applyInputDenormalMode(KnownY_, Mode);
1048 KnownFPClass KnownX = applyInputDenormalMode(KnownX_, Mode);
1050
1051 // Even though these deductions are correct, we are ignoring the following
1052 // potentially erroneous cases:
1053 // * atan2(y, inf) is not subnormal
1054 // * atan2(inf, x) is not zero or subnormal
1055
1056 // atan2 result is in (-pi, pi], never Inf.
1057 Known.knownNot(fcInf);
1058
1059 Known.propagateNonNaN(KnownY, KnownX);
1060
1061 // If x <= -0.0, then |atan2(y, x)| >= pi/2
1062 if (KnownX.isKnownNever(fcPositive))
1063 Known.knownNot(fcZero | fcSubnormal);
1064
1065 // If y >= +0.0, then atan2(y, x) >= +0.0
1066 if (KnownY.isKnownNever(fcNegative))
1067 Known.knownNot(fcNegative);
1068
1069 // If y <= -0.0, then atan2(y, x) <= -0.0
1070 if (KnownY.isKnownNever(fcPositive))
1071 Known.knownNot(fcPositive);
1072
1073 return applyOutputDenormalMode(Known, Mode);
1074}
1075
1077 const fltSemantics &DstTy,
1078 const fltSemantics &SrcTy) {
1079 // Infinity, nan and zero propagate from source.
1080 KnownFPClass Known = KnownSrc;
1081
1082 // All subnormal inputs should be in the normal range in the result type.
1083 if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
1084 if (Known.getKnownFPClasses() & fcPosSubnormal)
1085 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosNormal);
1086 if (Known.getKnownFPClasses() & fcNegSubnormal)
1087 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegNormal);
1088 Known.knownNot(fcSubnormal);
1089 }
1090
1091 // Sign bit of a nan isn't guaranteed.
1092 if (!Known.isKnownNeverNaN())
1093 Known.setSignBit(std::nullopt);
1094
1095 return Known;
1096}
1097
1100
1101 // Sign should be preserved
1102 // TODO: Handle cannot be ordered greater than zero
1103 if (KnownSrc.cannotBeOrderedLessThanZero())
1105
1106 Known.propagateNonNaN(KnownSrc);
1107
1108 // Infinity needs a range check.
1109 return Known;
1110}
1111
1113 bool MayBeMultiUnitFPType,
1114 DenormalMode Mode) {
1116
1117 // Integer results cannot be subnormal.
1118 Known.knownNot(fcSubnormal);
1119
1120 Known.propagateNonNaN(KnownSrc);
1121
1122 // Pass through infinities, except PPC_FP128 is a special case for intrinsics.
1123 if (!MayBeMultiUnitFPType) {
1124 if (KnownSrc.isKnownNeverPosInfinity())
1125 Known.knownNot(fcPosInf);
1126 if (KnownSrc.isKnownNeverNegInfinity())
1127 Known.knownNot(fcNegInf);
1128 }
1129
1130 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1131 Known.knownNot(fcPosNormal);
1132
1133 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1134 Known.knownNot(fcNegNormal);
1135
1136 // Negative round ups towards zero produce negative zero.
1137 if (KnownSrc.isKnownNever(fcNegFinite))
1138 Known.knownNot(fcNegZero);
1139
1140 // Negative subnormals may flush to positive zero.
1141 if (KnownSrc.isKnownNever(fcPosFinite) &&
1142 (KnownSrc.isKnownNever(fcNegSubnormal) ||
1143 !Mode.inputsMayBePositiveZero()))
1144 Known.knownNot(fcPosZero);
1145
1146 return Known;
1147}
1148
1150 DenormalMode Mode) {
1152 /*MayBeMultiUnitFPType=*/true, Mode);
1153
1154 if (KnownSrc.isKnownNeverPosInfinity())
1155 Known.knownNot(fcPosInf);
1156 if (KnownSrc.isKnownNeverNegInfinity())
1157 Known.knownNot(fcNegInf);
1158
1159 return Known;
1160}
1161
1163 bool IsMultiUnitFPType, DenormalMode Mode) {
1164 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1165
1166 // Applicable for multi-unit floating point types.
1167 if (KnownSrc.isKnownNeverPosInfinity())
1168 Known.knownNot(fcPosInf);
1169
1170 return Known;
1171}
1172
1174 bool IsMultiUnitFPType, DenormalMode Mode) {
1175 KnownFPClass Known = roundToIntegral(KnownSrc, IsMultiUnitFPType, Mode);
1176
1177 // Applicable for multi-unit floating point types.
1178 if (KnownSrc.isKnownNeverNegInfinity())
1179 Known.knownNot(fcNegInf);
1180
1181 return Known;
1182}
1183
1185 DenormalMode Mode) {
1187
1188 Known.knownNot(fcSubnormal);
1189
1190 Known.propagateNonNaN(KnownSrc);
1191
1192 if (KnownSrc.isKnownNeverPosInfinity())
1193 Known.knownNot(fcPosInf);
1194
1195 if (KnownSrc.isKnownNeverNegInfinity())
1196 Known.knownNot(fcNegInf);
1197
1198 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
1199 Known.knownNot(fcPosZero);
1200
1201 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
1202 Known.knownNot(fcNegZero);
1203
1204 // TODO: These deductions can be improved if subnormal inputs are guaranteed
1205 // to be flushed to zero.
1206 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1207 Known.knownNot(fcPosNormal);
1208
1209 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1210 Known.knownNot(fcNegNormal);
1211
1212 return Known;
1213}
1214
1216 const APInt &ConstantRangeExpMin,
1217 const APInt &ConstantRangeExpMax,
1218 const fltSemantics &Flt, DenormalMode Mode) {
1220
1221 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
1222
1223 if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
1224 // ldexp(x, 0) -> x
1225 // Here we make sure to properly propagate sNaN and denormals.
1226 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcNan);
1227 Known.propagateNonNaN(KnownSrc);
1228 return applyOutputDenormalMode(Known, Mode);
1229 }
1230
1231 Known.propagateNonNaN(KnownSrc);
1232
1233 // Sign is preserved, but underflows may produce zeroes.
1234 if (KnownSrc.isKnownNever(fcNegative))
1235 Known.knownNot(fcNegative);
1236 else if (KnownSrc.cannotBeOrderedLessThanZero())
1238
1239 if (KnownSrc.isKnownNever(fcPositive))
1240 Known.knownNot(fcPositive);
1241 else if (KnownSrc.cannotBeOrderedGreaterThanZero())
1243
1244 // TODO: determine when it is safe to rule out subnormal for ppcf128.
1245 if (&Flt != &APFloat::PPCDoubleDouble()) {
1246 unsigned Precision = APFloat::semanticsPrecision(Flt);
1247 const int MantissaBits = Precision - 1;
1248 if (ConstantRangeExpMin.sge(MantissaBits))
1249 Known.knownNot(fcSubnormal);
1250 }
1251
1252 if (ConstantRangeExpMax.isNonPositive()) {
1253 // If we know the power is <= 0, can't introduce inf
1254 if (KnownSrc.isKnownNeverPosInfinity())
1255 Known.knownNot(fcPosInf);
1256 if (KnownSrc.isKnownNeverNegInfinity())
1257 Known.knownNot(fcNegInf);
1258 } else if (ConstantRangeExpMin.isNonNegative()) {
1259 // If we know the power is >= 0, can't introduce subnormal or zero
1260 if (KnownSrc.isKnownNeverPosSubnormal())
1261 Known.knownNot(fcPosSubnormal);
1262 if (KnownSrc.isKnownNeverNegSubnormal())
1263 Known.knownNot(fcNegSubnormal);
1264 if (KnownSrc.isKnownNeverPosZero())
1265 Known.knownNot(fcPosZero);
1266 if (KnownSrc.isKnownNeverNegZero())
1267 Known.knownNot(fcNegZero);
1268 }
1269
1270 return applyOutputDenormalMode(Known, Mode);
1271}
1272
1274 const KnownBits &ExpBits,
1275 const fltSemantics &Flt, DenormalMode Mode) {
1276 return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
1277 ExpBits.getSignedMaxValue(), Flt, Mode);
1278}
1279
1281 const KnownFPClass &KnownRHS) {
1283
1284 Known.propagateNonSNaN(KnownLHS, KnownRHS);
1285
1286 // pow may return NaN if one of the arguments is NaN. NaN may be produced from
1287 // a non-zero-finite-negative base and a non-integer exponent.
1288 if (KnownLHS.isKnownNever(fcNan | fcNegNormal | fcNegSubnormal) &&
1289 KnownRHS.isKnownNeverNaN())
1290 Known.knownNot(fcNan);
1291
1292 // We could rule out negative and subnormal results when exponent is known to
1293 // never be a normal value, but having either argument being known to never be
1294 // normal is unlikely and not worth considering.
1295
1296 // Only a negative base raised to an odd power returns a negative value.
1297 if (KnownLHS.isKnownNever(fcNegative)) {
1298 Known.knownNot(fcNegative);
1299 } else if (KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1300 Known.knownNot(fcNegNormal | fcNegSubnormal);
1301 // See if we can also rule out -0.0 or -inf.
1302 // Here at least one of -0.0 or -inf is a possible base.
1303
1304 // pow(-0.0, odd-positive) = -0.0
1305 // pow(-inf, odd-negative) = -0.0
1306 if ((KnownLHS.isKnownNever(fcNegZero) ||
1307 KnownRHS.isKnownNever(fcPosNormal)) &&
1308 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcNegNormal)))
1309 Known.knownNot(fcNegZero);
1310
1311 // pow(-0.0, odd-negative) = -inf
1312 // pow(-inf, odd-positive) = -inf
1313 if ((KnownLHS.isKnownNever(fcNegZero) ||
1314 KnownRHS.isKnownNever(fcNegNormal)) &&
1315 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosNormal)))
1316 Known.knownNot(fcNegInf);
1317 }
1318
1319 return Known;
1320}
1321
1323 const KnownBits &ExponentKnownBits) {
1325 Known.propagateNonNaN(KnownSrc);
1326
1327 if (ExponentKnownBits.isZero()) {
1328 // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
1329 // return 1.0 or a NaN.
1330 if (KnownSrc.isKnownNever(fcSNan)) {
1331 Known.knownNot(~fcPosNormal);
1332 return Known;
1333 }
1334
1335 Known.knownNot(~(fcPosNormal | fcNan));
1336 return Known;
1337 }
1338
1339 // Given that exp is an integer, here are the
1340 // ways that powi can return a negative value:
1341 //
1342 // powi(x, exp) --> negative if exp is odd and x is negative.
1343 // powi(-0, exp) --> -inf if exp is negative odd.
1344 // powi(-0, exp) --> -0 if exp is positive odd.
1345 // powi(-inf, exp) --> -0 if exp is negative odd.
1346 // powi(-inf, exp) --> -inf if exp is positive odd.
1347 if (KnownSrc.isKnownNever(fcNegative) || ExponentKnownBits.isEven()) {
1348 Known.knownNot(fcNegative);
1349 } else if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1350 Known.knownNot(fcNegNormal | fcNegSubnormal);
1351 // See if we can also rule out -0.0 or -inf.
1352 // Here at least one of -0.0 or -inf is a possible base.
1353
1354 // We already know that ExponentKnownBits.isEven() is false here.
1355 const bool IsKnownNeverOddPositive = ExponentKnownBits.isNegative();
1356 const bool IsKnownNeverOddNegative = ExponentKnownBits.isNonNegative();
1357
1358 // powi(-0.0, odd-positive) = -0.0
1359 // powi(-inf, odd-negative) = -0.0
1360 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddPositive) &&
1361 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddNegative))
1362 Known.knownNot(fcNegZero);
1363
1364 // powi(-0.0, odd-negative) = -inf
1365 // powi(-inf, odd-positive) = -inf
1366 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddNegative) &&
1367 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddPositive))
1368 Known.knownNot(fcNegInf);
1369 }
1370
1371 // powi(x, exp) --> inf
1372 // when:
1373 // * powi(inf, exp), exp > 0
1374 // * powi(+/-0, exp), exp < 0
1375 // * powi(finite, exp), |exp| > 1
1376 // * powi(subnormal, -1)
1377 // TODO:
1378 // 1. This simple all or nothing approach. We can do better
1379 // and cover sign/parity and exp > 1 vs exp < -1 separately.
1380 // 2. powi(0/nan, exp), exp > 0 can be refinable
1381 // to fcNan | fcZero | fcPosNormal.
1382 {
1383 APInt MinExp = ExponentKnownBits.getSignedMinValue();
1384 APInt MaxExp = ExponentKnownBits.getSignedMaxValue();
1385
1386 // powi(inf, exp), exp > 0
1387 bool MayInfSrc =
1388 !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();
1389
1390 // powi(+/-0, exp), exp < 0
1391 bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();
1392
1393 // powi(finite, exp), |exp| > 1
1394 bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
1395 bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
1396 bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;
1397
1398 // powi(subnormal, -1)
1399 bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
1400 bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;
1401
1402 if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
1403 Known.knownNot(fcInf);
1404 }
1405
1406 return Known;
1407}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS, const KnownFPClass &KnownRHS, DenormalMode Mode)
static bool 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:307
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 KnownFPClass square(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
static LLVM_ABI KnownFPClass fsub(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fsub.
bool isKnownNeverSubnormal() const
Return true if it's known this can never be a subnormal.
bool isKnownAlways(FPClassTest Mask) const
static LLVM_ABI KnownFPClass canonicalize(const KnownFPClass &Src, DenormalMode DenormMode=DenormalMode::getDynamic())
Apply the canonicalize intrinsic to this value.
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a zero.
static LLVM_ABI KnownFPClass 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())
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