LLVM 23.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 : KnownFPClasses(C.classify()), SignBit(C.isNegative()) {}
23
24/// Return true if it's possible to assume IEEE treatment of input denormals in
25/// \p F for \p Val.
27 return Mode.Input == DenormalMode::IEEE;
28}
29
34
39
44
47 return false;
48
49 // If we know there are no denormals, nothing can be flushed to zero.
51 return true;
52
53 switch (Mode.Input) {
55 return true;
57 // Negative subnormal won't flush to +0
60 default:
61 // Both positive and negative subnormal could flush to +0
62 return false;
63 }
64
65 llvm_unreachable("covered switch over denormal mode");
66}
67
69 DenormalMode Mode) {
70 KnownFPClasses = Src.KnownFPClasses;
71 // If we aren't assuming the source can't be a zero, we don't have to check if
72 // a denormal input could be flushed.
73 if (!Src.isKnownNeverPosZero() && !Src.isKnownNeverNegZero())
74 return;
75
76 // If we know the input can't be a denormal, it can't be flushed to 0.
77 if (Src.isKnownNeverSubnormal())
78 return;
79
80 if (!Src.isKnownNeverPosSubnormal() && Mode != DenormalMode::getIEEE())
82
83 if (!Src.isKnownNeverNegSubnormal() && Mode != DenormalMode::getIEEE()) {
86
87 if (Mode.Input == DenormalMode::PositiveZero ||
88 Mode.Output == DenormalMode::PositiveZero ||
89 Mode.Input == DenormalMode::Dynamic ||
90 Mode.Output == DenormalMode::Dynamic)
92 }
93}
94
96 const KnownFPClass &RHS_, MinMaxKind Kind,
97 DenormalMode Mode) {
98 KnownFPClass KnownLHS = LHS_;
99 KnownFPClass KnownRHS = RHS_;
100
101 bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
102 KnownFPClass Known = KnownLHS | KnownRHS;
103
104 // If either operand is not NaN, the result is not NaN.
105 if (NeverNaN &&
106 (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
108 Known.knownNot(fcNan);
109
110 if (Kind == MinMaxKind::maxnum || Kind == MinMaxKind::maximumnum) {
111 // If at least one operand is known to be positive, the result must be
112 // positive.
113 if ((KnownLHS.cannotBeOrderedLessThanZero() &&
114 KnownLHS.isKnownNeverNaN()) ||
115 (KnownRHS.cannotBeOrderedLessThanZero() && KnownRHS.isKnownNeverNaN()))
117 } else if (Kind == MinMaxKind::maximum) {
118 // If at least one operand is known to be positive, the result must be
119 // positive.
120 if (KnownLHS.cannotBeOrderedLessThanZero() ||
123 } else if (Kind == MinMaxKind::minnum || Kind == MinMaxKind::minimumnum) {
124 // If at least one operand is known to be negative, the result must be
125 // negative.
126 if ((KnownLHS.cannotBeOrderedGreaterThanZero() &&
127 KnownLHS.isKnownNeverNaN()) ||
128 (KnownRHS.cannotBeOrderedGreaterThanZero() &&
129 KnownRHS.isKnownNeverNaN()))
131 } else if (Kind == MinMaxKind::minimum) {
132 // If at least one operand is known to be negative, the result must be
133 // negative.
134 if (KnownLHS.cannotBeOrderedGreaterThanZero() ||
137 } else
138 llvm_unreachable("unhandled intrinsic");
139
140 // Fixup zero handling if denormals could be returned as a zero.
141 //
142 // As there's no spec for denormal flushing, be conservative with the
143 // treatment of denormals that could be flushed to zero. For older
144 // subtargets on AMDGPU the min/max instructions would not flush the
145 // output and return the original value.
146 //
147 if ((Known.KnownFPClasses & fcZero) != fcNone &&
148 !Known.isKnownNeverSubnormal()) {
149 if (Mode != DenormalMode::getIEEE())
150 Known.KnownFPClasses |= fcZero;
151 }
152
153 if (Known.isKnownNeverNaN()) {
154 if (KnownLHS.SignBit && KnownRHS.SignBit &&
155 *KnownLHS.SignBit == *KnownRHS.SignBit) {
156 if (*KnownLHS.SignBit)
157 Known.signBitMustBeOne();
158 else
159 Known.signBitMustBeZero();
160 } else if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::minimum ||
161 Kind == MinMaxKind::maximumnum ||
162 Kind == MinMaxKind::minimumnum) ||
163 // FIXME: Should be using logical zero versions
164 ((KnownLHS.isKnownNeverNegZero() ||
165 KnownRHS.isKnownNeverPosZero()) &&
166 (KnownLHS.isKnownNeverPosZero() ||
167 KnownRHS.isKnownNeverNegZero()))) {
168 // Don't take sign bit from NaN operands.
169 if (!KnownLHS.isKnownNeverNaN())
170 KnownLHS.SignBit = std::nullopt;
171 if (!KnownRHS.isKnownNeverNaN())
172 KnownRHS.SignBit = std::nullopt;
173 if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::maximumnum ||
174 Kind == MinMaxKind::maxnum) &&
175 (KnownLHS.SignBit == false || KnownRHS.SignBit == false))
176 Known.signBitMustBeZero();
177 else if ((Kind == MinMaxKind::minimum || Kind == MinMaxKind::minimumnum ||
178 Kind == MinMaxKind::minnum) &&
179 (KnownLHS.SignBit == true || KnownRHS.SignBit == true))
180 Known.signBitMustBeOne();
181 }
182 }
183
184 return Known;
185}
186
188 DenormalMode DenormMode) {
189 KnownFPClass Known;
190
191 // This is essentially a stronger form of
192 // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
193 // actually have an IR canonicalization guarantee.
194
195 // Canonicalize may flush denormals to zero, so we have to consider the
196 // denormal mode to preserve known-not-0 knowledge.
197 Known.KnownFPClasses = KnownSrc.KnownFPClasses | fcZero | fcQNan;
198
199 // Stronger version of propagateNaN
200 // Canonicalize is guaranteed to quiet signaling nans.
201 if (KnownSrc.isKnownNeverNaN())
202 Known.knownNot(fcNan);
203 else
204 Known.knownNot(fcSNan);
205
206 // FIXME: Missing check of IEEE like types.
207
208 // If the parent function flushes denormals, the canonical output cannot be a
209 // denormal.
210 if (DenormMode == DenormalMode::getIEEE()) {
211 if (KnownSrc.isKnownNever(fcPosZero))
212 Known.knownNot(fcPosZero);
213 if (KnownSrc.isKnownNever(fcNegZero))
214 Known.knownNot(fcNegZero);
215 return Known;
216 }
217
218 if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
219 Known.knownNot(fcSubnormal);
220
221 if (DenormMode == DenormalMode::getPreserveSign()) {
222 if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
223 Known.knownNot(fcPosZero);
224 if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
225 Known.knownNot(fcNegZero);
226 return Known;
227 }
228
229 if (DenormMode.Input == DenormalMode::PositiveZero ||
230 (DenormMode.Output == DenormalMode::PositiveZero &&
231 DenormMode.Input == DenormalMode::IEEE))
232 Known.knownNot(fcNegZero);
233
234 return Known;
235}
236
238 const KnownBits &Bits) {
239 assert(FltSemantics.sizeInBits == Bits.getBitWidth() &&
240 "Bitcast operand has incorrect bit width");
241 KnownFPClass Known;
242
243 // Transfer information from the sign bit.
244 if (Bits.isNonNegative())
245 Known.signBitMustBeZero();
246 else if (Bits.isNegative())
247 Known.signBitMustBeOne();
248
249 if (APFloat::isIEEELikeFP(FltSemantics)) {
250 // IEEE floats are NaN when all bits of the exponent plus at least one of
251 // the fraction bits are 1. This means:
252 // - If we assume unknown bits are 0 and the value is NaN, it will
253 // always be NaN
254 // - If we assume unknown bits are 1 and the value is not NaN, it can
255 // never be NaN
256 // Note: They do not hold for x86_fp80 format.
257 if (APFloat(FltSemantics, Bits.One).isNaN())
258 Known.KnownFPClasses = fcNan;
259 else if (!APFloat(FltSemantics, ~Bits.Zero).isNaN())
260 Known.knownNot(fcNan);
261
262 // Build KnownBits representing Inf and check if it must be equal or
263 // unequal to this value.
264 auto InfKB =
265 KnownBits::makeConstant(APFloat::getInf(FltSemantics).bitcastToAPInt());
266 InfKB.Zero.clearSignBit();
267 if (const auto InfResult = KnownBits::eq(Bits, InfKB)) {
268 assert(!InfResult.value());
269 Known.knownNot(fcInf);
270 } else if (Bits == InfKB) {
271 Known.KnownFPClasses = fcInf;
272 }
273
274 // Build KnownBits representing Zero and check if it must be equal or
275 // unequal to this value.
276 auto ZeroKB = KnownBits::makeConstant(
277 APFloat::getZero(FltSemantics).bitcastToAPInt());
278 ZeroKB.Zero.clearSignBit();
279 if (const auto ZeroResult = KnownBits::eq(Bits, ZeroKB)) {
280 assert(!ZeroResult.value());
281 Known.knownNot(fcZero);
282 } else if (Bits == ZeroKB) {
283 Known.KnownFPClasses = fcZero;
284 }
285 }
286
287 return Known;
288}
289
290// Handle known sign bit and nan cases for fadd.
291static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
292 const KnownFPClass &KnownRHS, DenormalMode Mode) {
293 KnownFPClass Known;
294
295 // Adding positive and negative infinity produces NaN.
296 // TODO: Check sign of infinities.
297 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
298 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()))
299 Known.knownNot(fcNan);
300
301 if (KnownLHS.cannotBeOrderedLessThanZero() &&
302 KnownRHS.cannotBeOrderedLessThanZero()) {
304
305 // This can't underflow if one of the operands is known normal.
306 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
309 }
310
311 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
314
315 // This can't underflow if one of the operands is known normal.
316 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
319 }
320
321 return Known;
322}
323
325 const KnownFPClass &KnownRHS,
326 DenormalMode Mode) {
327 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, Mode);
328
329 // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
330 if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
331 KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
332 // Make sure output negative denormal can't flush to -0
333 (Mode.Output == DenormalMode::IEEE ||
334 Mode.Output == DenormalMode::PositiveZero))
335 Known.knownNot(fcNegZero);
336
337 return Known;
338}
339
341 DenormalMode Mode) {
342 KnownFPClass Known = fadd(KnownSrc, KnownSrc, Mode);
343
344 // Doubling 0 will give the same 0.
345 if (KnownSrc.isKnownNeverLogicalPosZero(Mode) &&
346 (Mode.Output == DenormalMode::IEEE ||
347 (Mode.Output == DenormalMode::PreserveSign &&
348 KnownSrc.isKnownNeverPosSubnormal()) ||
349 (Mode.Output == DenormalMode::PositiveZero &&
350 KnownSrc.isKnownNeverSubnormal())))
351 Known.knownNot(fcPosZero);
352
353 return Known;
354}
355
357 const KnownFPClass &KnownRHS,
358 DenormalMode Mode) {
359 return fadd(KnownLHS, fneg(KnownRHS), Mode);
360}
361
363 const KnownFPClass &KnownRHS,
364 DenormalMode Mode) {
365 KnownFPClass Known;
366
367 // xor sign bit.
368 if ((KnownLHS.isKnownNever(fcNegative) &&
369 KnownRHS.isKnownNever(fcNegative)) ||
370 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
371 Known.knownNot(fcNegative);
372
373 if ((KnownLHS.isKnownNever(fcPositive) &&
374 KnownRHS.isKnownNever(fcNegative)) ||
375 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
376 Known.knownNot(fcPositive);
377
378 // inf * anything => inf or nan
379 if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
380 KnownRHS.isKnownAlways(fcInf | fcNan))
382
383 // 0 * anything => 0 or nan
384 if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
385 KnownLHS.isKnownAlways(fcZero | fcNan))
387
388 // +/-0 * +/-inf = nan
389 if ((KnownLHS.isKnownAlways(fcZero | fcNan) &&
390 KnownRHS.isKnownAlways(fcInf | fcNan)) ||
391 (KnownLHS.isKnownAlways(fcInf | fcNan) &&
392 KnownRHS.isKnownAlways(fcZero | fcNan)))
393 Known.knownNot(~fcNan);
394
395 if (!KnownLHS.isKnownNeverNaN() || !KnownRHS.isKnownNeverNaN())
396 return Known;
397
398 // If 0 * +/-inf produces NaN.
399 if ((KnownRHS.isKnownNeverInfinity() ||
400 KnownLHS.isKnownNeverLogicalZero(Mode)) &&
401 (KnownLHS.isKnownNeverInfinity() ||
402 KnownRHS.isKnownNeverLogicalZero(Mode)))
403 Known.knownNot(fcNan);
404
405 return Known;
406}
407
408// TODO: This generalizes to known ranges
410 const APFloat &CRHS, DenormalMode Mode) {
411 // Match denormal scaling pattern, similar to the case in ldexp. If the
412 // constant's exponent is sufficiently large, the result cannot be subnormal.
413
414 const fltSemantics &Flt = CRHS.getSemantics();
415 unsigned Precision = APFloat::semanticsPrecision(Flt);
416 const int MantissaBits = Precision - 1;
417
418 int MinKnownExponent = ilogb(CRHS);
419 bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);
420
421 KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
422 if (CannotBeSubnormal)
423 Known.knownNot(fcSubnormal);
424
425 // Multiply of values <= 1 cannot introduce overflow.
426 if (KnownLHS.isKnownNever(fcInf)) {
427 if (MinKnownExponent < 0)
428 Known.knownNot(fcInf);
429 else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
430 Flt)) == APFloat::cmpEqual)
431 Known.knownNot(fcInf);
432 }
433
434 return Known;
435}
436
438 const KnownFPClass &KnownRHS,
439 DenormalMode Mode) {
440 KnownFPClass Known;
441
442 // Only 0/0, Inf/Inf produce NaN.
443 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
444 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
445 (KnownLHS.isKnownNeverLogicalZero(Mode) ||
446 KnownRHS.isKnownNeverLogicalZero(Mode))) {
447 Known.knownNot(fcNan);
448 }
449
450 // xor sign bit.
451 // X / -0.0 is -Inf (or NaN).
452 // +X / +X is +X
453 if ((KnownLHS.isKnownNever(fcNegative) &&
454 KnownRHS.isKnownNever(fcNegative)) ||
455 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
456 Known.knownNot(fcNegative);
457
458 if ((KnownLHS.isKnownNever(fcPositive) &&
459 KnownRHS.isKnownNever(fcNegative)) ||
460 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
461 Known.knownNot(fcPositive);
462
463 // 0 / x => 0 or nan
464 if (KnownLHS.isKnownAlways(fcZero))
466
467 // x / 0 => nan or inf
468 if (KnownRHS.isKnownAlways(fcZero))
469 Known.knownNot(fcFinite);
470
471 return Known;
472}
473
475 DenormalMode Mode) {
476 // X / X is always exactly 1.0 or a NaN.
478
479 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
480 Known.knownNot(fcNan);
481 else if (KnownSrc.isKnownNever(fcSNan))
482 Known.knownNot(fcSNan);
483
484 return Known;
485}
487 DenormalMode Mode) {
488 // X % X is always exactly [+-]0.0 or a NaN.
489 KnownFPClass Known(fcNan | fcZero);
490
491 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
492 Known.knownNot(fcNan);
493 else if (KnownSrc.isKnownNever(fcSNan))
494 Known.knownNot(fcSNan);
495
496 return Known;
497}
498
500 const KnownFPClass &KnownRHS,
501 const KnownFPClass &KnownAddend,
502 DenormalMode Mode) {
503 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, Mode);
504
505 // FMA differs from the base fmul + fadd handling only in the treatment of -0
506 // results.
507 //
508 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
509 // unlike for a separate fadd.
510 return fadd_impl(Mul, KnownAddend, Mode);
511}
512
514 const KnownFPClass &KnownAddend,
515 DenormalMode Mode) {
516 KnownFPClass Squared = square(KnownSquared, Mode);
517 KnownFPClass Known = fadd_impl(Squared, KnownAddend, Mode);
518
519 // Since we know the squared input must be positive, the add of opposite sign
520 // infinities nan hazard only applies for negative inf.
521 //
522 // TODO: Alternatively to proving addend is not -inf, we could know Squared is
523 // not pinf. Other than the degenerate always-subnormal input case, we can't
524 // prove that without a known range.
525 if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
526 Known.knownNot(fcNan);
527
528 return Known;
529}
530
532 KnownFPClass Known;
533 Known.knownNot(fcNegative);
534
535 Known.propagateNaN(KnownSrc);
536
537 if (KnownSrc.cannotBeOrderedLessThanZero()) {
538 // If the source is positive this cannot underflow.
539 Known.knownNot(fcPosZero);
540
541 // Cannot introduce denormal values.
543 }
544
545 // If the source is negative, this cannot overflow to infinity.
546 if (KnownSrc.cannotBeOrderedGreaterThanZero())
547 Known.knownNot(fcPosInf);
548
549 return Known;
550}
551
553 DenormalMode Mode) {
554 propagateDenormal(Src, Mode);
555 propagateNaN(Src, /*PreserveSign=*/true);
556}
557
559 DenormalMode Mode) {
560 KnownFPClass Known;
562
563 if (KnownSrc.isKnownNeverPosInfinity())
564 Known.knownNot(fcPosInf);
565
566 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
567 Known.knownNot(fcNan);
568
569 if (KnownSrc.isKnownNeverLogicalZero(Mode))
570 Known.knownNot(fcNegInf);
571
572 return Known;
573}
574
576 DenormalMode Mode) {
577 KnownFPClass Known;
579
580 if (KnownSrc.isKnownNeverPosInfinity())
581 Known.knownNot(fcPosInf);
582 if (KnownSrc.isKnownNever(fcSNan))
583 Known.knownNot(fcSNan);
584
585 // Any negative value besides -0 returns a nan.
586 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
587 Known.knownNot(fcNan);
588
589 // The only negative value that can be returned is -0 for -0 inputs.
591
592 // If the input denormal mode could be PreserveSign, a negative
593 // subnormal input could produce a negative zero output.
594 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
595 Known.knownNot(fcNegZero);
596
597 return Known;
598}
599
601 KnownFPClass Known;
602
603 // Return NaN on infinite inputs.
604 Known.knownNot(fcInf);
605 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
606 Known.knownNot(fcNan);
607
608 return Known;
609}
610
612 return sin(KnownSrc);
613}
614
616 const fltSemantics &DstTy,
617 const fltSemantics &SrcTy) {
618 // Infinity, nan and zero propagate from source.
619 KnownFPClass Known = KnownSrc;
620
621 // All subnormal inputs should be in the normal range in the result type.
622 if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
623 if (Known.KnownFPClasses & fcPosSubnormal)
625 if (Known.KnownFPClasses & fcNegSubnormal)
627 Known.knownNot(fcSubnormal);
628 }
629
630 // Sign bit of a nan isn't guaranteed.
631 if (!Known.isKnownNeverNaN())
632 Known.SignBit = std::nullopt;
633
634 return Known;
635}
636
638 KnownFPClass Known;
639
640 // Sign should be preserved
641 // TODO: Handle cannot be ordered greater than zero
642 if (KnownSrc.cannotBeOrderedLessThanZero())
644
645 Known.propagateNaN(KnownSrc, true);
646
647 // Infinity needs a range check.
648 return Known;
649}
650
652 bool IsTrunc,
653 bool IsMultiUnitFPType) {
654 KnownFPClass Known;
655
656 // Integer results cannot be subnormal.
657 Known.knownNot(fcSubnormal);
658
659 Known.propagateNaN(KnownSrc, true);
660
661 // Pass through infinities, except PPC_FP128 is a special case for
662 // intrinsics other than trunc.
663 if (IsTrunc || !IsMultiUnitFPType) {
664 if (KnownSrc.isKnownNeverPosInfinity())
665 Known.knownNot(fcPosInf);
666 if (KnownSrc.isKnownNeverNegInfinity())
667 Known.knownNot(fcNegInf);
668 }
669
670 // Negative round ups to 0 produce -0
671 if (KnownSrc.isKnownNever(fcPosFinite))
672 Known.knownNot(fcPosFinite);
673 if (KnownSrc.isKnownNever(fcNegFinite))
674 Known.knownNot(fcNegFinite);
675
676 return Known;
677}
678
680 DenormalMode Mode) {
681 KnownFPClass Known;
682 Known.knownNot(fcSubnormal);
683
684 if (KnownSrc.isKnownNever(fcNegative))
685 Known.knownNot(fcNegative);
686 else {
687 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
688 Known.knownNot(fcNegZero);
689 if (KnownSrc.isKnownNever(fcNegInf))
690 Known.knownNot(fcNegInf);
691 }
692
693 if (KnownSrc.isKnownNever(fcPositive))
694 Known.knownNot(fcPositive);
695 else {
696 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
697 Known.knownNot(fcPosZero);
698 if (KnownSrc.isKnownNever(fcPosInf))
699 Known.knownNot(fcPosInf);
700 }
701
702 Known.propagateNaN(KnownSrc);
703 return Known;
704}
705
707 const KnownBits &ExpBits,
708 const fltSemantics &Flt, DenormalMode Mode) {
709 KnownFPClass Known;
710 Known.propagateNaN(KnownSrc, /*PropagateSign=*/true);
711
712 // Sign is preserved, but underflows may produce zeroes.
713 if (KnownSrc.isKnownNever(fcNegative))
714 Known.knownNot(fcNegative);
715 else if (KnownSrc.cannotBeOrderedLessThanZero())
717
718 if (KnownSrc.isKnownNever(fcPositive))
719 Known.knownNot(fcPositive);
720 else if (KnownSrc.cannotBeOrderedGreaterThanZero())
722
723 unsigned Precision = APFloat::semanticsPrecision(Flt);
724 const int MantissaBits = Precision - 1;
725
726 if (ExpBits.getSignedMinValue().sge(static_cast<int64_t>(MantissaBits)))
727 Known.knownNot(fcSubnormal);
728
729 if (ExpBits.isConstant() && ExpBits.getConstant().isZero()) {
730 // ldexp(x, 0) -> x, so propagate everything.
731 Known.propagateCanonicalizingSrc(KnownSrc, Mode);
732 } else if (ExpBits.isNegative()) {
733 // If we know the power is <= 0, can't introduce inf
734 if (KnownSrc.isKnownNeverPosInfinity())
735 Known.knownNot(fcPosInf);
736 if (KnownSrc.isKnownNeverNegInfinity())
737 Known.knownNot(fcNegInf);
738 } else if (ExpBits.isNonNegative()) {
739 // If we know the power is >= 0, can't introduce subnormal or zero
740 if (KnownSrc.isKnownNeverPosSubnormal())
742 if (KnownSrc.isKnownNeverNegSubnormal())
744 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
745 Known.knownNot(fcPosZero);
746 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
747 Known.knownNot(fcNegZero);
748 }
749
750 return Known;
751}
752
753// TODO: Detect no-infinity cases
755 const KnownBits &ExponentKnownBits) {
756 KnownFPClass Known;
757 Known.propagateNaN(KnownSrc);
758
759 if (ExponentKnownBits.isZero()) {
760 // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
761 // return 1.0 or a NaN.
762 if (KnownSrc.isKnownNever(fcSNan)) {
763 Known.knownNot(~fcPosNormal);
764 return Known;
765 }
766
767 Known.knownNot(~(fcPosNormal | fcNan));
768 return Known;
769 }
770
771 if (ExponentKnownBits.isEven()) {
772 Known.knownNot(fcNegative);
773 return Known;
774 }
775
776 // Given that exp is an integer, here are the
777 // ways that pow can return a negative value:
778 //
779 // pow(-x, exp) --> negative if exp is odd and x is negative.
780 // pow(-0, exp) --> -inf if exp is negative odd.
781 // pow(-0, exp) --> -0 if exp is positive odd.
782 // pow(-inf, exp) --> -0 if exp is negative odd.
783 // pow(-inf, exp) --> -inf if exp is positive odd.
784 if (KnownSrc.isKnownNever(fcNegative))
785 Known.knownNot(fcNegative);
786
787 return Known;
788}
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 KnownFPClass fadd_impl(const KnownFPClass &KnownLHS, const KnownFPClass &KnownRHS, DenormalMode Mode)
static bool inputDenormalIsIEEE(DenormalMode Mode)
Return true if it's possible to assume IEEE treatment of input denormals in F for Val.
static bool inputDenormalIsIEEEOrPosZero(DenormalMode Mode)
static 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:214
static LLVM_ABI bool isRepresentableAsNormalIn(const fltSemantics &Src, const fltSemantics &Dst)
Definition APFloat.cpp:264
static LLVM_ABI bool isIEEELikeFP(const fltSemantics &)
Definition APFloat.cpp:255
cmpResult compareAbsoluteValue(const APFloat &RHS) const
Definition APFloat.h:1471
const fltSemantics & getSemantics() const
Definition APFloat.h:1524
bool isNaN() const
Definition APFloat.h:1514
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
Definition APFloat.h:1143
static APFloat getInf(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Infinity.
Definition APFloat.h:1153
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Definition APFloat.h:1134
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition APInt.h:381
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
Definition APInt.h:1244
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
int ilogb(const APFloat &Arg)
Returns the exponent of the internal representation of the APFloat.
Definition APFloat.h:1601
@ Mul
Product of integers.
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
constexpr bool outputsAreZero() const
Return true if output denormals should be flushed to 0.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
@ Dynamic
Denormals have unknown treatment.
@ IEEE
IEEE-754 denormal numbers preserved.
static constexpr DenormalMode getPositiveZero()
constexpr bool inputsAreZero() const
Return true if input denormals must be implicitly treated as 0.
static constexpr DenormalMode getPreserveSign()
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static constexpr DenormalMode getIEEE()
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
Definition KnownBits.h:317
static LLVM_ABI std::optional< bool > eq(const KnownBits &LHS, const KnownBits &RHS)
Determine if these known bits always give the same ICMP_EQ result.
bool isNonNegative() const
Returns true if this value is known to be non-negative.
Definition KnownBits.h:108
bool isZero() const
Returns true if value is all zero.
Definition KnownBits.h:80
bool isConstant() const
Returns true if we know the value of all bits.
Definition KnownBits.h:54
bool isEven() const
Return if the value is known even (the low bit is 0).
Definition KnownBits.h:164
bool isNegative() const
Returns true if this value is known to be negative.
Definition KnownBits.h:105
APInt getSignedMinValue() const
Return the minimal signed value possible given these KnownBits.
Definition KnownBits.h:138
const APInt & getConstant() const
Returns the value when all bits have a known value.
Definition KnownBits.h:60
bool isKnownNeverInfOrNaN() const
Return true if it's known this can never be an infinity or nan.
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
bool isKnownNeverInfinity() const
Return true if it's known this can never be an infinity.
KnownFPClass(FPClassTest Known=fcAllFlags, std::optional< bool > Sign={})
bool cannotBeOrderedGreaterThanZero() const
Return true if we can prove that the analyzed floating-point value is either NaN or never greater tha...
static LLVM_ABI KnownFPClass sin(const KnownFPClass &Src)
Report known values for sin.
static LLVM_ABI KnownFPClass fdiv_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv x, x.
static constexpr FPClassTest OrderedGreaterThanZeroMask
static constexpr FPClassTest OrderedLessThanZeroMask
void knownNot(FPClassTest RuleOut)
static LLVM_ABI KnownFPClass fmul(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fmul.
static LLVM_ABI KnownFPClass fadd_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd x, x.
bool isKnownNeverZero() const
Return true if it's known this can never be a zero.
static KnownFPClass square(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
static LLVM_ABI KnownFPClass fsub(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fsub.
bool isKnownNeverSubnormal() const
Return true if it's known this can never be a subnormal.
bool isKnownAlways(FPClassTest Mask) const
static LLVM_ABI KnownFPClass canonicalize(const KnownFPClass &Src, DenormalMode DenormMode=DenormalMode::getDynamic())
Apply the canonicalize intrinsic to this value.
LLVM_ABI bool isKnownNeverLogicalZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a zero.
static LLVM_ABI KnownFPClass log(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for log/log2/log10.
LLVM_ABI void propagateDenormal(const KnownFPClass &Src, DenormalMode Mode)
Propagate knowledge from a source value that could be a denormal or zero.
static LLVM_ABI KnownFPClass fdiv(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fdiv.
static LLVM_ABI KnownFPClass roundToIntegral(const KnownFPClass &Src, bool IsTrunc, bool IsMultiUnitFPType)
Propagate known class for rounding intrinsics (trunc, floor, ceil, rint, nearbyint,...
static LLVM_ABI KnownFPClass cos(const KnownFPClass &Src)
Report known values for cos.
static LLVM_ABI KnownFPClass ldexp(const KnownFPClass &Src, const KnownBits &N, const fltSemantics &Flt, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for ldexp.
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.
std::optional< bool > SignBit
std::nullopt if the sign bit is unknown, true if the sign bit is definitely set or false if the sign ...
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.
static LLVM_ABI KnownFPClass fpext(const KnownFPClass &KnownSrc, const fltSemantics &DstTy, const fltSemantics &SrcTy)
Propagate known class for fpext.
bool isKnownNeverNegZero() const
Return true if it's known this can never be a negative zero.
static LLVM_ABI KnownFPClass fma(const KnownFPClass &LHS, const KnownFPClass &RHS, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma.
void propagateNaN(const KnownFPClass &Src, bool PreserveSign=false)
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 -...
void signBitMustBeOne()
Assume the sign bit is one.
LLVM_ABI void propagateCanonicalizingSrc(const KnownFPClass &Src, DenormalMode Mode)
Report known classes if Src is evaluated through a potentially canonicalizing operation.
void signBitMustBeZero()
Assume the sign bit is zero.
static LLVM_ABI KnownFPClass sqrt(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for sqrt.
LLVM_ABI bool isKnownNeverLogicalPosZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a positive zero.
bool isKnownNeverPosInfinity() const
Return true if it's known this can never be +infinity.
static LLVM_ABI KnownFPClass fadd(const KnownFPClass &LHS, const KnownFPClass &RHS, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fadd.
LLVM_ABI bool isKnownNeverLogicalNegZero(DenormalMode Mode) const
Return true if it's known this can never be interpreted as a negative zero.
static LLVM_ABI KnownFPClass bitcast(const fltSemantics &FltSemantics, const KnownBits &Bits)
Report known values for a bitcast into a float with provided semantics.
static LLVM_ABI KnownFPClass fma_square(const KnownFPClass &Squared, const KnownFPClass &Addend, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for fma squared, squared, addend.
static LLVM_ABI KnownFPClass frem_self(const KnownFPClass &Src, DenormalMode Mode=DenormalMode::getDynamic())
Report known values for frem.
static LLVM_ABI KnownFPClass powi(const KnownFPClass &Src, const KnownBits &N)
Propagate known class for powi.
bool isKnownNeverPosSubnormal() const
Return true if it's known this can never be a positive subnormal.
unsigned int sizeInBits
Definition APFloat.h:1007