diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2023-04-08 22:33:35 -0400 |
---|---|---|
committer | Matt Arsenault <arsenm2@gmail.com> | 2023-05-16 12:41:43 +0100 |
commit | fe5786d41644ec6c739b6ace49d654a21a07cca0 (patch) | |
tree | ce6086f61d2f9639b9e66954c482fe2d65a5f83c /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 4707458755fd73c6fdfc298c7cc325145483e94e (diff) | |
download | llvm-fe5786d41644ec6c739b6ace49d654a21a07cca0.zip llvm-fe5786d41644ec6c739b6ace49d654a21a07cca0.tar.gz llvm-fe5786d41644ec6c739b6ace49d654a21a07cca0.tar.bz2 |
ValueTracking: Implement computeKnownFPClass for sqrt
Could be slightly smarter in cases that are probably uninteresting.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index fb91b98..7c2e98d 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4293,11 +4293,24 @@ static bool inputDenormalIsIEEE(const Function &F, const Type *Ty) { return F.getDenormalMode(Ty->getFltSemantics()).Input == DenormalMode::IEEE; } +static bool inputDenormalIsIEEEOrPosZero(const Function &F, const Type *Ty) { + Ty = Ty->getScalarType(); + DenormalMode Mode = F.getDenormalMode(Ty->getFltSemantics()); + return Mode.Input == DenormalMode::IEEE || + Mode.Input == DenormalMode::PositiveZero; +} + bool KnownFPClass::isKnownNeverLogicalZero(const Function &F, Type *Ty) const { return isKnownNeverZero() && (isKnownNeverSubnormal() || inputDenormalIsIEEE(F, Ty)); } +bool KnownFPClass::isKnownNeverLogicalNegZero(const Function &F, + Type *Ty) const { + return isKnownNeverNegZero() && + (isKnownNeverNegSubnormal() || inputDenormalIsIEEEOrPosZero(F, Ty)); +} + /// Returns a pair of values, which if passed to llvm.is.fpclass, returns the /// same result as an fcmp with the given operands. std::pair<Value *, FPClassTest> llvm::fcmpToClassTest(FCmpInst::Predicate Pred, @@ -4711,6 +4724,39 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts, Known.knownNot(fcNegative); break; } + case Intrinsic::sqrt: { + KnownFPClass KnownSrc; + FPClassTest InterestedSrcs = InterestedClasses; + if (InterestedClasses & fcNan) + InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask; + + computeKnownFPClass(II->getArgOperand(0), DemandedElts, + InterestedSrcs, KnownSrc, Depth + 1, Q, TLI); + + if (KnownSrc.isKnownNeverPosInfinity()) + Known.knownNot(fcPosInf); + if (KnownSrc.isKnownNever(fcSNan)) + Known.knownNot(fcSNan); + + // Any negative value besides -0 returns a nan. + if (KnownSrc.isKnownNeverNaN() && + KnownSrc.cannotBeOrderedLessThanZero()) + Known.knownNot(fcNan); + + // The only negative value that can be returned is -0 for -0 inputs. + Known.knownNot(fcNegInf | fcNegSubnormal | fcNegNormal); + + // If the input denormal mode could be PreserveSign, a negative + // subnormal input could produce a negative zero output. + if (KnownSrc.isKnownNeverLogicalNegZero(*II->getFunction(), + II->getType())) { + Known.knownNot(fcNegZero); + if (KnownSrc.isKnownNeverNaN()) + Known.SignBit = false; + } + + break; + } case Intrinsic::sin: case Intrinsic::cos: { // Return NaN on infinite inputs. |