diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index 82c87edd6297c..c25dcad5e2242 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -1002,11 +1002,19 @@ bool isGuaranteedNotToBeUndefOrPoison(const Value *V, const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr, unsigned Depth = 0); + +/// Returns true if V cannot be poison, but may be undef. bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC = nullptr, const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr, unsigned Depth = 0); +/// Returns true if V cannot be undef, but may be poison. +bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC = nullptr, + const Instruction *CtxI = nullptr, + const DominatorTree *DT = nullptr, + unsigned Depth = 0); + /// Return true if undefined behavior would provable be executed on the path to /// OnPathTo if Root produced a posion result. Note that this doesn't say /// anything about whether OnPathTo is actually executed or whether Root is diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 3c2f26e924213..b708ee04c0dd5 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -880,7 +880,7 @@ LazyValueInfoImpl::solveBlockValueSelect(SelectInst *SI, BasicBlock *BB) { Value *Cond = SI->getCondition(); // If the value is undef, a different value may be chosen in // the select condition. - if (isGuaranteedNotToBeUndefOrPoison(Cond, AC)) { + if (isGuaranteedNotToBeUndef(Cond, AC)) { TrueVal = intersect(TrueVal, getValueFromCondition(SI->getTrueValue(), Cond, true)); FalseVal = intersect( @@ -1719,7 +1719,7 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U, if (auto *SI = dyn_cast(CurrI)) { // If the value is undef, a different value may be chosen in // the select condition and at use. - if (!isGuaranteedNotToBeUndefOrPoison(SI->getCondition(), AC)) + if (!isGuaranteedNotToBeUndef(SI->getCondition(), AC)) break; if (CurrU->getOperandNo() == 1) CondVal = getValueFromCondition(V, SI->getCondition(), true); diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 8c29c242215d6..8e7f0c6b81030 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -388,10 +388,9 @@ static void computeKnownBitsMul(const Value *Op0, const Value *Op1, bool NSW, } bool SelfMultiply = Op0 == Op1; - // TODO: SelfMultiply can be poison, but not undef. if (SelfMultiply) SelfMultiply &= - isGuaranteedNotToBeUndefOrPoison(Op0, Q.AC, Q.CxtI, Q.DT, Depth + 1); + isGuaranteedNotToBeUndef(Op0, Q.AC, Q.CxtI, Q.DT, Depth + 1); Known = KnownBits::mul(Known, Known2, SelfMultiply); // Only make use of no-wrap flags if we failed to compute the sign bit @@ -6488,7 +6487,7 @@ OverflowResult llvm::computeOverflowForUnsignedSub(const Value *LHS, // See simplifyICmpWithBinOpOnLHS() for candidates. if (match(RHS, m_URem(m_Specific(LHS), m_Value())) || match(RHS, m_NUWSub(m_Specific(LHS), m_Value()))) - if (isGuaranteedNotToBeUndefOrPoison(LHS, SQ.AC, SQ.CxtI, SQ.DT)) + if (isGuaranteedNotToBeUndef(LHS, SQ.AC, SQ.CxtI, SQ.DT)) return OverflowResult::NeverOverflows; // Checking for conditions implied by dominating conditions may be expensive. @@ -6521,7 +6520,7 @@ OverflowResult llvm::computeOverflowForSignedSub(const Value *LHS, // then determining no-overflow may allow other transforms. if (match(RHS, m_SRem(m_Specific(LHS), m_Value())) || match(RHS, m_NSWSub(m_Specific(LHS), m_Value()))) - if (isGuaranteedNotToBeUndefOrPoison(LHS, SQ.AC, SQ.CxtI, SQ.DT)) + if (isGuaranteedNotToBeUndef(LHS, SQ.AC, SQ.CxtI, SQ.DT)) return OverflowResult::NeverOverflows; // If LHS and RHS each have at least two sign bits, the subtraction @@ -6982,6 +6981,13 @@ bool llvm::isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC, return ::isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth, true); } +bool llvm::isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC, + const Instruction *CtxI, + const DominatorTree *DT, unsigned Depth) { + // TODO: This is currently equivalent to isGuaranteedNotToBeUndefOrPoison(). + return ::isGuaranteedNotToBeUndefOrPoison(V, AC, CtxI, DT, Depth, false); +} + /// Return true if undefined behavior would provably be executed on the path to /// OnPathTo if Root produced a posion result. Note that this doesn't say /// anything about whether OnPathTo is actually executed or whether Root is diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 1bdc441d18ea6..a5cf875ef3541 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -757,7 +757,7 @@ static bool expandUDivOrURem(BinaryOperator *Instr, const ConstantRange &XCR, // NOTE: this transformation introduces two uses of X, // but it may be undef so we must freeze it first. Value *FrozenX = X; - if (!isGuaranteedNotToBeUndefOrPoison(X)) + if (!isGuaranteedNotToBeUndef(X)) FrozenX = B.CreateFreeze(X, X->getName() + ".frozen"); auto *AdjX = B.CreateNUWSub(FrozenX, Y, Instr->getName() + ".urem"); auto *Cmp =