/// Return true if the floating-point scalar value is not an infinity or if
/// the floating-point vector value has no infinities. Return false if a value
/// could ever be infinity.
-bool isKnownNeverInfinity(const Value *V, const DataLayout &DL,
- const TargetLibraryInfo *TLI = nullptr,
- unsigned Depth = 0, AssumptionCache *AC = nullptr,
- const Instruction *CtxI = nullptr,
- const DominatorTree *DT = nullptr,
- OptimizationRemarkEmitter *ORE = nullptr,
- bool UseInstrInfo = true);
+inline bool isKnownNeverInfinity(const Value *V, const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr,
+ unsigned Depth = 0,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CtxI = nullptr,
+ const DominatorTree *DT = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr,
+ bool UseInstrInfo = true) {
+ KnownFPClass Known = computeKnownFPClass(V, DL, fcInf, Depth, TLI, AC, CtxI,
+ DT, ORE, UseInstrInfo);
+ return Known.isKnownNeverInfinity();
+}
/// Return true if the floating-point value can never contain a NaN or infinity.
inline bool isKnownNeverInfOrNaN(
return cannotBeOrderedLessThanZeroImpl(V, DL, TLI, false, 0);
}
-bool llvm::isKnownNeverInfinity(const Value *V, const DataLayout &DL,
- const TargetLibraryInfo *TLI, unsigned Depth,
- AssumptionCache *AC, const Instruction *CtxI,
- const DominatorTree *DT,
- OptimizationRemarkEmitter *ORE,
- bool UseInstrInfo) {
- assert(V->getType()->isFPOrFPVectorTy() && "Querying for Inf on non-FP type");
-
- // If we're told that infinities won't happen, assume they won't.
- if (auto *FPMathOp = dyn_cast<FPMathOperator>(V))
- if (FPMathOp->hasNoInfs())
- return true;
-
- if (const auto *Arg = dyn_cast<Argument>(V)) {
- if ((Arg->getNoFPClass() & fcInf) == fcInf)
- return true;
- }
-
- // TODO: Use fpclass like API for isKnown queries and distinguish +inf from
- // -inf.
- if (const auto *CB = dyn_cast<CallBase>(V)) {
- if ((CB->getRetNoFPClass() & fcInf) == fcInf)
- return true;
- }
-
- // Handle scalar constants.
- if (auto *CFP = dyn_cast<ConstantFP>(V))
- return !CFP->isInfinity();
-
- if (Depth == MaxAnalysisRecursionDepth)
- return false;
-
- if (auto *Inst = dyn_cast<Instruction>(V)) {
- switch (Inst->getOpcode()) {
- case Instruction::Select: {
- return isKnownNeverInfinity(Inst->getOperand(1), DL, TLI, Depth + 1) &&
- isKnownNeverInfinity(Inst->getOperand(2), DL, TLI, Depth + 1);
- }
- case Instruction::SIToFP:
- case Instruction::UIToFP: {
- // Get width of largest magnitude integer (remove a bit if signed).
- // This still works for a signed minimum value because the largest FP
- // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
- int IntSize = Inst->getOperand(0)->getType()->getScalarSizeInBits();
- if (Inst->getOpcode() == Instruction::SIToFP)
- --IntSize;
-
- // If the exponent of the largest finite FP value can hold the largest
- // integer, the result of the cast must be finite.
- Type *FPTy = Inst->getType()->getScalarType();
- return ilogb(APFloat::getLargest(FPTy->getFltSemantics())) >= IntSize;
- }
- case Instruction::FNeg:
- case Instruction::FPExt: {
- // Peek through to source op. If it is not infinity, this is not infinity.
- return isKnownNeverInfinity(Inst->getOperand(0), DL, TLI, Depth + 1);
- }
- case Instruction::FPTrunc: {
- // Need a range check.
- return false;
- }
- default:
- break;
- }
-
- if (const auto *II = dyn_cast<IntrinsicInst>(V)) {
- switch (II->getIntrinsicID()) {
- case Intrinsic::sin:
- case Intrinsic::cos:
- // Return NaN on infinite inputs.
- return true;
- case Intrinsic::fabs:
- case Intrinsic::sqrt:
- case Intrinsic::canonicalize:
- case Intrinsic::copysign:
- case Intrinsic::arithmetic_fence:
- case Intrinsic::trunc:
- return isKnownNeverInfinity(Inst->getOperand(0), DL, TLI, Depth + 1);
- case Intrinsic::floor:
- case Intrinsic::ceil:
- case Intrinsic::rint:
- case Intrinsic::nearbyint:
- case Intrinsic::round:
- case Intrinsic::roundeven:
- // PPC_FP128 is a special case.
- if (V->getType()->isMultiUnitFPType())
- return false;
- return isKnownNeverInfinity(Inst->getOperand(0), DL, TLI, Depth + 1);
- case Intrinsic::fptrunc_round:
- // Requires knowing the value range.
- return false;
- case Intrinsic::minnum:
- case Intrinsic::maxnum:
- case Intrinsic::minimum:
- case Intrinsic::maximum:
- return isKnownNeverInfinity(Inst->getOperand(0), DL, TLI, Depth + 1) &&
- isKnownNeverInfinity(Inst->getOperand(1), DL, TLI, Depth + 1);
- case Intrinsic::log:
- case Intrinsic::log10:
- case Intrinsic::log2:
- // log(+inf) -> +inf
- // log([+-]0.0) -> -inf
- // log(-inf) -> nan
- // log(-x) -> nan
- // TODO: We lack API to check the == 0 case.
- return false;
- case Intrinsic::exp:
- case Intrinsic::exp2:
- case Intrinsic::pow:
- case Intrinsic::powi:
- case Intrinsic::fma:
- case Intrinsic::fmuladd:
- // These can return infinities on overflow cases, so it's hard to prove
- // anything about it.
- return false;
- default:
- break;
- }
- }
- }
-
- // try to handle fixed width vector constants
- auto *VFVTy = dyn_cast<FixedVectorType>(V->getType());
- if (VFVTy && isa<Constant>(V)) {
- // For vectors, verify that each element is not infinity.
- unsigned NumElts = VFVTy->getNumElements();
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *Elt = cast<Constant>(V)->getAggregateElement(i);
- if (!Elt)
- return false;
- if (isa<UndefValue>(Elt))
- continue;
- auto *CElt = dyn_cast<ConstantFP>(Elt);
- if (!CElt || CElt->isInfinity())
- return false;
- }
- // All elements were confirmed non-infinity or undefined.
- return true;
- }
-
- // was not able to prove that V never contains infinity
- return false;
-}
-
bool llvm::SignBitMustBeZero(const Value *V, const DataLayout &DL,
const TargetLibraryInfo *TLI) {
return cannotBeOrderedLessThanZeroImpl(V, DL, TLI, true, 0);