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 DenormalMode Mode) {
106 setKnownFPClasses(Src.getKnownFPClasses());
107 // If we aren't assuming the source can't be a zero, we don't have to check if
108 // a denormal input could be flushed.
109 if (!Src.isKnownNeverPosZero() && !Src.isKnownNeverNegZero())
110 return;
111
112 // If we know the input can't be a denormal, it can't be flushed to 0.
113 if (Src.isKnownNeverSubnormal())
114 return;
115
116 if (!Src.isKnownNeverPosSubnormal() && Mode != DenormalMode::getIEEE())
118
119 if (!Src.isKnownNeverNegSubnormal() && Mode != DenormalMode::getIEEE()) {
120 if (Mode != DenormalMode::getPositiveZero())
122
123 if (Mode.Input == DenormalMode::PositiveZero ||
124 Mode.Output == DenormalMode::PositiveZero ||
125 Mode.Input == DenormalMode::Dynamic ||
126 Mode.Output == DenormalMode::Dynamic)
128 }
129}
130
132 const KnownFPClass &RHS_, MinMaxKind Kind,
133 DenormalMode Mode) {
134 KnownFPClass KnownLHS = LHS_;
135 KnownFPClass KnownRHS = RHS_;
136
137 bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
138 KnownFPClass Known = KnownLHS | KnownRHS;
139
140 // If either operand is not NaN, the result is not NaN.
141 if (NeverNaN &&
142 (Kind == MinMaxKind::minnum || Kind == MinMaxKind::maxnum ||
144 Known.knownNot(fcNan);
145
146 if (Kind == MinMaxKind::maxnum || Kind == MinMaxKind::maximumnum) {
147 if (KnownLHS.isKnownNeverNaN())
148 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses()));
149 if (KnownRHS.isKnownNeverNaN())
150 Known.knownNot(orderedStrictlyLess(KnownRHS.getKnownFPClasses()));
151 } else if (Kind == MinMaxKind::maximum) {
152 Known.knownNot(orderedStrictlyLess(KnownLHS.getKnownFPClasses()) |
154 } else if (Kind == MinMaxKind::minnum || Kind == MinMaxKind::minimumnum) {
155 if (KnownLHS.isKnownNeverNaN())
156 Known.knownNot(orderedStrictlyGreater(KnownLHS.getKnownFPClasses()));
157 if (KnownRHS.isKnownNeverNaN())
158 Known.knownNot(orderedStrictlyGreater(KnownRHS.getKnownFPClasses()));
159 } else if (Kind == MinMaxKind::minimum) {
160 Known.knownNot(orderedStrictlyGreater(KnownLHS.getKnownFPClasses()) |
162 } else
163 llvm_unreachable("unhandled intrinsic");
164
165 // Fixup zero handling if denormals could be returned as a zero.
166 //
167 // As there's no spec for denormal flushing, be conservative with the
168 // treatment of denormals that could be flushed to zero. For older
169 // subtargets on AMDGPU the min/max instructions would not flush the
170 // output and return the original value.
171 //
172 if ((Known.getKnownFPClasses() & fcZero) != fcNone &&
173 !Known.isKnownNeverSubnormal()) {
174 if (Mode != DenormalMode::getIEEE())
175 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcZero);
176 }
177
178 if (Known.isKnownNeverNaN()) {
179 if (KnownLHS.getSignBit() && KnownRHS.getSignBit() &&
180 *KnownLHS.getSignBit() == *KnownRHS.getSignBit()) {
181 if (*KnownLHS.getSignBit())
182 Known.signBitMustBeOne();
183 else
184 Known.signBitMustBeZero();
185 } else if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::minimum ||
186 Kind == MinMaxKind::maximumnum ||
187 Kind == MinMaxKind::minimumnum) ||
188 // FIXME: Should be using logical zero versions
189 ((KnownLHS.isKnownNeverNegZero() ||
190 KnownRHS.isKnownNeverPosZero()) &&
191 (KnownLHS.isKnownNeverPosZero() ||
192 KnownRHS.isKnownNeverNegZero()))) {
193 // Don't take sign bit from NaN operands.
194 if (!KnownLHS.isKnownNeverNaN())
195 KnownLHS.setSignBit(std::nullopt);
196 if (!KnownRHS.isKnownNeverNaN())
197 KnownRHS.setSignBit(std::nullopt);
198 if ((Kind == MinMaxKind::maximum || Kind == MinMaxKind::maximumnum ||
199 Kind == MinMaxKind::maxnum) &&
200 (KnownLHS.getSignBit() == false || KnownRHS.getSignBit() == false))
201 Known.signBitMustBeZero();
202 else if ((Kind == MinMaxKind::minimum || Kind == MinMaxKind::minimumnum ||
203 Kind == MinMaxKind::minnum) &&
204 (KnownLHS.getSignBit() == true || KnownRHS.getSignBit() == true))
205 Known.signBitMustBeOne();
206 }
207 }
208
209 return Known;
210}
211
213 DenormalMode DenormMode) {
215
216 // This is essentially a stronger form of
217 // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
218 // actually have an IR canonicalization guarantee.
219
220 // Canonicalize may flush denormals to zero, so we have to consider the
221 // denormal mode to preserve known-not-0 knowledge.
222 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcZero | fcQNan);
223
224 // Stronger version of propagateNaN
225 // Canonicalize is guaranteed to quiet signaling nans.
226 if (KnownSrc.isKnownNeverNaN())
227 Known.knownNot(fcNan);
228 else
229 Known.knownNot(fcSNan);
230
231 // FIXME: Missing check of IEEE like types.
232
233 // If the parent function flushes denormals, the canonical output cannot be a
234 // denormal.
235 if (DenormMode == DenormalMode::getIEEE()) {
236 if (KnownSrc.isKnownNever(fcPosZero))
237 Known.knownNot(fcPosZero);
238 if (KnownSrc.isKnownNever(fcNegZero))
239 Known.knownNot(fcNegZero);
240 return Known;
241 }
242
243 if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
244 Known.knownNot(fcSubnormal);
245
246 if (DenormMode == DenormalMode::getPreserveSign()) {
247 if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
248 Known.knownNot(fcPosZero);
249 if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
250 Known.knownNot(fcNegZero);
251 return Known;
252 }
253
254 if (DenormMode.Input == DenormalMode::PositiveZero ||
255 (DenormMode.Output == DenormalMode::PositiveZero &&
256 DenormMode.Input == DenormalMode::IEEE)) {
257 // -0.0 is not a subnormal and should not be flushed.
258 if (KnownSrc.isKnownNever(fcNegZero))
259 Known.knownNot(fcNegZero);
260
261 if (KnownSrc.isKnownNever(fcPosZero | fcSubnormal))
262 Known.knownNot(fcPosZero);
263 }
264
265 return Known;
266}
267
269 const KnownBits &Bits) {
270 assert(FltSemantics.sizeInBits == Bits.getBitWidth() &&
271 "Bitcast operand has incorrect bit width");
273
274 // Conflicting known bits do not describe a concrete value. Return unknown.
275 if (Bits.hasConflict())
276 return Known;
277
278 // Return unknown for types we have not validated.
279 auto IsSupported = [](const fltSemantics &Semantics) {
280 switch (APFloat::SemanticsToEnum(Semantics)) {
287 return true;
288 default:
289 return false;
290 }
291 };
292 if (!IsSupported(FltSemantics))
293 return Known;
294
295 // Transfer information from the sign bit.
296 if (Bits.isNonNegative())
297 Known.signBitMustBeZero();
298 else if (Bits.isNegative())
299 Known.signBitMustBeOne();
300
301 if (APFloat::isIEEELikeFP(FltSemantics)) {
302 const unsigned MantissaBits = FltSemantics.precision - 1;
303 const APInt ExponentMask = APInt::getBitsSet(
304 FltSemantics.sizeInBits, MantissaBits, FltSemantics.sizeInBits - 1);
305 const APInt MantissaMask =
306 APInt::getLowBitsSet(FltSemantics.sizeInBits, MantissaBits);
307
308 const bool ExponentKnownAllZeros =
309 (Bits.Zero & ExponentMask) == ExponentMask;
310 const bool ExponentKnownAllOnes = (Bits.One & ExponentMask) == ExponentMask;
311 const bool ExponentKnownNotAllZeros = !(Bits.One & ExponentMask).isZero();
312 const bool ExponentKnownNotAllOnes = !(Bits.Zero & ExponentMask).isZero();
313
314 const bool MantissaKnownAllZeros =
315 (Bits.Zero & MantissaMask) == MantissaMask;
316 const bool MantissaKnownNotAllZeros = !(Bits.One & MantissaMask).isZero();
317
318 // Zero and subnormal require an exponent with all zero bits.
319 if (ExponentKnownNotAllZeros)
320 Known.knownNot(fcZero | fcSubnormal);
321
322 // Infinity and NaN require an exponent with all one bits.
323 if (ExponentKnownNotAllOnes)
324 Known.knownNot(fcInf | fcNan);
325
326 // Normal values have an exponent that is not all zeros or all ones.
327 if (ExponentKnownAllZeros || ExponentKnownAllOnes)
328 Known.knownNot(fcNormal);
329
330 // Zero and infinity require a mantissa with all zero bits.
331 if (MantissaKnownNotAllZeros)
332 Known.knownNot(fcZero | fcInf);
333
334 // Subnormal and NaN require a non-zero mantissa.
335 if (MantissaKnownAllZeros)
336 Known.knownNot(fcSubnormal | fcNan);
337
338 const bool QuietBitKnownSet = Bits.One[MantissaBits - 1];
339 const bool QuietBitKnownClear = Bits.Zero[MantissaBits - 1];
340
341 if (QuietBitKnownSet)
342 Known.knownNot(fcSNan);
343 else if (QuietBitKnownClear)
344 Known.knownNot(fcQNan);
345 }
346
347 return Known;
348}
349
351 KnownBits Known(FltSemantics.sizeInBits);
352 const FPClassTest FPClasses = getKnownFPClasses();
353
354 // Return unknown if poison.
355 if (FPClasses == fcNone)
356 return Known;
357
358 // Return unknown for types we have not validated.
359 auto IsSupported = [](const fltSemantics &Semantics) {
360 switch (APFloat::SemanticsToEnum(Semantics)) {
367 return true;
368 default:
369 return false;
370 }
371 };
372 if (!IsSupported(FltSemantics))
373 return Known;
374
375 switch (APFloat::SemanticsToEnum(FltSemantics)) {
381 // For ieee types, we cannot deduce anything if the source could be normal.
382 if (FPClasses & fcNormal)
383 break;
384
385 Known.setAllConflict();
386
387 const unsigned BitWidth = FltSemantics.sizeInBits;
388 const unsigned MantissaBits = FltSemantics.precision - 1;
389 const unsigned ExponentBits = BitWidth - MantissaBits - 1;
390
391 APInt MantissaMask = APInt::getLowBitsSet(BitWidth, MantissaBits);
392 APInt ExponentMask =
393 APInt::getBitsSet(BitWidth, MantissaBits, MantissaBits + ExponentBits);
394
395 const unsigned QuietBitIndex = MantissaBits - 1;
396 APInt PayloadMask = MantissaMask;
397 PayloadMask.clearBit(QuietBitIndex);
398
399 if (FPClasses & fcNan) {
400 // Exponent bits cannot be zeros.
401 Known.Zero &= ~ExponentMask;
402 // No individual payload bit is known.
403 Known.Zero &= ~PayloadMask;
404 Known.One &= ~PayloadMask;
405
406 if (FPClasses & fcQNan)
407 Known.Zero.clearBit(QuietBitIndex);
408 if (FPClasses & fcSNan)
409 Known.One.clearBit(QuietBitIndex);
410 }
411 if (FPClasses & fcInf) {
412 // Exponent bits cannot be zeros.
413 Known.Zero &= ~ExponentMask;
414 // Mantissa bits cannot be ones.
415 Known.One &= ~MantissaMask;
416 }
417 if (FPClasses & fcSubnormal) {
418 // Exponent bits cannot be ones.
419 Known.One &= ~ExponentMask;
420 // Unknown mantissa.
421 Known.One &= ~MantissaMask;
422 Known.Zero &= ~MantissaMask;
423 }
424 if (FPClasses & fcZero) {
425 // Exponent bits cannot be ones.
426 Known.One &= ~ExponentMask;
427 // Mantissa cannot be ones.
428 Known.One &= ~MantissaMask;
429 }
430
431 break;
432 }
435 break;
436
437 Known.setAllConflict();
438
439 if (FPClasses & fcInf)
440 Known = Known.intersectWith(KnownBits::makeConstant(
441 APFloat::getInf(FltSemantics).bitcastToAPInt()));
442
443 if (FPClasses & fcZero)
444 Known = Known.intersectWith(
446
447 break;
448 }
449 default:
450 llvm_unreachable("unhandled supported semantics");
451 }
452
453 Known.Zero.clearSignBit();
454 Known.One.clearSignBit();
455 if (std::optional<bool> Sign = getSignBit()) {
456 if (*Sign)
457 Known.makeNegative();
458 else
459 Known.makeNonNegative();
460 }
461
462 return Known;
463}
464
465// Handle known sign bit and nan cases for fadd.
466static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
467 const KnownFPClass &KnownRHS, DenormalMode Mode) {
469
470 // Adding positive and negative infinity produces NaN, but only if both
471 // opposite-sign infinity combinations are possible.
472 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
473 (KnownLHS.isKnownNever(fcPosInf) || KnownRHS.isKnownNever(fcNegInf)) &&
474 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosInf)))
475 Known.knownNot(fcNan);
476
477 if (KnownLHS.cannotBeOrderedLessThanZero() &&
478 KnownRHS.cannotBeOrderedLessThanZero()) {
480
481 // This can't underflow if one of the operands is known normal.
482 if (KnownLHS.isKnownNever(fcZero | fcPosSubnormal) ||
484 Known.knownNot(fcZero | fcPosSubnormal);
485 }
486
487 if (KnownLHS.cannotBeOrderedGreaterThanZero() &&
490
491 // This can't underflow if one of the operands is known normal.
492 if (KnownLHS.isKnownNever(fcZero | fcNegSubnormal) ||
494 Known.knownNot(fcZero | fcNegSubnormal);
495 }
496
497 return Known;
498}
499
501 const KnownFPClass &KnownRHS,
502 DenormalMode Mode) {
503 KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, Mode);
504
505 // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
506 if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
507 KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
508 // Make sure output negative denormal can't flush to -0
509 (Mode.Output == DenormalMode::IEEE ||
510 Mode.Output == DenormalMode::PositiveZero))
511 Known.knownNot(fcNegZero);
512
513 Known.propagateNonSNaN(KnownLHS, KnownRHS);
514
515 return Known;
516}
517
519 DenormalMode Mode) {
520 KnownFPClass Known = fadd(KnownSrc, KnownSrc, Mode);
521
522 // Doubling 0 will give the same 0.
523 if (KnownSrc.isKnownNeverLogicalPosZero(Mode) &&
524 (Mode.Output == DenormalMode::IEEE ||
525 (Mode.Output == DenormalMode::PreserveSign &&
526 KnownSrc.isKnownNeverPosSubnormal()) ||
527 (Mode.Output == DenormalMode::PositiveZero &&
528 KnownSrc.isKnownNeverSubnormal())))
529 Known.knownNot(fcPosZero);
530
531 return Known;
532}
533
535 const KnownFPClass &KnownRHS,
536 DenormalMode Mode) {
537 return fadd(KnownLHS, fneg(KnownRHS), Mode);
538}
539
541 const KnownFPClass &KnownRHS_,
542 DenormalMode Mode) {
543 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
544 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
545
547
548 Known.propagateNonSNaN(KnownLHS, KnownRHS);
549
550 // +X * +Y or -X * -Y => +Q
551 // +X * -Y or -X * +Y => -Q
552 if ((KnownLHS.isKnownNever(fcNegative) &&
553 KnownRHS.isKnownNever(fcNegative)) ||
554 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
555 Known.knownNot(fcNegative);
556 if ((KnownLHS.isKnownNever(fcPositive) &&
557 KnownRHS.isKnownNever(fcNegative)) ||
558 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
559 Known.knownNot(fcPositive);
560
561 // Inf * Y => Inf or NaN
562 if (KnownLHS.isKnownAlways(fcInf | fcNan) ||
563 KnownRHS.isKnownAlways(fcInf | fcNan))
564 Known.knownNot(fcNormal | fcSubnormal | fcZero);
565
566 // 0 * Y => 0 or NaN
567 if (KnownRHS.isKnownAlways(fcZero | fcNan) ||
568 KnownLHS.isKnownAlways(fcZero | fcNan))
569 Known.knownNot(fcNormal | fcSubnormal | fcInf);
570
571 // 0 * +/-inf => NaN
572 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
573 (KnownRHS.isKnownNeverInfinity() || KnownLHS.isKnownNeverZero()) &&
574 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverZero()))
575 Known.knownNot(fcNan);
576
577 return applyOutputDenormalMode(Known, Mode);
578}
579
580// TODO: This generalizes to known ranges
582 const APFloat &CRHS, DenormalMode Mode) {
583 // Match denormal scaling pattern, similar to the case in ldexp. If the
584 // constant's exponent is sufficiently large, the result cannot be subnormal.
585
586 const fltSemantics &Flt = CRHS.getSemantics();
587 unsigned Precision = APFloat::semanticsPrecision(Flt);
588 const int MantissaBits = Precision - 1;
589
590 int MinKnownExponent = ilogb(CRHS);
591 bool CannotBeSubnormal = (MinKnownExponent >= MantissaBits);
592
593 KnownFPClass Known = KnownFPClass::fmul(KnownLHS, KnownFPClass(CRHS), Mode);
594 if (CannotBeSubnormal)
595 Known.knownNot(fcSubnormal);
596
597 // Multiply of values <= 1 cannot introduce overflow.
598 if (KnownLHS.isKnownNever(fcInf)) {
599 if (MinKnownExponent < 0)
600 Known.knownNot(fcInf);
601 else if (MinKnownExponent == 0 && CRHS.compareAbsoluteValue(APFloat::getOne(
602 Flt)) == APFloat::cmpEqual)
603 Known.knownNot(fcInf);
604 }
605
606 return Known;
607}
608
610 const KnownFPClass &KnownRHS_,
611 DenormalMode Mode) {
612 KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
613 KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
614
616
617 Known.propagateNonSNaN(KnownLHS, KnownRHS);
618
619 // Only 0/0, Inf/Inf produce NaN.
620 if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
621 (KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
622 (KnownLHS.isKnownNeverZero() || KnownRHS.isKnownNeverZero())) {
623 Known.knownNot(fcNan);
624 }
625
626 // X / -0.0 => -Inf (or NaN)
627 // +X / +Y or -X / -Y => +Q
628 // +X / -Y or -X / +Y => -Q
629 if ((KnownLHS.isKnownNever(fcNegative) &&
630 KnownRHS.isKnownNever(fcNegative)) ||
631 (KnownLHS.isKnownNever(fcPositive) && KnownRHS.isKnownNever(fcPositive)))
632 Known.knownNot(fcNegative);
633 if ((KnownLHS.isKnownNever(fcPositive) &&
634 KnownRHS.isKnownNever(fcNegative)) ||
635 (KnownLHS.isKnownNever(fcNegative) && KnownRHS.isKnownNever(fcPositive)))
636 Known.knownNot(fcPositive);
637
638 // Normal and subnormal results require two non-zero finite operands.
639 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
643 Known.knownNot(fcNegNormal | fcNegSubnormal);
644 if ((KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal) &&
648 Known.knownNot(fcPosNormal | fcPosSubnormal);
649
650 // 0 / X => 0 or NaN
651 if (KnownLHS.isKnownAlways(fcZero))
652 Known.knownNot(fcSubnormal | fcNormal | fcInf);
653
654 // X / 0 => NaN or Inf
655 if (KnownRHS.isKnownAlways(fcZero))
656 Known.knownNot(fcFinite);
657
658 return applyOutputDenormalMode(Known, Mode);
659}
660
662 DenormalMode Mode) {
663 // X / X is always exactly 1.0 or a NaN.
665
666 Known.propagateNonSNaN(KnownSrc);
667
668 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
669 Known.knownNot(fcNan);
670
671 return Known;
672}
673
675 const KnownFPClass &KnownRHS,
676 DenormalMode Mode) {
678
679 // We are assuming that frem(x, Inf) is already handled elsewhere.
680
681 Known.knownNot(fcInf);
682
683 Known.propagateNonSNaN(KnownLHS, KnownRHS);
684
685 // frem(Inf, x) and frem(x, 0) produce NaN.
686 if (KnownLHS.isKnownNeverInfOrNaN() && KnownRHS.isKnownNeverNaN() &&
687 KnownRHS.isKnownNeverLogicalZero(Mode)) {
688 Known.knownNot(fcNan);
689 }
690
691 // The sign for frem is the same as the first operand.
693 Known.knownNot(fcPosNormal | fcPosSubnormal);
695 Known.knownNot(fcNegNormal | fcNegSubnormal);
696
697 // A negative zero result requires a negative finite first operand.
698 if (KnownLHS.isKnownNever(fcNegFinite))
699 Known.knownNot(fcNegZero);
700
701 // A positive zero result can additionally come from a negative finite
702 // result being flushed to positive zero.
703 if (KnownLHS.isKnownNever(fcPosFinite) &&
704 KnownLHS.isKnownNeverLogicalPosZero(Mode) &&
705 (!Mode.outputsMayBePositiveZero() ||
707 Known.knownNot(fcPosZero);
708
709 return Known;
710}
711
713 DenormalMode Mode) {
714 // X % X is always exactly [+-]0.0 or a NaN.
716
717 Known.propagateNonSNaN(KnownSrc);
718
719 if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
720 Known.knownNot(fcNan);
721
722 // The sign of a zero result is the sign of the finite non-zero input.
723 // We do not have to worry about subnormal values flushing to zero, since
724 // frem(+-0.0, +-0.0) = NaN.
726 Known.knownNot(fcPosZero);
728 Known.knownNot(fcNegZero);
729
730 return Known;
731}
732
734 const KnownFPClass &KnownRHS,
735 const KnownFPClass &KnownAddend,
736 DenormalMode Mode) {
737 KnownFPClass Mul = fmul(KnownLHS, KnownRHS, Mode);
738
739 // FMA differs from the base fmul + fadd handling only in the treatment of -0
740 // results.
741 //
742 // If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
743 // unlike for a separate fadd.
744 KnownFPClass Known = fadd_impl(Mul, KnownAddend, Mode);
745
746 // propagateNonSNaN for 3 arguments.
747 if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
748 KnownAddend.isKnownNever(fcSNan))
749 Known.knownNot(fcSNan);
750
751 return Known;
752}
753
755 const KnownFPClass &KnownAddend,
756 DenormalMode Mode) {
757 KnownFPClass Squared = square(KnownSquared, Mode);
758 KnownFPClass Known = fadd_impl(Squared, KnownAddend, Mode);
759
760 // Since we know the squared input must be positive, the add of opposite sign
761 // infinities nan hazard only applies for negative inf.
762 //
763 // TODO: Alternatively to proving addend is not -inf, we could know Squared is
764 // not pinf. Other than the degenerate always-subnormal input case, we can't
765 // prove that without a known range.
766 if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
767 Known.knownNot(fcNan);
768
769 Known.propagateNonSNaN(KnownSquared, KnownAddend);
770
771 return Known;
772}
773
776 Known.knownNot(fcNegative);
777
778 Known.propagateNonNaN(KnownSrc);
779
780 // The following deductions assume that exp10(-1.0) = +0.1 and
781 // exp10(+1.0) = +10.0 are both finite normal values.
782
783 // Zero can only be produced if x < -1.0.
784 if (KnownSrc.isKnownNever(fcNegNormal | fcNegInf))
785 Known.knownNot(fcPosZero);
786
787 // Subnormals can only be produced if x < -1.0 and x is finite.
788 if (KnownSrc.isKnownNever(fcNegNormal))
789 Known.knownNot(fcPosSubnormal);
790
791 // Infinity can only be produced if x > +1.0.
792 if (KnownSrc.isKnownNever(fcPosNormal | fcPosInf))
793 Known.knownNot(fcPosInf);
794
795 return Known;
796}
797
803
805 bool IsMultiUnitFPType) {
807
808 // PPCDoubleDouble can represent the exact value of 1.0 + subnormal, and
809 // log(1.0 + subnormal) = subnormal.
810 if (!IsMultiUnitFPType)
811 Known.knownNot(fcNegZero | fcSubnormal);
812
813 Known.propagateNonSNaN(KnownSrc);
814
815 if (KnownSrc.isKnownNeverPosInfinity())
816 Known.knownNot(fcPosInf);
817
818 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
819 Known.knownNot(fcNan);
820
821 if (KnownSrc.isKnownNeverLogicalZero(Mode))
822 Known.knownNot(fcNegInf);
823
824 return Known;
825}
826
828 DenormalMode Mode) {
830 Known.knownNot(fcPosSubnormal);
831
832 if (KnownSrc.isKnownNeverPosInfinity())
833 Known.knownNot(fcPosInf);
834
835 Known.propagateNonSNaN(KnownSrc);
836
837 // Any negative value besides -0 returns a nan.
838 if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
839 Known.knownNot(fcNan);
840
841 // The only negative value that can be returned is -0 for -0 inputs.
843
844 // If the input denormal mode could be PreserveSign, a negative
845 // subnormal input could produce a negative zero output.
846 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
847 Known.knownNot(fcNegZero);
848
849 return Known;
850}
851
854
855 Known.propagateNonSNaN(KnownSrc);
856
857 // Return NaN on infinite inputs.
858 Known.knownNot(fcInf);
859 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
860 Known.knownNot(fcNan);
861
862 return Known;
863}
864
866 return sin(KnownSrc);
867}
868
871
872 // tan never returns Inf (tan(+-Inf) = NaN; tan(finite) = finite).
873 Known.knownNot(fcInf);
874
875 Known.propagateNonSNaN(KnownSrc);
876
877 // NaN propagates. tan(+-Inf) is NaN.
878 if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
879 Known.knownNot(fcNan);
880
881 return Known;
882}
883
886
887 // sinh is sign-preserving: sinh(x) < 0 iff x < 0.
888 if (KnownSrc.isKnownNever(fcNegative))
889 Known.knownNot(fcNegative);
890
891 Known.propagateNonNaN(KnownSrc);
892
893 return Known;
894}
895
898
899 // cosh(x) >= 1 for all real x; cosh(+-Inf) = +Inf. Never negative,
900 // zero, or subnormal.
901 Known.knownNot(fcNegative | fcZero | fcSubnormal);
902
903 Known.propagateNonNaN(KnownSrc);
904
905 return Known;
906}
907
910
911 // tanh is bounded to (-1, 1), never Inf.
912 Known.knownNot(fcInf);
913
914 // tanh is sign-preserving: tanh(x) < 0 iff x < 0.
916 Known.knownNot(fcNegSubnormal | fcNegNormal);
917
918 // -0.0 is preserved: tanh(-0.0) = -0.0.
919 if (KnownSrc.isKnownNeverNegZero())
920 Known.knownNot(fcNegZero);
921 }
922
923 // Likewise, tanh(x) > 0 iff x > 0. Zero is not ruled out: tanh(+-0.0) =
924 // +-0.0, and a flushed subnormal may become +0.0.
926 Known.knownNot(fcPosSubnormal | fcPosNormal);
927
928 Known.propagateNonNaN(KnownSrc);
929
930 return Known;
931}
932
935
936 // asin is bounded to [-pi/2, pi/2], never Inf.
937 Known.knownNot(fcInf);
938
939 Known.propagateNonSNaN(KnownSrc);
940
941 // asin is sign-preserving for finite arguments.
942 if (KnownSrc.isKnownNever(fcNegFinite))
943 Known.knownNot(fcNegFinite);
944
945 // NaN propagates. asin(x) is also NaN for |x| > 1, so we cannot rule
946 // out NaN without knowing the source is in [-1, 1].
947 return Known;
948}
949
952
953 // acos(x) is bounded to [0, pi] for -1 <= x <= 1, and is never negative,
954 // infinite, or subnormal. The smallest non-zero value occurs when x is
955 // close to 1.0, where acos(x) can be approximated by sqrt(2 * (1 - x)).
956 // Since sqrt cannot produce a subnormal result, we can conclude that
957 // acos(x) will also never produce a subnormal result.
958 Known.knownNot(fcNegative | fcInf | fcSubnormal);
959
960 // acos(x) == +0.0 iff x == +1.0
961 if (KnownSrc.isKnownNever(fcPosNormal))
962 Known.knownNot(fcZero);
963
964 Known.propagateNonSNaN(KnownSrc);
965
966 // NaN propagates. acos(x) is also NaN for |x| > 1, so we cannot rule
967 // out NaN without knowing the source is in [-1, 1].
968 return Known;
969}
970
973
974 // atan is bounded to (-pi/2, pi/2), never Inf. atan(+-Inf) = +-pi/2 (finite).
975 Known.knownNot(fcInf);
976
977 // atan is sign-preserving: atan(x) < 0 iff x < 0.
978 if (KnownSrc.isKnownNever(fcNegative))
979 Known.knownNot(fcNegative);
980
981 Known.propagateNonNaN(KnownSrc);
982
983 return Known;
984}
985
987 const KnownFPClass &KnownX_,
988 DenormalMode Mode) {
989 KnownFPClass KnownY = applyInputDenormalMode(KnownY_, Mode);
990 KnownFPClass KnownX = applyInputDenormalMode(KnownX_, Mode);
992
993 // Even though these deductions are correct, we are ignoring the following
994 // potentially erroneous cases:
995 // * atan2(y, inf) is not subnormal
996 // * atan2(inf, x) is not zero or subnormal
997
998 // atan2 result is in (-pi, pi], never Inf.
999 Known.knownNot(fcInf);
1000
1001 Known.propagateNonNaN(KnownY, KnownX);
1002
1003 // If x <= -0.0, then |atan2(y, x)| >= pi/2
1004 if (KnownX.isKnownNever(fcPositive))
1005 Known.knownNot(fcZero | fcSubnormal);
1006
1007 // If y >= +0.0, then atan2(y, x) >= +0.0
1008 if (KnownY.isKnownNever(fcNegative))
1009 Known.knownNot(fcNegative);
1010
1011 // If y <= -0.0, then atan2(y, x) <= -0.0
1012 if (KnownY.isKnownNever(fcPositive))
1013 Known.knownNot(fcPositive);
1014
1015 return applyOutputDenormalMode(Known, Mode);
1016}
1017
1019 const fltSemantics &DstTy,
1020 const fltSemantics &SrcTy) {
1021 // Infinity, nan and zero propagate from source.
1022 KnownFPClass Known = KnownSrc;
1023
1024 // All subnormal inputs should be in the normal range in the result type.
1025 if (APFloat::isRepresentableAsNormalIn(SrcTy, DstTy)) {
1026 if (Known.getKnownFPClasses() & fcPosSubnormal)
1027 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosNormal);
1028 if (Known.getKnownFPClasses() & fcNegSubnormal)
1029 Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegNormal);
1030 Known.knownNot(fcSubnormal);
1031 }
1032
1033 // Sign bit of a nan isn't guaranteed.
1034 if (!Known.isKnownNeverNaN())
1035 Known.setSignBit(std::nullopt);
1036
1037 return Known;
1038}
1039
1042
1043 // Sign should be preserved
1044 // TODO: Handle cannot be ordered greater than zero
1045 if (KnownSrc.cannotBeOrderedLessThanZero())
1047
1048 Known.propagateNonNaN(KnownSrc);
1049
1050 // Infinity needs a range check.
1051 return Known;
1052}
1053
1055 bool IsTrunc, bool IsMultiUnitFPType,
1056 DenormalMode Mode) {
1058
1059 // Integer results cannot be subnormal.
1060 Known.knownNot(fcSubnormal);
1061
1062 Known.propagateNonNaN(KnownSrc);
1063
1064 // Pass through infinities, except PPC_FP128 is a special case for
1065 // intrinsics other than trunc.
1066 if (IsTrunc || !IsMultiUnitFPType) {
1067 if (KnownSrc.isKnownNeverPosInfinity())
1068 Known.knownNot(fcPosInf);
1069 if (KnownSrc.isKnownNeverNegInfinity())
1070 Known.knownNot(fcNegInf);
1071 }
1072
1073 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1074 Known.knownNot(fcPosNormal);
1075
1076 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1077 Known.knownNot(fcNegNormal);
1078
1079 // Negative round ups towards zero produce negative zero.
1080 if (KnownSrc.isKnownNever(fcNegFinite))
1081 Known.knownNot(fcNegZero);
1082
1083 // Negative subnormals may flush to positive zero.
1084 if (KnownSrc.isKnownNever(fcPosFinite) &&
1085 (KnownSrc.isKnownNever(fcNegSubnormal) ||
1086 !Mode.inputsMayBePositiveZero()))
1087 Known.knownNot(fcPosZero);
1088
1089 return Known;
1090}
1091
1093 DenormalMode Mode) {
1095
1096 Known.knownNot(fcSubnormal);
1097
1098 Known.propagateNonNaN(KnownSrc);
1099
1100 if (KnownSrc.isKnownNeverPosInfinity())
1101 Known.knownNot(fcPosInf);
1102
1103 if (KnownSrc.isKnownNeverNegInfinity())
1104 Known.knownNot(fcNegInf);
1105
1106 if (KnownSrc.isKnownNeverLogicalPosZero(Mode))
1107 Known.knownNot(fcPosZero);
1108
1109 if (KnownSrc.isKnownNeverLogicalNegZero(Mode))
1110 Known.knownNot(fcNegZero);
1111
1112 // TODO: These deductions can be improved if subnormal inputs are guaranteed
1113 // to be flushed to zero.
1114 if (KnownSrc.isKnownNever(fcPosNormal | fcPosSubnormal))
1115 Known.knownNot(fcPosNormal);
1116
1117 if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal))
1118 Known.knownNot(fcNegNormal);
1119
1120 return Known;
1121}
1122
1124 const APInt &ConstantRangeExpMin,
1125 const APInt &ConstantRangeExpMax,
1126 const fltSemantics &Flt, DenormalMode Mode) {
1128
1129 KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
1130
1131 if (ConstantRangeExpMin.isZero() && ConstantRangeExpMax.isZero()) {
1132 // ldexp(x, 0) -> x
1133 // Here we make sure to properly propagate sNaN and denormals.
1134 Known.setKnownFPClasses(KnownSrc.getKnownFPClasses() | fcNan);
1135 Known.propagateNonNaN(KnownSrc);
1136 return applyOutputDenormalMode(Known, Mode);
1137 }
1138
1139 Known.propagateNonNaN(KnownSrc);
1140
1141 // Sign is preserved, but underflows may produce zeroes.
1142 if (KnownSrc.isKnownNever(fcNegative))
1143 Known.knownNot(fcNegative);
1144 else if (KnownSrc.cannotBeOrderedLessThanZero())
1146
1147 if (KnownSrc.isKnownNever(fcPositive))
1148 Known.knownNot(fcPositive);
1149 else if (KnownSrc.cannotBeOrderedGreaterThanZero())
1151
1152 // TODO: determine when it is safe to rule out subnormal for ppcf128.
1153 if (&Flt != &APFloat::PPCDoubleDouble()) {
1154 unsigned Precision = APFloat::semanticsPrecision(Flt);
1155 const int MantissaBits = Precision - 1;
1156 if (ConstantRangeExpMin.sge(MantissaBits))
1157 Known.knownNot(fcSubnormal);
1158 }
1159
1160 if (ConstantRangeExpMax.isNonPositive()) {
1161 // If we know the power is <= 0, can't introduce inf
1162 if (KnownSrc.isKnownNeverPosInfinity())
1163 Known.knownNot(fcPosInf);
1164 if (KnownSrc.isKnownNeverNegInfinity())
1165 Known.knownNot(fcNegInf);
1166 } else if (ConstantRangeExpMin.isNonNegative()) {
1167 // If we know the power is >= 0, can't introduce subnormal or zero
1168 if (KnownSrc.isKnownNeverPosSubnormal())
1169 Known.knownNot(fcPosSubnormal);
1170 if (KnownSrc.isKnownNeverNegSubnormal())
1171 Known.knownNot(fcNegSubnormal);
1172 if (KnownSrc.isKnownNeverPosZero())
1173 Known.knownNot(fcPosZero);
1174 if (KnownSrc.isKnownNeverNegZero())
1175 Known.knownNot(fcNegZero);
1176 }
1177
1178 return applyOutputDenormalMode(Known, Mode);
1179}
1180
1182 const KnownBits &ExpBits,
1183 const fltSemantics &Flt, DenormalMode Mode) {
1184 return ldexp(KnownSrc, ExpBits.getSignedMinValue(),
1185 ExpBits.getSignedMaxValue(), Flt, Mode);
1186}
1187
1189 const KnownFPClass &KnownRHS) {
1191
1192 Known.propagateNonSNaN(KnownLHS, KnownRHS);
1193
1194 // pow may return NaN if one of the arguments is NaN. NaN may be produced from
1195 // a non-zero-finite-negative base and a non-integer exponent.
1196 if (KnownLHS.isKnownNever(fcNan | fcNegNormal | fcNegSubnormal) &&
1197 KnownRHS.isKnownNeverNaN())
1198 Known.knownNot(fcNan);
1199
1200 // We could rule out negative and subnormal results when exponent is known to
1201 // never be a normal value, but having either argument being known to never be
1202 // normal is unlikely and not worth considering.
1203
1204 // Only a negative base raised to an odd power returns a negative value.
1205 if (KnownLHS.isKnownNever(fcNegative)) {
1206 Known.knownNot(fcNegative);
1207 } else if (KnownLHS.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1208 Known.knownNot(fcNegNormal | fcNegSubnormal);
1209 // See if we can also rule out -0.0 or -inf.
1210 // Here at least one of -0.0 or -inf is a possible base.
1211
1212 // pow(-0.0, odd-positive) = -0.0
1213 // pow(-inf, odd-negative) = -0.0
1214 if ((KnownLHS.isKnownNever(fcNegZero) ||
1215 KnownRHS.isKnownNever(fcPosNormal)) &&
1216 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcNegNormal)))
1217 Known.knownNot(fcNegZero);
1218
1219 // pow(-0.0, odd-negative) = -inf
1220 // pow(-inf, odd-positive) = -inf
1221 if ((KnownLHS.isKnownNever(fcNegZero) ||
1222 KnownRHS.isKnownNever(fcNegNormal)) &&
1223 (KnownLHS.isKnownNever(fcNegInf) || KnownRHS.isKnownNever(fcPosNormal)))
1224 Known.knownNot(fcNegInf);
1225 }
1226
1227 return Known;
1228}
1229
1231 const KnownBits &ExponentKnownBits) {
1233 Known.propagateNonNaN(KnownSrc);
1234
1235 if (ExponentKnownBits.isZero()) {
1236 // powi(QNaN, 0) returns 1.0, and powi(SNaN, 0) may non-deterministically
1237 // return 1.0 or a NaN.
1238 if (KnownSrc.isKnownNever(fcSNan)) {
1239 Known.knownNot(~fcPosNormal);
1240 return Known;
1241 }
1242
1243 Known.knownNot(~(fcPosNormal | fcNan));
1244 return Known;
1245 }
1246
1247 // Given that exp is an integer, here are the
1248 // ways that powi can return a negative value:
1249 //
1250 // powi(x, exp) --> negative if exp is odd and x is negative.
1251 // powi(-0, exp) --> -inf if exp is negative odd.
1252 // powi(-0, exp) --> -0 if exp is positive odd.
1253 // powi(-inf, exp) --> -0 if exp is negative odd.
1254 // powi(-inf, exp) --> -inf if exp is positive odd.
1255 if (KnownSrc.isKnownNever(fcNegative) || ExponentKnownBits.isEven()) {
1256 Known.knownNot(fcNegative);
1257 } else if (KnownSrc.isKnownNever(fcNegNormal | fcNegSubnormal)) {
1258 Known.knownNot(fcNegNormal | fcNegSubnormal);
1259 // See if we can also rule out -0.0 or -inf.
1260 // Here at least one of -0.0 or -inf is a possible base.
1261
1262 // We already know that ExponentKnownBits.isEven() is false here.
1263 const bool IsKnownNeverOddPositive = ExponentKnownBits.isNegative();
1264 const bool IsKnownNeverOddNegative = ExponentKnownBits.isNonNegative();
1265
1266 // powi(-0.0, odd-positive) = -0.0
1267 // powi(-inf, odd-negative) = -0.0
1268 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddPositive) &&
1269 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddNegative))
1270 Known.knownNot(fcNegZero);
1271
1272 // powi(-0.0, odd-negative) = -inf
1273 // powi(-inf, odd-positive) = -inf
1274 if ((KnownSrc.isKnownNever(fcNegZero) || IsKnownNeverOddNegative) &&
1275 (KnownSrc.isKnownNever(fcNegInf) || IsKnownNeverOddPositive))
1276 Known.knownNot(fcNegInf);
1277 }
1278
1279 // powi(x, exp) --> inf
1280 // when:
1281 // * powi(inf, exp), exp > 0
1282 // * powi(+/-0, exp), exp < 0
1283 // * powi(finite, exp), |exp| > 1
1284 // * powi(subnormal, -1)
1285 // TODO:
1286 // 1. This simple all or nothing approach. We can do better
1287 // and cover sign/parity and exp > 1 vs exp < -1 separately.
1288 // 2. powi(0/nan, exp), exp > 0 can be refinable
1289 // to fcNan | fcZero | fcPosNormal.
1290 {
1291 APInt MinExp = ExponentKnownBits.getSignedMinValue();
1292 APInt MaxExp = ExponentKnownBits.getSignedMaxValue();
1293
1294 // powi(inf, exp), exp > 0
1295 bool MayInfSrc =
1296 !KnownSrc.isKnownNever(fcInf) && MaxExp.isStrictlyPositive();
1297
1298 // powi(+/-0, exp), exp < 0
1299 bool MayDivByZero = !KnownSrc.isKnownNever(fcZero) && MinExp.isNegative();
1300
1301 // powi(finite, exp), |exp| > 1
1302 bool MayFinite = !KnownSrc.isKnownNever(fcNormal | fcSubnormal);
1303 bool MayAbsExpGT1 = MinExp.slt(-1) || MaxExp.sgt(1);
1304 bool MayFiniteOverflow = MayFinite && MayAbsExpGT1;
1305
1306 // powi(subnormal, -1)
1307 bool MayBeNegOne = ExponentKnownBits.Zero.isZero();
1308 bool MaySubnormInv = !KnownSrc.isKnownNever(fcSubnormal) && MayBeNegOne;
1309
1310 if (!MayInfSrc && !MayDivByZero && !MayFiniteOverflow && !MaySubnormInv)
1311 Known.knownNot(fcInf);
1312 }
1313
1314 return Known;
1315}
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:329
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:379
static LLVM_ABI bool isIEEELikeFP(const fltSemantics &)
Definition APFloat.cpp:370
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.
@ 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: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.
void setKnownFPClasses(FPClassTest Classes)
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 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.
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 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 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 -...
LLVM_ABI void propagateCanonicalizingSrc(const KnownFPClass &Src, DenormalMode Mode)
Report known classes if Src is evaluated through a potentially canonicalizing operation.
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 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.
void propagateNonNaN(const KnownFPClass &Src)
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 roundToIntegral(const KnownFPClass &Src, bool IsTrunc, bool IsMultiUnitFPType, DenormalMode Mode=DenormalMode::getDynamic())
Propagate known class for rounding intrinsics (trunc, floor, ceil, rint, nearbyint,...
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