Index: llvm/include/llvm/Analysis/ValueTracking.h =================================================================== --- llvm/include/llvm/Analysis/ValueTracking.h +++ llvm/include/llvm/Analysis/ValueTracking.h @@ -356,19 +356,30 @@ /// -0 --> true /// x > +0 --> true /// x < -0 --> false -bool CannotBeOrderedLessThanZero(const Value *V, const TargetLibraryInfo *TLI); +bool CannotBeOrderedLessThanZero(const Value *V, const DataLayout &DL, + const TargetLibraryInfo *TLI); /// 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 TargetLibraryInfo *TLI, - unsigned Depth = 0); +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 scalar value is not a NaN or if the /// floating-point vector value has no NaN elements. Return false if a value /// could ever be NaN. -bool isKnownNeverNaN(const Value *V, const TargetLibraryInfo *TLI, - unsigned Depth = 0); +bool isKnownNeverNaN(const Value *V, const DataLayout &DL, + const TargetLibraryInfo *TLI, unsigned Depth = 0); /// Return true if we can prove that the specified FP value's sign bit is 0. /// @@ -377,7 +388,8 @@ /// -0 --> false /// x > +0 --> true /// x < -0 --> false -bool SignBitMustBeZero(const Value *V, const TargetLibraryInfo *TLI); +bool SignBitMustBeZero(const Value *V, const DataLayout &DL, + const TargetLibraryInfo *TLI); /// If the specified value can be set by repeating the same byte in memory, /// return the i8 value that it is represented with. This is true for all i8 Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -1972,7 +1972,8 @@ return nullptr; } -static Value *simplifyAndOrOfFCmps(const TargetLibraryInfo *TLI, FCmpInst *LHS, +static Value *simplifyAndOrOfFCmps(const DataLayout &DL, + const TargetLibraryInfo *TLI, FCmpInst *LHS, FCmpInst *RHS, bool IsAnd) { Value *LHS0 = LHS->getOperand(0), *LHS1 = LHS->getOperand(1); Value *RHS0 = RHS->getOperand(0), *RHS1 = RHS->getOperand(1); @@ -1990,8 +1991,8 @@ // (fcmp uno NNAN, X) | (fcmp uno Y, X) --> fcmp uno Y, X // (fcmp uno X, NNAN) | (fcmp uno X, Y) --> fcmp uno X, Y // (fcmp uno X, NNAN) | (fcmp uno Y, X) --> fcmp uno Y, X - if ((isKnownNeverNaN(LHS0, TLI) && (LHS1 == RHS0 || LHS1 == RHS1)) || - (isKnownNeverNaN(LHS1, TLI) && (LHS0 == RHS0 || LHS0 == RHS1))) + if ((isKnownNeverNaN(LHS0, DL, TLI) && (LHS1 == RHS0 || LHS1 == RHS1)) || + (isKnownNeverNaN(LHS1, DL, TLI) && (LHS0 == RHS0 || LHS0 == RHS1))) return RHS; // (fcmp ord X, Y) & (fcmp ord NNAN, X) --> fcmp ord X, Y @@ -2002,8 +2003,8 @@ // (fcmp uno Y, X) | (fcmp uno NNAN, X) --> fcmp uno Y, X // (fcmp uno X, Y) | (fcmp uno X, NNAN) --> fcmp uno X, Y // (fcmp uno Y, X) | (fcmp uno X, NNAN) --> fcmp uno Y, X - if ((isKnownNeverNaN(RHS0, TLI) && (RHS1 == LHS0 || RHS1 == LHS1)) || - (isKnownNeverNaN(RHS1, TLI) && (RHS0 == LHS0 || RHS0 == LHS1))) + if ((isKnownNeverNaN(RHS0, DL, TLI) && (RHS1 == LHS0 || RHS1 == LHS1)) || + (isKnownNeverNaN(RHS1, DL, TLI) && (RHS0 == LHS0 || RHS0 == LHS1))) return LHS; } @@ -2031,7 +2032,7 @@ auto *FCmp0 = dyn_cast(Op0); auto *FCmp1 = dyn_cast(Op1); if (FCmp0 && FCmp1) - V = simplifyAndOrOfFCmps(Q.TLI, FCmp0, FCmp1, IsAnd); + V = simplifyAndOrOfFCmps(Q.DL, Q.TLI, FCmp0, FCmp1, IsAnd); if (!V) return nullptr; @@ -4037,8 +4038,8 @@ // Fold (un)ordered comparison if we can determine there are no NaNs. if (Pred == FCmpInst::FCMP_UNO || Pred == FCmpInst::FCMP_ORD) - if (FMF.noNaNs() || - (isKnownNeverNaN(LHS, Q.TLI) && isKnownNeverNaN(RHS, Q.TLI))) + if (FMF.noNaNs() || (isKnownNeverNaN(LHS, Q.DL, Q.TLI) && + isKnownNeverNaN(RHS, Q.DL, Q.TLI))) return ConstantInt::get(RetTy, Pred == FCmpInst::FCMP_ORD); // NaN is unordered; NaN is not ordered. @@ -4100,18 +4101,20 @@ } // LHS == Inf - if (Pred == FCmpInst::FCMP_OEQ && isKnownNeverInfinity(LHS, Q.TLI)) + if (Pred == FCmpInst::FCMP_OEQ && isKnownNeverInfinity(LHS, Q.DL, Q.TLI)) return getFalse(RetTy); // LHS != Inf - if (Pred == FCmpInst::FCMP_UNE && isKnownNeverInfinity(LHS, Q.TLI)) + if (Pred == FCmpInst::FCMP_UNE && isKnownNeverInfinity(LHS, Q.DL, Q.TLI)) return getTrue(RetTy); // LHS == Inf || LHS == NaN - if (Pred == FCmpInst::FCMP_UEQ && isKnownNeverInfinity(LHS, Q.TLI) && - isKnownNeverNaN(LHS, Q.TLI)) + if (Pred == FCmpInst::FCMP_UEQ && + isKnownNeverInfinity(LHS, Q.DL, Q.TLI) && + isKnownNeverNaN(LHS, Q.DL, Q.TLI)) return getFalse(RetTy); // LHS != Inf && LHS != NaN - if (Pred == FCmpInst::FCMP_ONE && isKnownNeverInfinity(LHS, Q.TLI) && - isKnownNeverNaN(LHS, Q.TLI)) + if (Pred == FCmpInst::FCMP_ONE && + isKnownNeverInfinity(LHS, Q.DL, Q.TLI) && + isKnownNeverNaN(LHS, Q.DL, Q.TLI)) return getTrue(RetTy); } if (C->isNegative() && !C->isNegZero()) { @@ -4123,14 +4126,14 @@ case FCmpInst::FCMP_UGT: case FCmpInst::FCMP_UNE: // (X >= 0) implies (X > C) when (C < 0) - if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) + if (CannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI)) return getTrue(RetTy); break; case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_OLE: case FCmpInst::FCMP_OLT: // (X >= 0) implies !(X < C) when (C < 0) - if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) + if (CannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI)) return getFalse(RetTy); break; default: @@ -4190,15 +4193,15 @@ case FCmpInst::FCMP_ULT: // Positive or zero X >= 0.0 --> true // Positive or zero X < 0.0 --> false - if ((FMF.noNaNs() || isKnownNeverNaN(LHS, Q.TLI)) && - CannotBeOrderedLessThanZero(LHS, Q.TLI)) + if ((FMF.noNaNs() || isKnownNeverNaN(LHS, Q.DL, Q.TLI)) && + CannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI)) return Pred == FCmpInst::FCMP_OGE ? getTrue(RetTy) : getFalse(RetTy); break; case FCmpInst::FCMP_UGE: case FCmpInst::FCMP_OLT: // Positive or zero or nan X >= 0.0 --> true // Positive or zero or nan X < 0.0 --> false - if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) + if (CannotBeOrderedLessThanZero(LHS, Q.DL, Q.TLI)) return Pred == FCmpInst::FCMP_UGE ? getTrue(RetTy) : getFalse(RetTy); break; default: @@ -5619,8 +5622,10 @@ return ConstantFP::getZero(Op0->getType()); // +normal number * (-)0.0 --> (-)0.0 - if (isKnownNeverInfinity(Op0, Q.TLI) && isKnownNeverNaN(Op0, Q.TLI) && - SignBitMustBeZero(Op0, Q.TLI)) + // TODO: Use computeKnownFPClass + if (isKnownNeverInfinity(Op0, Q.DL, Q.TLI) && + isKnownNeverNaN(Op0, Q.DL, Q.TLI) && + SignBitMustBeZero(Op0, Q.DL, Q.TLI)) return Op1; } @@ -6027,7 +6032,7 @@ Value *X; switch (IID) { case Intrinsic::fabs: - if (SignBitMustBeZero(Op0, Q.TLI)) + if (SignBitMustBeZero(Op0, Q.DL, Q.TLI)) return Op0; break; case Intrinsic::bswap: Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -3669,9 +3669,9 @@ /// standard ordered compare. e.g. make -0.0 olt 0.0 be true because of the sign /// bit despite comparing equal. static bool cannotBeOrderedLessThanZeroImpl(const Value *V, + const DataLayout &DL, const TargetLibraryInfo *TLI, - bool SignBitOnly, - unsigned Depth) { + bool SignBitOnly, unsigned Depth) { // TODO: This function does not do the right thing when SignBitOnly is true // and we're lowering to a hypothetical IEEE 754-compliant-but-evil platform // which flips the sign bits of NaNs. See @@ -3720,9 +3720,9 @@ return true; // Set SignBitOnly for RHS, because X / -0.0 is -Inf (or NaN). - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, - Depth + 1) && - cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1) && + cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI, /*SignBitOnly*/ true, Depth + 1); case Instruction::FMul: // X * X is always non-negative or a NaN. @@ -3733,26 +3733,26 @@ [[fallthrough]]; case Instruction::FAdd: case Instruction::FRem: - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, - Depth + 1) && - cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, SignBitOnly, - Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1) && + cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI, + SignBitOnly, Depth + 1); case Instruction::Select: - return cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, SignBitOnly, - Depth + 1) && - cannotBeOrderedLessThanZeroImpl(I->getOperand(2), TLI, SignBitOnly, - Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI, + SignBitOnly, Depth + 1) && + cannotBeOrderedLessThanZeroImpl(I->getOperand(2), DL, TLI, + SignBitOnly, Depth + 1); case Instruction::FPExt: case Instruction::FPTrunc: // Widening/narrowing never change sign. - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, - Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1); case Instruction::ExtractElement: // Look through extract element. At the moment we keep this simple and skip // tracking the specific element. But at least we might find information // valid for all elements of the vector. - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, - Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1); case Instruction::Call: const auto *CI = cast(I); Intrinsic::ID IID = getIntrinsicForCallSite(*CI, TLI); @@ -3769,7 +3769,8 @@ case Intrinsic::round: case Intrinsic::roundeven: case Intrinsic::fptrunc_round: - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1); case Intrinsic::maxnum: { Value *V0 = I->getOperand(0), *V1 = I->getOperand(1); auto isPositiveNum = [&](Value *V) { @@ -3784,8 +3785,8 @@ // -0.0 compares equal to 0.0, so if this operand is at least -0.0, // maxnum can't be ordered-less-than-zero. - return isKnownNeverNaN(V, TLI) && - cannotBeOrderedLessThanZeroImpl(V, TLI, false, Depth + 1); + return isKnownNeverNaN(V, DL, TLI) && + cannotBeOrderedLessThanZeroImpl(V, DL, TLI, false, Depth + 1); }; // TODO: This could be improved. We could also check that neither operand @@ -3794,23 +3795,23 @@ } case Intrinsic::maximum: - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, - Depth + 1) || - cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, SignBitOnly, - Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1) || + cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI, + SignBitOnly, Depth + 1); case Intrinsic::minnum: case Intrinsic::minimum: - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, - Depth + 1) && - cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, SignBitOnly, - Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1) && + cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI, + SignBitOnly, Depth + 1); case Intrinsic::exp: case Intrinsic::exp2: case Intrinsic::fabs: return true; case Intrinsic::copysign: // Only the sign operand matters. - return cannotBeOrderedLessThanZeroImpl(I->getOperand(1), TLI, true, + return cannotBeOrderedLessThanZeroImpl(I->getOperand(1), DL, TLI, true, Depth + 1); case Intrinsic::sqrt: // sqrt(x) is always >= -0 or NaN. Moreover, sqrt(x) == -0 iff x == -0. @@ -3838,173 +3839,34 @@ // but we must return false if x == -0. Unfortunately we do not currently // have a way of expressing this constraint. See details in // https://llvm.org/bugs/show_bug.cgi?id=31702. - return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, - Depth + 1); + return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), DL, TLI, + SignBitOnly, Depth + 1); case Intrinsic::fma: case Intrinsic::fmuladd: // x*x+y is non-negative if y is non-negative. return I->getOperand(0) == I->getOperand(1) && (!SignBitOnly || cast(I)->hasNoNaNs()) && - cannotBeOrderedLessThanZeroImpl(I->getOperand(2), TLI, SignBitOnly, - Depth + 1); + cannotBeOrderedLessThanZeroImpl(I->getOperand(2), DL, TLI, + SignBitOnly, Depth + 1); } break; } return false; } -bool llvm::CannotBeOrderedLessThanZero(const Value *V, +bool llvm::CannotBeOrderedLessThanZero(const Value *V, const DataLayout &DL, const TargetLibraryInfo *TLI) { - return cannotBeOrderedLessThanZeroImpl(V, TLI, false, 0); -} - -bool llvm::SignBitMustBeZero(const Value *V, const TargetLibraryInfo *TLI) { - return cannotBeOrderedLessThanZeroImpl(V, TLI, true, 0); + return cannotBeOrderedLessThanZeroImpl(V, DL, TLI, false, 0); } -bool llvm::isKnownNeverInfinity(const Value *V, const TargetLibraryInfo *TLI, - unsigned Depth) { - 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(V)) - if (FPMathOp->hasNoInfs()) - return true; - - if (const auto *Arg = dyn_cast(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(V)) { - if ((CB->getRetNoFPClass() & fcInf) == fcInf) - return true; - } - - // Handle scalar constants. - if (auto *CFP = dyn_cast(V)) - return !CFP->isInfinity(); - - if (Depth == MaxAnalysisRecursionDepth) - return false; - - if (auto *Inst = dyn_cast(V)) { - switch (Inst->getOpcode()) { - case Instruction::Select: { - return isKnownNeverInfinity(Inst->getOperand(1), TLI, Depth + 1) && - isKnownNeverInfinity(Inst->getOperand(2), 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), TLI, Depth + 1); - } - case Instruction::FPTrunc: { - // Need a range check. - return false; - } - default: - break; - } - - if (const auto *II = dyn_cast(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), 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), 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), TLI, Depth + 1) && - isKnownNeverInfinity(Inst->getOperand(1), 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(V->getType()); - if (VFVTy && isa(V)) { - // For vectors, verify that each element is not infinity. - unsigned NumElts = VFVTy->getNumElements(); - for (unsigned i = 0; i != NumElts; ++i) { - Constant *Elt = cast(V)->getAggregateElement(i); - if (!Elt) - return false; - if (isa(Elt)) - continue; - auto *CElt = dyn_cast(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); } -bool llvm::isKnownNeverNaN(const Value *V, const TargetLibraryInfo *TLI, - unsigned Depth) { +bool llvm::isKnownNeverNaN(const Value *V, const DataLayout &DL, + const TargetLibraryInfo *TLI, unsigned Depth) { assert(V->getType()->isFPOrFPVectorTy() && "Querying for NaN on non-FP type"); // If we're told that NaNs won't happen, assume they won't. @@ -4037,18 +3899,18 @@ case Instruction::FAdd: case Instruction::FSub: // Adding positive and negative infinity produces NaN. - return isKnownNeverNaN(Inst->getOperand(0), TLI, Depth + 1) && - isKnownNeverNaN(Inst->getOperand(1), TLI, Depth + 1) && - (isKnownNeverInfinity(Inst->getOperand(0), TLI, Depth + 1) || - isKnownNeverInfinity(Inst->getOperand(1), TLI, Depth + 1)); + return isKnownNeverNaN(Inst->getOperand(0), DL, TLI, Depth + 1) && + isKnownNeverNaN(Inst->getOperand(1), DL, TLI, Depth + 1) && + (isKnownNeverInfinity(Inst->getOperand(0), DL, TLI, Depth + 1) || + isKnownNeverInfinity(Inst->getOperand(1), DL, TLI, Depth + 1)); case Instruction::FMul: // Zero multiplied with infinity produces NaN. // FIXME: If neither side can be zero fmul never produces NaN. - return isKnownNeverNaN(Inst->getOperand(0), TLI, Depth + 1) && - isKnownNeverInfinity(Inst->getOperand(0), TLI, Depth + 1) && - isKnownNeverNaN(Inst->getOperand(1), TLI, Depth + 1) && - isKnownNeverInfinity(Inst->getOperand(1), TLI, Depth + 1); + return isKnownNeverNaN(Inst->getOperand(0), DL, TLI, Depth + 1) && + isKnownNeverInfinity(Inst->getOperand(0), DL, TLI, Depth + 1) && + isKnownNeverNaN(Inst->getOperand(1), DL, TLI, Depth + 1) && + isKnownNeverInfinity(Inst->getOperand(1), DL, TLI, Depth + 1); case Instruction::FDiv: case Instruction::FRem: @@ -4056,8 +3918,8 @@ return false; case Instruction::Select: { - return isKnownNeverNaN(Inst->getOperand(1), TLI, Depth + 1) && - isKnownNeverNaN(Inst->getOperand(2), TLI, Depth + 1); + return isKnownNeverNaN(Inst->getOperand(1), DL, TLI, Depth + 1) && + isKnownNeverNaN(Inst->getOperand(2), DL, TLI, Depth + 1); } case Instruction::SIToFP: case Instruction::UIToFP: @@ -4065,7 +3927,7 @@ case Instruction::FPTrunc: case Instruction::FPExt: case Instruction::FNeg: - return isKnownNeverNaN(Inst->getOperand(0), TLI, Depth + 1); + return isKnownNeverNaN(Inst->getOperand(0), DL, TLI, Depth + 1); default: break; } @@ -4086,15 +3948,15 @@ case Intrinsic::round: case Intrinsic::roundeven: case Intrinsic::arithmetic_fence: - return isKnownNeverNaN(II->getArgOperand(0), TLI, Depth + 1); + return isKnownNeverNaN(II->getArgOperand(0), DL, TLI, Depth + 1); case Intrinsic::sqrt: - return isKnownNeverNaN(II->getArgOperand(0), TLI, Depth + 1) && - CannotBeOrderedLessThanZero(II->getArgOperand(0), TLI); + return isKnownNeverNaN(II->getArgOperand(0), DL, TLI, Depth + 1) && + CannotBeOrderedLessThanZero(II->getArgOperand(0), DL, TLI); case Intrinsic::minnum: case Intrinsic::maxnum: // If either operand is not NaN, the result is not NaN. - return isKnownNeverNaN(II->getArgOperand(0), TLI, Depth + 1) || - isKnownNeverNaN(II->getArgOperand(1), TLI, Depth + 1); + return isKnownNeverNaN(II->getArgOperand(0), DL, TLI, Depth + 1) || + isKnownNeverNaN(II->getArgOperand(1), DL, TLI, Depth + 1); default: return false; } @@ -4443,8 +4305,8 @@ if (KnownSrc.isKnownNeverNaN() && (InterestedClasses & fcNan) != fcNone && - cannotBeOrderedLessThanZeroImpl(II->getArgOperand(0), TLI, false, - Depth + 1)) + cannotBeOrderedLessThanZeroImpl(II->getArgOperand(0), Q.DL, TLI, + false, Depth + 1)) Known.knownNot(fcNan); // Any negative value besides -0 returns a nan. Index: llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp @@ -340,9 +340,13 @@ // One operand is not zero or infinity or NaN. return true; } + + // TODO: Use computeKnownFPClass auto *TLI = &IC.getTargetLibraryInfo(); - if (isKnownNeverInfinity(Op0, TLI) && isKnownNeverNaN(Op0, TLI) && - isKnownNeverInfinity(Op1, TLI) && isKnownNeverNaN(Op1, TLI)) { + if (isKnownNeverInfinity(Op0, IC.getDataLayout(), TLI) && + isKnownNeverNaN(Op0, IC.getDataLayout(), TLI) && + isKnownNeverInfinity(Op1, IC.getDataLayout(), TLI) && + isKnownNeverNaN(Op1, IC.getDataLayout(), TLI)) { // Neither operand is infinity or NaN. return true; } @@ -463,7 +467,8 @@ } // fp_class (nnan x), qnan|snan|other -> fp_class (nnan x), other - if ((Mask & fcNan) && isKnownNeverNaN(Src0, &IC.getTargetLibraryInfo())) { + if ((Mask & fcNan) && + isKnownNeverNaN(Src0, IC.getDataLayout(), &IC.getTargetLibraryInfo())) { return IC.replaceOperand( II, 1, ConstantInt::get(Src1->getType(), Mask & ~fcNan)); } Index: llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp =================================================================== --- llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp +++ llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp @@ -423,7 +423,8 @@ Type *Ty = Call->getType(); Value *Arg = Call->getArgOperand(0); if (TTI.haveFastSqrt(Ty) && - (Call->hasNoNaNs() || CannotBeOrderedLessThanZero(Arg, &TLI))) { + (Call->hasNoNaNs() || + CannotBeOrderedLessThanZero(Arg, M->getDataLayout(), &TLI))) { IRBuilder<> Builder(&I); IRBuilderBase::FastMathFlagGuard Guard(Builder); Builder.setFastMathFlags(Call->getFastMathFlags()); Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -929,26 +929,27 @@ } // fp_class (nnan x), qnan|snan|other -> fp_class (nnan x), other - if ((Mask & fcNan) && isKnownNeverNaN(Src0, &getTargetLibraryInfo())) { + if ((Mask & fcNan) && isKnownNeverNaN(Src0, DL, &getTargetLibraryInfo())) { II.setArgOperand(1, ConstantInt::get(Src1->getType(), Mask & ~fcNan)); return &II; } // fp_class (nnan x), ~(qnan|snan) -> true if (Mask == (~fcNan & fcAllFlags) && - isKnownNeverNaN(Src0, &getTargetLibraryInfo())) { + isKnownNeverNaN(Src0, DL, &getTargetLibraryInfo())) { return replaceInstUsesWith(II, ConstantInt::get(II.getType(), true)); } // fp_class (ninf x), ninf|pinf|other -> fp_class (ninf x), other - if ((Mask & fcInf) && isKnownNeverInfinity(Src0, &getTargetLibraryInfo())) { + if ((Mask & fcInf) && + isKnownNeverInfinity(Src0, DL, &getTargetLibraryInfo())) { II.setArgOperand(1, ConstantInt::get(Src1->getType(), Mask & ~fcInf)); return &II; } // fp_class (ninf x), ~(ninf|pinf) -> true if (Mask == (~fcInf & fcAllFlags) && - isKnownNeverInfinity(Src0, &getTargetLibraryInfo())) { + isKnownNeverInfinity(Src0, DL, &getTargetLibraryInfo())) { return replaceInstUsesWith(II, ConstantInt::get(II.getType(), true)); } @@ -2151,7 +2152,7 @@ } case Intrinsic::copysign: { Value *Mag = II->getArgOperand(0), *Sign = II->getArgOperand(1); - if (SignBitMustBeZero(Sign, &TLI)) { + if (SignBitMustBeZero(Sign, DL, &TLI)) { // If we know that the sign argument is positive, reduce to FABS: // copysign Mag, +Sign --> fabs Mag Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, Mag, II); Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -7047,10 +7047,10 @@ // If we're just checking for a NaN (ORD/UNO) and have a non-NaN operand, // then canonicalize the operand to 0.0. if (Pred == CmpInst::FCMP_ORD || Pred == CmpInst::FCMP_UNO) { - if (!match(Op0, m_PosZeroFP()) && isKnownNeverNaN(Op0, &TLI)) + if (!match(Op0, m_PosZeroFP()) && isKnownNeverNaN(Op0, DL, &TLI)) return replaceOperand(I, 0, ConstantFP::getZero(OpType)); - if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, &TLI)) + if (!match(Op1, m_PosZeroFP()) && isKnownNeverNaN(Op1, DL, &TLI)) return replaceOperand(I, 1, ConstantFP::getZero(OpType)); } Index: llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -2057,7 +2057,7 @@ // pow(-Inf, 0.5) is optionally required to have a result of +Inf (not setting // errno), but sqrt(-Inf) is required by various standards to set errno. if (!Pow->doesNotAccessMemory() && !Pow->hasNoInfs() && - !isKnownNeverInfinity(Base, TLI)) + !isKnownNeverInfinity(Base, DL, TLI)) return nullptr; Sqrt = getSqrtCall(Base, AttributeList(), Pow->doesNotAccessMemory(), Mod, B,