aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2023-04-08 22:33:35 -0400
committerMatt Arsenault <arsenm2@gmail.com>2023-05-16 12:41:43 +0100
commitfe5786d41644ec6c739b6ace49d654a21a07cca0 (patch)
treece6086f61d2f9639b9e66954c482fe2d65a5f83c /llvm/lib/Analysis/ValueTracking.cpp
parent4707458755fd73c6fdfc298c7cc325145483e94e (diff)
downloadllvm-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.cpp46
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.