[llvm] 729b55e - ValueTracking: Reduce indentation in computeKnownFPClass
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 7 14:32:08 PDT 2023
Author: Matt Arsenault
Date: 2023-08-07T17:32:03-04:00
New Revision: 729b55ef5e7aff33fb1d191c5ef576bbda03b801
URL: https://github.com/llvm/llvm-project/commit/729b55ef5e7aff33fb1d191c5ef576bbda03b801
DIFF: https://github.com/llvm/llvm-project/commit/729b55ef5e7aff33fb1d191c5ef576bbda03b801.diff
LOG: ValueTracking: Reduce indentation in computeKnownFPClass
Added:
Modified:
llvm/lib/Analysis/ValueTracking.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index b3502746450825..8bae935bc9543f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4377,427 +4377,420 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
break;
}
case Instruction::Call: {
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op)) {
- const Intrinsic::ID IID = II->getIntrinsicID();
- switch (IID) {
- case Intrinsic::fabs: {
- if ((InterestedClasses & (fcNan | fcPositive)) != fcNone) {
- // If we only care about the sign bit we don't need to inspect the
- // operand.
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedClasses, Known, Depth + 1, Q);
- }
-
- Known.fabs();
- break;
- }
- case Intrinsic::copysign: {
- KnownFPClass KnownSign;
-
+ const CallInst *II = cast<CallInst>(Op);
+ const Intrinsic::ID IID = II->getIntrinsicID();
+ switch (IID) {
+ case Intrinsic::fabs: {
+ if ((InterestedClasses & (fcNan | fcPositive)) != fcNone) {
+ // If we only care about the sign bit we don't need to inspect the
+ // operand.
computeKnownFPClass(II->getArgOperand(0), DemandedElts,
InterestedClasses, Known, Depth + 1, Q);
- computeKnownFPClass(II->getArgOperand(1), DemandedElts,
- InterestedClasses, KnownSign, Depth + 1, Q);
- Known.copysign(KnownSign);
- break;
}
- case Intrinsic::fma:
- case Intrinsic::fmuladd: {
- if ((InterestedClasses & fcNegative) == fcNone)
- break;
- if (II->getArgOperand(0) != II->getArgOperand(1))
- break;
-
- // The multiply cannot be -0 and therefore the add can't be -0
- Known.knownNot(fcNegZero);
+ Known.fabs();
+ break;
+ }
+ case Intrinsic::copysign: {
+ KnownFPClass KnownSign;
- // x * x + y is non-negative if y is non-negative.
- KnownFPClass KnownAddend;
- computeKnownFPClass(II->getArgOperand(2), DemandedElts,
- InterestedClasses, KnownAddend, Depth + 1, Q);
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses,
+ Known, Depth + 1, Q);
+ computeKnownFPClass(II->getArgOperand(1), DemandedElts, InterestedClasses,
+ KnownSign, Depth + 1, Q);
+ Known.copysign(KnownSign);
+ break;
+ }
+ case Intrinsic::fma:
+ case Intrinsic::fmuladd: {
+ if ((InterestedClasses & fcNegative) == fcNone)
+ break;
- // TODO: Known sign bit with no nans
- if (KnownAddend.cannotBeOrderedLessThanZero())
- Known.knownNot(fcNegative);
+ if (II->getArgOperand(0) != II->getArgOperand(1))
break;
- }
- case Intrinsic::sqrt:
- case Intrinsic::experimental_constrained_sqrt: {
- KnownFPClass KnownSrc;
- FPClassTest InterestedSrcs = InterestedClasses;
- if (InterestedClasses & fcNan)
- InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedSrcs, KnownSrc, Depth + 1, Q);
+ // The multiply cannot be -0 and therefore the add can't be -0
+ Known.knownNot(fcNegZero);
- 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.
- const Function *F = II->getFunction();
- if (Q.IIQ.hasNoSignedZeros(II) ||
- (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))) {
- Known.knownNot(fcNegZero);
- if (KnownSrc.isKnownNeverNaN())
- Known.SignBit = false;
- }
+ // x * x + y is non-negative if y is non-negative.
+ KnownFPClass KnownAddend;
+ computeKnownFPClass(II->getArgOperand(2), DemandedElts, InterestedClasses,
+ KnownAddend, Depth + 1, Q);
- break;
- }
- case Intrinsic::sin:
- case Intrinsic::cos: {
- // Return NaN on infinite inputs.
- KnownFPClass KnownSrc;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedClasses, KnownSrc, Depth + 1, Q);
- Known.knownNot(fcInf);
- if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
- Known.knownNot(fcNan);
- break;
+ // TODO: Known sign bit with no nans
+ if (KnownAddend.cannotBeOrderedLessThanZero())
+ Known.knownNot(fcNegative);
+ break;
+ }
+ case Intrinsic::sqrt:
+ case Intrinsic::experimental_constrained_sqrt: {
+ KnownFPClass KnownSrc;
+ FPClassTest InterestedSrcs = InterestedClasses;
+ if (InterestedClasses & fcNan)
+ InterestedSrcs |= KnownFPClass::OrderedLessThanZeroMask;
+
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedSrcs,
+ KnownSrc, Depth + 1, Q);
+
+ 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.
+ const Function *F = II->getFunction();
+ if (Q.IIQ.hasNoSignedZeros(II) ||
+ (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))) {
+ Known.knownNot(fcNegZero);
+ if (KnownSrc.isKnownNeverNaN())
+ Known.SignBit = false;
}
- case Intrinsic::maxnum:
- case Intrinsic::minnum:
- case Intrinsic::minimum:
- case Intrinsic::maximum: {
- KnownFPClass KnownLHS, KnownRHS;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedClasses, KnownLHS, Depth + 1, Q);
- computeKnownFPClass(II->getArgOperand(1), DemandedElts,
- InterestedClasses, KnownRHS, Depth + 1, Q);
-
- bool NeverNaN =
- KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
- Known = KnownLHS | KnownRHS;
-
- // If either operand is not NaN, the result is not NaN.
- if (NeverNaN && (IID == Intrinsic::minnum || IID == Intrinsic::maxnum))
- Known.knownNot(fcNan);
-
- if (IID == Intrinsic::maxnum) {
- // If at least one operand is known to be positive, the result must be
- // positive.
- if ((KnownLHS.cannotBeOrderedLessThanZero() &&
- KnownLHS.isKnownNeverNaN()) ||
- (KnownRHS.cannotBeOrderedLessThanZero() &&
- KnownRHS.isKnownNeverNaN()))
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- } else if (IID == Intrinsic::maximum) {
- // If at least one operand is known to be positive, the result must be
- // positive.
- if (KnownLHS.cannotBeOrderedLessThanZero() ||
- KnownRHS.cannotBeOrderedLessThanZero())
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- } else if (IID == Intrinsic::minnum) {
- // If at least one operand is known to be negative, the result must be
- // negative.
- if ((KnownLHS.cannotBeOrderedGreaterThanZero() &&
- KnownLHS.isKnownNeverNaN()) ||
- (KnownRHS.cannotBeOrderedGreaterThanZero() &&
- KnownRHS.isKnownNeverNaN()))
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
- } else {
- // If at least one operand is known to be negative, the result must be
- // negative.
- if (KnownLHS.cannotBeOrderedGreaterThanZero() ||
- KnownRHS.cannotBeOrderedGreaterThanZero())
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
- }
+ break;
+ }
+ case Intrinsic::sin:
+ case Intrinsic::cos: {
+ // Return NaN on infinite inputs.
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses,
+ KnownSrc, Depth + 1, Q);
+ Known.knownNot(fcInf);
+ if (KnownSrc.isKnownNeverNaN() && KnownSrc.isKnownNeverInfinity())
+ Known.knownNot(fcNan);
+ break;
+ }
+ case Intrinsic::maxnum:
+ case Intrinsic::minnum:
+ case Intrinsic::minimum:
+ case Intrinsic::maximum: {
+ KnownFPClass KnownLHS, KnownRHS;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses,
+ KnownLHS, Depth + 1, Q);
+ computeKnownFPClass(II->getArgOperand(1), DemandedElts, InterestedClasses,
+ KnownRHS, Depth + 1, Q);
- // Fixup zero handling if denormals could be returned as a zero.
- //
- // As there's no spec for denormal flushing, be conservative with the
- // treatment of denormals that could be flushed to zero. For older
- // subtargets on AMDGPU the min/max instructions would not flush the
- // output and return the original value.
- //
- // TODO: This could be refined based on the sign
- if ((Known.KnownFPClasses & fcZero) != fcNone &&
- !Known.isKnownNeverSubnormal()) {
- const Function *Parent = II->getFunction();
- if (!Parent)
- break;
-
- DenormalMode Mode = Parent->getDenormalMode(
- II->getType()->getScalarType()->getFltSemantics());
- if (Mode != DenormalMode::getIEEE())
- Known.KnownFPClasses |= fcZero;
- }
+ bool NeverNaN = KnownLHS.isKnownNeverNaN() || KnownRHS.isKnownNeverNaN();
+ Known = KnownLHS | KnownRHS;
- break;
+ // If either operand is not NaN, the result is not NaN.
+ if (NeverNaN && (IID == Intrinsic::minnum || IID == Intrinsic::maxnum))
+ Known.knownNot(fcNan);
+
+ if (IID == Intrinsic::maxnum) {
+ // If at least one operand is known to be positive, the result must be
+ // positive.
+ if ((KnownLHS.cannotBeOrderedLessThanZero() &&
+ KnownLHS.isKnownNeverNaN()) ||
+ (KnownRHS.cannotBeOrderedLessThanZero() &&
+ KnownRHS.isKnownNeverNaN()))
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ } else if (IID == Intrinsic::maximum) {
+ // If at least one operand is known to be positive, the result must be
+ // positive.
+ if (KnownLHS.cannotBeOrderedLessThanZero() ||
+ KnownRHS.cannotBeOrderedLessThanZero())
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ } else if (IID == Intrinsic::minnum) {
+ // If at least one operand is known to be negative, the result must be
+ // negative.
+ if ((KnownLHS.cannotBeOrderedGreaterThanZero() &&
+ KnownLHS.isKnownNeverNaN()) ||
+ (KnownRHS.cannotBeOrderedGreaterThanZero() &&
+ KnownRHS.isKnownNeverNaN()))
+ Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
+ } else {
+ // If at least one operand is known to be negative, the result must be
+ // negative.
+ if (KnownLHS.cannotBeOrderedGreaterThanZero() ||
+ KnownRHS.cannotBeOrderedGreaterThanZero())
+ Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
}
- case Intrinsic::canonicalize: {
- KnownFPClass KnownSrc;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedClasses, KnownSrc, Depth + 1, Q);
- // This is essentially a stronger form of
- // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
- // actually have an IR canonicalization guarantee.
+ // Fixup zero handling if denormals could be returned as a zero.
+ //
+ // As there's no spec for denormal flushing, be conservative with the
+ // treatment of denormals that could be flushed to zero. For older
+ // subtargets on AMDGPU the min/max instructions would not flush the
+ // output and return the original value.
+ //
+ // TODO: This could be refined based on the sign
+ if ((Known.KnownFPClasses & fcZero) != fcNone &&
+ !Known.isKnownNeverSubnormal()) {
+ const Function *Parent = II->getFunction();
+ if (!Parent)
+ break;
- // Canonicalize may flush denormals to zero, so we have to consider the
- // denormal mode to preserve known-not-0 knowledge.
- Known.KnownFPClasses = KnownSrc.KnownFPClasses | fcZero | fcQNan;
+ DenormalMode Mode = Parent->getDenormalMode(
+ II->getType()->getScalarType()->getFltSemantics());
+ if (Mode != DenormalMode::getIEEE())
+ Known.KnownFPClasses |= fcZero;
+ }
- // Stronger version of propagateNaN
- // Canonicalize is guaranteed to quiet signaling nans.
- if (KnownSrc.isKnownNeverNaN())
- Known.knownNot(fcNan);
- else
- Known.knownNot(fcSNan);
+ break;
+ }
+ case Intrinsic::canonicalize: {
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses,
+ KnownSrc, Depth + 1, Q);
- const Function *F = II->getFunction();
- if (!F)
- break;
+ // This is essentially a stronger form of
+ // propagateCanonicalizingSrc. Other "canonicalizing" operations don't
+ // actually have an IR canonicalization guarantee.
- // If the parent function flushes denormals, the canonical output cannot
- // be a denormal.
- const fltSemantics &FPType =
- II->getType()->getScalarType()->getFltSemantics();
- DenormalMode DenormMode = F->getDenormalMode(FPType);
- if (DenormMode == DenormalMode::getIEEE()) {
- if (KnownSrc.isKnownNever(fcPosZero))
- Known.knownNot(fcPosZero);
- if (KnownSrc.isKnownNever(fcNegZero))
- Known.knownNot(fcNegZero);
- break;
- }
+ // Canonicalize may flush denormals to zero, so we have to consider the
+ // denormal mode to preserve known-not-0 knowledge.
+ Known.KnownFPClasses = KnownSrc.KnownFPClasses | fcZero | fcQNan;
- if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
- Known.knownNot(fcSubnormal);
+ // Stronger version of propagateNaN
+ // Canonicalize is guaranteed to quiet signaling nans.
+ if (KnownSrc.isKnownNeverNaN())
+ Known.knownNot(fcNan);
+ else
+ Known.knownNot(fcSNan);
- if (DenormMode.Input == DenormalMode::PositiveZero ||
- (DenormMode.Output == DenormalMode::PositiveZero &&
- DenormMode.Input == DenormalMode::IEEE))
- Known.knownNot(fcNegZero);
+ const Function *F = II->getFunction();
+ if (!F)
+ break;
+ // If the parent function flushes denormals, the canonical output cannot
+ // be a denormal.
+ const fltSemantics &FPType =
+ II->getType()->getScalarType()->getFltSemantics();
+ DenormalMode DenormMode = F->getDenormalMode(FPType);
+ if (DenormMode == DenormalMode::getIEEE()) {
+ if (KnownSrc.isKnownNever(fcPosZero))
+ Known.knownNot(fcPosZero);
+ if (KnownSrc.isKnownNever(fcNegZero))
+ Known.knownNot(fcNegZero);
break;
}
- case Intrinsic::trunc:
- case Intrinsic::floor:
- case Intrinsic::ceil:
- case Intrinsic::rint:
- case Intrinsic::nearbyint:
- case Intrinsic::round:
- case Intrinsic::roundeven: {
- KnownFPClass KnownSrc;
- FPClassTest InterestedSrcs = InterestedClasses;
- if (InterestedSrcs & fcPosFinite)
- InterestedSrcs |= fcPosFinite;
- if (InterestedSrcs & fcNegFinite)
- InterestedSrcs |= fcNegFinite;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedSrcs, KnownSrc, Depth + 1, Q);
- // Integer results cannot be subnormal.
+ if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
Known.knownNot(fcSubnormal);
- Known.propagateNaN(KnownSrc, true);
+ if (DenormMode.Input == DenormalMode::PositiveZero ||
+ (DenormMode.Output == DenormalMode::PositiveZero &&
+ DenormMode.Input == DenormalMode::IEEE))
+ Known.knownNot(fcNegZero);
- // Pass through infinities, except PPC_FP128 is a special case for
- // intrinsics other than trunc.
- if (IID == Intrinsic::trunc || !V->getType()->isMultiUnitFPType()) {
- if (KnownSrc.isKnownNeverPosInfinity())
- Known.knownNot(fcPosInf);
- if (KnownSrc.isKnownNeverNegInfinity())
- Known.knownNot(fcNegInf);
- }
+ break;
+ }
+ case Intrinsic::trunc:
+ case Intrinsic::floor:
+ case Intrinsic::ceil:
+ case Intrinsic::rint:
+ case Intrinsic::nearbyint:
+ case Intrinsic::round:
+ case Intrinsic::roundeven: {
+ KnownFPClass KnownSrc;
+ FPClassTest InterestedSrcs = InterestedClasses;
+ if (InterestedSrcs & fcPosFinite)
+ InterestedSrcs |= fcPosFinite;
+ if (InterestedSrcs & fcNegFinite)
+ InterestedSrcs |= fcNegFinite;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedSrcs,
+ KnownSrc, Depth + 1, Q);
+
+ // Integer results cannot be subnormal.
+ Known.knownNot(fcSubnormal);
- // Negative round ups to 0 produce -0
- if (KnownSrc.isKnownNever(fcPosFinite))
- Known.knownNot(fcPosFinite);
- if (KnownSrc.isKnownNever(fcNegFinite))
- Known.knownNot(fcNegFinite);
+ Known.propagateNaN(KnownSrc, true);
- break;
+ // Pass through infinities, except PPC_FP128 is a special case for
+ // intrinsics other than trunc.
+ if (IID == Intrinsic::trunc || !V->getType()->isMultiUnitFPType()) {
+ if (KnownSrc.isKnownNeverPosInfinity())
+ Known.knownNot(fcPosInf);
+ if (KnownSrc.isKnownNeverNegInfinity())
+ Known.knownNot(fcNegInf);
}
- case Intrinsic::exp:
- case Intrinsic::exp2: {
- Known.knownNot(fcNegative);
- if ((InterestedClasses & fcNan) == fcNone)
- break;
- KnownFPClass KnownSrc;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedClasses, KnownSrc, Depth + 1, Q);
- if (KnownSrc.isKnownNeverNaN()) {
- Known.knownNot(fcNan);
- Known.SignBit = false;
- }
+ // Negative round ups to 0 produce -0
+ if (KnownSrc.isKnownNever(fcPosFinite))
+ Known.knownNot(fcPosFinite);
+ if (KnownSrc.isKnownNever(fcNegFinite))
+ Known.knownNot(fcNegFinite);
+ break;
+ }
+ case Intrinsic::exp:
+ case Intrinsic::exp2: {
+ Known.knownNot(fcNegative);
+ if ((InterestedClasses & fcNan) == fcNone)
break;
+
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses,
+ KnownSrc, Depth + 1, Q);
+ if (KnownSrc.isKnownNeverNaN()) {
+ Known.knownNot(fcNan);
+ Known.SignBit = false;
}
- case Intrinsic::fptrunc_round: {
- computeKnownFPClassForFPTrunc(Op, DemandedElts, InterestedClasses,
- Known, Depth, Q);
+
+ break;
+ }
+ case Intrinsic::fptrunc_round: {
+ computeKnownFPClassForFPTrunc(Op, DemandedElts, InterestedClasses, Known,
+ Depth, Q);
+ break;
+ }
+ case Intrinsic::log:
+ case Intrinsic::log10:
+ case Intrinsic::log2:
+ case Intrinsic::experimental_constrained_log:
+ case Intrinsic::experimental_constrained_log10:
+ case Intrinsic::experimental_constrained_log2: {
+ // log(+inf) -> +inf
+ // log([+-]0.0) -> -inf
+ // log(-inf) -> nan
+ // log(-x) -> nan
+ if ((InterestedClasses & (fcNan | fcInf)) == fcNone)
break;
- }
- case Intrinsic::log:
- case Intrinsic::log10:
- case Intrinsic::log2:
- case Intrinsic::experimental_constrained_log:
- case Intrinsic::experimental_constrained_log10:
- case Intrinsic::experimental_constrained_log2: {
- // log(+inf) -> +inf
- // log([+-]0.0) -> -inf
- // log(-inf) -> nan
- // log(-x) -> nan
- if ((InterestedClasses & (fcNan | fcInf)) == fcNone)
- break;
- FPClassTest InterestedSrcs = InterestedClasses;
- if ((InterestedClasses & fcNegInf) != fcNone)
- InterestedSrcs |= fcZero | fcSubnormal;
- if ((InterestedClasses & fcNan) != fcNone)
- InterestedSrcs |= fcNan | (fcNegative & ~fcNan);
+ FPClassTest InterestedSrcs = InterestedClasses;
+ if ((InterestedClasses & fcNegInf) != fcNone)
+ InterestedSrcs |= fcZero | fcSubnormal;
+ if ((InterestedClasses & fcNan) != fcNone)
+ InterestedSrcs |= fcNan | (fcNegative & ~fcNan);
- KnownFPClass KnownSrc;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedSrcs,
- KnownSrc, Depth + 1, Q);
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedSrcs,
+ KnownSrc, Depth + 1, Q);
- if (KnownSrc.isKnownNeverPosInfinity())
- Known.knownNot(fcPosInf);
+ if (KnownSrc.isKnownNeverPosInfinity())
+ Known.knownNot(fcPosInf);
- if (KnownSrc.isKnownNeverNaN() &&
- KnownSrc.cannotBeOrderedLessThanZero())
- Known.knownNot(fcNan);
+ if (KnownSrc.isKnownNeverNaN() && KnownSrc.cannotBeOrderedLessThanZero())
+ Known.knownNot(fcNan);
- const Function *F = II->getFunction();
- if (F && KnownSrc.isKnownNeverLogicalZero(*F, II->getType()))
- Known.knownNot(fcNegInf);
+ const Function *F = II->getFunction();
+ if (F && KnownSrc.isKnownNeverLogicalZero(*F, II->getType()))
+ Known.knownNot(fcNegInf);
+ break;
+ }
+ case Intrinsic::powi: {
+ if ((InterestedClasses & fcNegative) == fcNone)
break;
- }
- case Intrinsic::powi: {
- if ((InterestedClasses & fcNegative) == fcNone)
- break;
- const Value *Exp = II->getArgOperand(1);
- Type *ExpTy = Exp->getType();
- unsigned BitWidth = ExpTy->getScalarType()->getIntegerBitWidth();
- KnownBits ExponentKnownBits(BitWidth);
- computeKnownBits(Exp,
- isa<VectorType>(ExpTy) ? DemandedElts : APInt(1, 1),
- ExponentKnownBits, Depth + 1, Q);
+ const Value *Exp = II->getArgOperand(1);
+ Type *ExpTy = Exp->getType();
+ unsigned BitWidth = ExpTy->getScalarType()->getIntegerBitWidth();
+ KnownBits ExponentKnownBits(BitWidth);
+ computeKnownBits(Exp, isa<VectorType>(ExpTy) ? DemandedElts : APInt(1, 1),
+ ExponentKnownBits, Depth + 1, Q);
- if (ExponentKnownBits.Zero[0]) { // Is even
- Known.knownNot(fcNegative);
- break;
- }
-
- // Given that exp is an integer, here are the
- // ways that pow can return a negative value:
- //
- // pow(-x, exp) --> negative if exp is odd and x is negative.
- // pow(-0, exp) --> -inf if exp is negative odd.
- // pow(-0, exp) --> -0 if exp is positive odd.
- // pow(-inf, exp) --> -0 if exp is negative odd.
- // pow(-inf, exp) --> -inf if exp is positive odd.
- KnownFPClass KnownSrc;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts, fcNegative,
- KnownSrc, Depth + 1, Q);
- if (KnownSrc.isKnownNever(fcNegative))
- Known.knownNot(fcNegative);
+ if (ExponentKnownBits.Zero[0]) { // Is even
+ Known.knownNot(fcNegative);
break;
}
- case Intrinsic::ldexp: {
- KnownFPClass KnownSrc;
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedClasses, KnownSrc, Depth + 1, Q);
- Known.propagateNaN(KnownSrc, /*PropagateSign=*/true);
- // Sign is preserved, but underflows may produce zeroes.
- if (KnownSrc.isKnownNever(fcNegative))
- Known.knownNot(fcNegative);
- else if (KnownSrc.cannotBeOrderedLessThanZero())
- Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
+ // Given that exp is an integer, here are the
+ // ways that pow can return a negative value:
+ //
+ // pow(-x, exp) --> negative if exp is odd and x is negative.
+ // pow(-0, exp) --> -inf if exp is negative odd.
+ // pow(-0, exp) --> -0 if exp is positive odd.
+ // pow(-inf, exp) --> -0 if exp is negative odd.
+ // pow(-inf, exp) --> -inf if exp is positive odd.
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, fcNegative,
+ KnownSrc, Depth + 1, Q);
+ if (KnownSrc.isKnownNever(fcNegative))
+ Known.knownNot(fcNegative);
+ break;
+ }
+ case Intrinsic::ldexp: {
+ KnownFPClass KnownSrc;
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses,
+ KnownSrc, Depth + 1, Q);
+ Known.propagateNaN(KnownSrc, /*PropagateSign=*/true);
- if (KnownSrc.isKnownNever(fcPositive))
- Known.knownNot(fcPositive);
- else if (KnownSrc.cannotBeOrderedGreaterThanZero())
- Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
+ // Sign is preserved, but underflows may produce zeroes.
+ if (KnownSrc.isKnownNever(fcNegative))
+ Known.knownNot(fcNegative);
+ else if (KnownSrc.cannotBeOrderedLessThanZero())
+ Known.knownNot(KnownFPClass::OrderedLessThanZeroMask);
- // Can refine inf/zero handling based on the exponent operand.
- const FPClassTest ExpInfoMask = fcZero | fcSubnormal | fcInf;
- if ((InterestedClasses & ExpInfoMask) == fcNone)
- break;
- if ((KnownSrc.KnownFPClasses & ExpInfoMask) == fcNone)
- break;
+ if (KnownSrc.isKnownNever(fcPositive))
+ Known.knownNot(fcPositive);
+ else if (KnownSrc.cannotBeOrderedGreaterThanZero())
+ Known.knownNot(KnownFPClass::OrderedGreaterThanZeroMask);
- const fltSemantics &Flt
- = II->getType()->getScalarType()->getFltSemantics();
- unsigned Precision = APFloat::semanticsPrecision(Flt);
- const Value *ExpArg = II->getArgOperand(1);
- ConstantRange ExpRange = computeConstantRange(
- ExpArg, true, Q.IIQ.UseInstrInfo, Q.AC, Q.CxtI, Q.DT, Depth + 1);
+ // Can refine inf/zero handling based on the exponent operand.
+ const FPClassTest ExpInfoMask = fcZero | fcSubnormal | fcInf;
+ if ((InterestedClasses & ExpInfoMask) == fcNone)
+ break;
+ if ((KnownSrc.KnownFPClasses & ExpInfoMask) == fcNone)
+ break;
- const int MantissaBits = Precision - 1;
- if (ExpRange.getSignedMin().sge(static_cast<int64_t>(MantissaBits)))
- Known.knownNot(fcSubnormal);
+ const fltSemantics &Flt =
+ II->getType()->getScalarType()->getFltSemantics();
+ unsigned Precision = APFloat::semanticsPrecision(Flt);
+ const Value *ExpArg = II->getArgOperand(1);
+ ConstantRange ExpRange = computeConstantRange(
+ ExpArg, true, Q.IIQ.UseInstrInfo, Q.AC, Q.CxtI, Q.DT, Depth + 1);
- const Function *F = II->getFunction();
- const APInt *ConstVal = ExpRange.getSingleElement();
- if (ConstVal && ConstVal->isZero()) {
- // ldexp(x, 0) -> x, so propagate everything.
- Known.propagateCanonicalizingSrc(KnownSrc, *F,
- II->getType());
- } else if (ExpRange.isAllNegative()) {
- // If we know the power is <= 0, can't introduce inf
- if (KnownSrc.isKnownNeverPosInfinity())
- Known.knownNot(fcPosInf);
- if (KnownSrc.isKnownNeverNegInfinity())
- Known.knownNot(fcNegInf);
- } else if (ExpRange.isAllNonNegative()) {
- // If we know the power is >= 0, can't introduce subnormal or zero
- if (KnownSrc.isKnownNeverPosSubnormal())
- Known.knownNot(fcPosSubnormal);
- if (KnownSrc.isKnownNeverNegSubnormal())
- Known.knownNot(fcNegSubnormal);
- if (F && KnownSrc.isKnownNeverLogicalPosZero(*F, II->getType()))
- Known.knownNot(fcPosZero);
- if (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))
- Known.knownNot(fcNegZero);
- }
+ const int MantissaBits = Precision - 1;
+ if (ExpRange.getSignedMin().sge(static_cast<int64_t>(MantissaBits)))
+ Known.knownNot(fcSubnormal);
- break;
- }
- case Intrinsic::arithmetic_fence: {
- computeKnownFPClass(II->getArgOperand(0), DemandedElts,
- InterestedClasses, Known, Depth + 1, Q);
- break;
+ const Function *F = II->getFunction();
+ const APInt *ConstVal = ExpRange.getSingleElement();
+ if (ConstVal && ConstVal->isZero()) {
+ // ldexp(x, 0) -> x, so propagate everything.
+ Known.propagateCanonicalizingSrc(KnownSrc, *F, II->getType());
+ } else if (ExpRange.isAllNegative()) {
+ // If we know the power is <= 0, can't introduce inf
+ if (KnownSrc.isKnownNeverPosInfinity())
+ Known.knownNot(fcPosInf);
+ if (KnownSrc.isKnownNeverNegInfinity())
+ Known.knownNot(fcNegInf);
+ } else if (ExpRange.isAllNonNegative()) {
+ // If we know the power is >= 0, can't introduce subnormal or zero
+ if (KnownSrc.isKnownNeverPosSubnormal())
+ Known.knownNot(fcPosSubnormal);
+ if (KnownSrc.isKnownNeverNegSubnormal())
+ Known.knownNot(fcNegSubnormal);
+ if (F && KnownSrc.isKnownNeverLogicalPosZero(*F, II->getType()))
+ Known.knownNot(fcPosZero);
+ if (F && KnownSrc.isKnownNeverLogicalNegZero(*F, II->getType()))
+ Known.knownNot(fcNegZero);
}
- case Intrinsic::experimental_constrained_sitofp:
- case Intrinsic::experimental_constrained_uitofp:
- // Cannot produce nan
- Known.knownNot(fcNan);
- // sitofp and uitofp turn into +0.0 for zero.
- Known.knownNot(fcNegZero);
+ break;
+ }
+ case Intrinsic::arithmetic_fence: {
+ computeKnownFPClass(II->getArgOperand(0), DemandedElts, InterestedClasses,
+ Known, Depth + 1, Q);
+ break;
+ }
+ case Intrinsic::experimental_constrained_sitofp:
+ case Intrinsic::experimental_constrained_uitofp:
+ // Cannot produce nan
+ Known.knownNot(fcNan);
- // Integers cannot be subnormal
- Known.knownNot(fcSubnormal);
+ // sitofp and uitofp turn into +0.0 for zero.
+ Known.knownNot(fcNegZero);
- if (IID == Intrinsic::experimental_constrained_uitofp)
- Known.signBitMustBeZero();
+ // Integers cannot be subnormal
+ Known.knownNot(fcSubnormal);
- // TODO: Copy inf handling from instructions
- break;
- default:
- break;
- }
+ if (IID == Intrinsic::experimental_constrained_uitofp)
+ Known.signBitMustBeZero();
+
+ // TODO: Copy inf handling from instructions
+ break;
+ default:
+ break;
}
break;
More information about the llvm-commits
mailing list