Skip to content

Commit

Permalink
[ValueTracking] Add isGuaranteedNotToBeUndef() variant (NFC)
Browse files Browse the repository at this point in the history
We have a bunch of places where we have to guard against undef
to avoid multi-use issues, but would be fine with poison. Use a
different function for these to make it clear, and to indicate that
this check can be removed once we no longer support undef. I've
replaced some of the obvious cases, but there's probably more.

For now, the implementation is the same as UndefOrPoison, it just
has a more precise name.
  • Loading branch information
nikic committed Dec 4, 2023
1 parent 5c672d8 commit 4275da2
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 7 deletions.
8 changes: 8 additions & 0 deletions llvm/include/llvm/Analysis/ValueTracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Analysis/LazyValueInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -1719,7 +1719,7 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
if (auto *SI = dyn_cast<SelectInst>(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);
Expand Down
14 changes: 10 additions & 4 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down

0 comments on commit 4275da2

Please sign in to comment.