aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp228
1 files changed, 114 insertions, 114 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index ba2b6fe94c18..1dababafb8a6 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -658,7 +658,7 @@ bool LazyValueInfoImpl::isNonNullAtEndOfBlock(Value *Val, BasicBlock *BB) {
Val->getType()->getPointerAddressSpace()))
return false;
- Val = getUnderlyingObject(Val);
+ Val = Val->stripInBoundsOffsets();
return TheCache.isNonNullAtEndOfBlock(Val, BB, [](BasicBlock *BB) {
NonNullPointerSet NonNullPointers;
for (Instruction &I : *BB)
@@ -673,7 +673,7 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueNonLocal(
// If this is the entry block, we must be asking about an argument. The
// value is overdefined.
- if (BB == &BB->getParent()->getEntryBlock()) {
+ if (BB->isEntryBlock()) {
assert(isa<Argument>(Val) && "Unknown live-in to the entry block");
return ValueLatticeElement::getOverdefined();
}
@@ -687,8 +687,8 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueNonLocal(
// find a path to function entry. TODO: We should consider explicitly
// canonicalizing to make this true rather than relying on this happy
// accident.
- for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
- Optional<ValueLatticeElement> EdgeResult = getEdgeValue(Val, *PI, BB);
+ for (BasicBlock *Pred : predecessors(BB)) {
+ Optional<ValueLatticeElement> EdgeResult = getEdgeValue(Val, Pred, BB);
if (!EdgeResult)
// Explore that input, then return here
return None;
@@ -801,22 +801,12 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueSelect(
return None;
ValueLatticeElement &TrueVal = *OptTrueVal;
- // If we hit overdefined, don't ask more queries. We want to avoid poisoning
- // extra slots in the table if we can.
- if (TrueVal.isOverdefined())
- return ValueLatticeElement::getOverdefined();
-
Optional<ValueLatticeElement> OptFalseVal =
getBlockValue(SI->getFalseValue(), BB);
if (!OptFalseVal)
return None;
ValueLatticeElement &FalseVal = *OptFalseVal;
- // If we hit overdefined, don't ask more queries. We want to avoid poisoning
- // extra slots in the table if we can.
- if (FalseVal.isOverdefined())
- return ValueLatticeElement::getOverdefined();
-
if (TrueVal.isConstantRange() && FalseVal.isConstantRange()) {
const ConstantRange &TrueCR = TrueVal.getConstantRange();
const ConstantRange &FalseCR = FalseVal.getConstantRange();
@@ -875,48 +865,6 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueSelect(
FalseVal = intersect(FalseVal,
getValueFromCondition(SI->getFalseValue(), Cond, false));
- // Handle clamp idioms such as:
- // %24 = constantrange<0, 17>
- // %39 = icmp eq i32 %24, 0
- // %40 = add i32 %24, -1
- // %siv.next = select i1 %39, i32 16, i32 %40
- // %siv.next = constantrange<0, 17> not <-1, 17>
- // In general, this can handle any clamp idiom which tests the edge
- // condition via an equality or inequality.
- if (auto *ICI = dyn_cast<ICmpInst>(Cond)) {
- ICmpInst::Predicate Pred = ICI->getPredicate();
- Value *A = ICI->getOperand(0);
- if (ConstantInt *CIBase = dyn_cast<ConstantInt>(ICI->getOperand(1))) {
- auto addConstants = [](ConstantInt *A, ConstantInt *B) {
- assert(A->getType() == B->getType());
- return ConstantInt::get(A->getType(), A->getValue() + B->getValue());
- };
- // See if either input is A + C2, subject to the constraint from the
- // condition that A != C when that input is used. We can assume that
- // that input doesn't include C + C2.
- ConstantInt *CIAdded;
- switch (Pred) {
- default: break;
- case ICmpInst::ICMP_EQ:
- if (match(SI->getFalseValue(), m_Add(m_Specific(A),
- m_ConstantInt(CIAdded)))) {
- auto ResNot = addConstants(CIBase, CIAdded);
- FalseVal = intersect(FalseVal,
- ValueLatticeElement::getNot(ResNot));
- }
- break;
- case ICmpInst::ICMP_NE:
- if (match(SI->getTrueValue(), m_Add(m_Specific(A),
- m_ConstantInt(CIAdded)))) {
- auto ResNot = addConstants(CIBase, CIAdded);
- TrueVal = intersect(TrueVal,
- ValueLatticeElement::getNot(ResNot));
- }
- break;
- };
- }
- }
-
ValueLatticeElement Result = TrueVal;
Result.mergeIn(FalseVal);
return Result;
@@ -1042,8 +990,8 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueIntrinsic(
IntrinsicInst *II, BasicBlock *BB) {
if (!ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
- << "' - overdefined (unknown intrinsic).\n");
- return ValueLatticeElement::getOverdefined();
+ << "' - unknown intrinsic.\n");
+ return getFromRangeMetadata(II);
}
SmallVector<ConstantRange, 2> OpRanges;
@@ -1076,15 +1024,25 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueExtractValue(
return ValueLatticeElement::getOverdefined();
}
-static bool matchICmpOperand(const APInt *&Offset, Value *LHS, Value *Val,
+static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val,
ICmpInst::Predicate Pred) {
if (LHS == Val)
return true;
// Handle range checking idiom produced by InstCombine. We will subtract the
// offset from the allowed range for RHS in this case.
- if (match(LHS, m_Add(m_Specific(Val), m_APInt(Offset))))
+ const APInt *C;
+ if (match(LHS, m_Add(m_Specific(Val), m_APInt(C)))) {
+ Offset = *C;
return true;
+ }
+
+ // Handle the symmetric case. This appears in saturation patterns like
+ // (x == 16) ? 16 : (x + 1).
+ if (match(Val, m_Add(m_Specific(LHS), m_APInt(C)))) {
+ Offset = -*C;
+ return true;
+ }
// If (x | y) < C, then (x < C) && (y < C).
if (match(LHS, m_c_Or(m_Specific(Val), m_Value())) &&
@@ -1101,7 +1059,7 @@ static bool matchICmpOperand(const APInt *&Offset, Value *LHS, Value *Val,
/// Get value range for a "(Val + Offset) Pred RHS" condition.
static ValueLatticeElement getValueFromSimpleICmpCondition(
- CmpInst::Predicate Pred, Value *RHS, const APInt *Offset) {
+ CmpInst::Predicate Pred, Value *RHS, const APInt &Offset) {
ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(),
/*isFullSet=*/true);
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
@@ -1112,11 +1070,7 @@ static ValueLatticeElement getValueFromSimpleICmpCondition(
ConstantRange TrueValues =
ConstantRange::makeAllowedICmpRegion(Pred, RHSRange);
-
- if (Offset)
- TrueValues = TrueValues.subtract(*Offset);
-
- return ValueLatticeElement::getRange(std::move(TrueValues));
+ return ValueLatticeElement::getRange(TrueValues.subtract(Offset));
}
static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
@@ -1137,10 +1091,11 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
}
}
- if (!Val->getType()->isIntegerTy())
+ Type *Ty = Val->getType();
+ if (!Ty->isIntegerTy())
return ValueLatticeElement::getOverdefined();
- const APInt *Offset = nullptr;
+ APInt Offset(Ty->getScalarSizeInBits(), 0);
if (matchICmpOperand(Offset, LHS, Val, EdgePred))
return getValueFromSimpleICmpCondition(EdgePred, RHS, Offset);
@@ -1148,17 +1103,27 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
if (matchICmpOperand(Offset, RHS, Val, SwappedPred))
return getValueFromSimpleICmpCondition(SwappedPred, LHS, Offset);
- // If (Val & Mask) == C then all the masked bits are known and we can compute
- // a value range based on that.
const APInt *Mask, *C;
- if (EdgePred == ICmpInst::ICMP_EQ &&
- match(LHS, m_And(m_Specific(Val), m_APInt(Mask))) &&
+ if (match(LHS, m_And(m_Specific(Val), m_APInt(Mask))) &&
match(RHS, m_APInt(C))) {
- KnownBits Known;
- Known.Zero = ~*C & *Mask;
- Known.One = *C & *Mask;
- return ValueLatticeElement::getRange(
- ConstantRange::fromKnownBits(Known, /*IsSigned*/ false));
+ // If (Val & Mask) == C then all the masked bits are known and we can
+ // compute a value range based on that.
+ if (EdgePred == ICmpInst::ICMP_EQ) {
+ KnownBits Known;
+ Known.Zero = ~*C & *Mask;
+ Known.One = *C & *Mask;
+ return ValueLatticeElement::getRange(
+ ConstantRange::fromKnownBits(Known, /*IsSigned*/ false));
+ }
+ // If (Val & Mask) != 0 then the value must be larger than the lowest set
+ // bit of Mask.
+ if (EdgePred == ICmpInst::ICMP_NE && !Mask->isNullValue() &&
+ C->isNullValue()) {
+ unsigned BitWidth = Ty->getIntegerBitWidth();
+ return ValueLatticeElement::getRange(ConstantRange::getNonEmpty(
+ APInt::getOneBitSet(BitWidth, Mask->countTrailingZeros()),
+ APInt::getNullValue(BitWidth)));
+ }
}
return ValueLatticeElement::getOverdefined();
@@ -1186,20 +1151,20 @@ static ValueLatticeElement getValueFromOverflowCondition(
return ValueLatticeElement::getRange(NWR);
}
-static ValueLatticeElement
-getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest,
- SmallDenseMap<Value*, ValueLatticeElement> &Visited);
-
-static ValueLatticeElement
+static Optional<ValueLatticeElement>
getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest,
- SmallDenseMap<Value*, ValueLatticeElement> &Visited) {
- if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cond))
- return getValueFromICmpCondition(Val, ICI, isTrueDest);
-
- if (auto *EVI = dyn_cast<ExtractValueInst>(Cond))
- if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand()))
- if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 1)
- return getValueFromOverflowCondition(Val, WO, isTrueDest);
+ bool isRevisit,
+ SmallDenseMap<Value *, ValueLatticeElement> &Visited,
+ SmallVectorImpl<Value *> &Worklist) {
+ if (!isRevisit) {
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cond))
+ return getValueFromICmpCondition(Val, ICI, isTrueDest);
+
+ if (auto *EVI = dyn_cast<ExtractValueInst>(Cond))
+ if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand()))
+ if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 1)
+ return getValueFromOverflowCondition(Val, WO, isTrueDest);
+ }
Value *L, *R;
bool IsAnd;
@@ -1210,46 +1175,63 @@ getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest,
else
return ValueLatticeElement::getOverdefined();
- // Prevent infinite recursion if Cond references itself as in this example:
- // Cond: "%tmp4 = and i1 %tmp4, undef"
- // BL: "%tmp4 = and i1 %tmp4, undef"
- // BR: "i1 undef"
- if (L == Cond || R == Cond)
- return ValueLatticeElement::getOverdefined();
+ auto LV = Visited.find(L);
+ auto RV = Visited.find(R);
// if (L && R) -> intersect L and R
// if (!(L || R)) -> intersect L and R
// if (L || R) -> union L and R
// if (!(L && R)) -> union L and R
- if (isTrueDest ^ IsAnd) {
- ValueLatticeElement V = getValueFromCondition(Val, L, isTrueDest, Visited);
+ if ((isTrueDest ^ IsAnd) && (LV != Visited.end())) {
+ ValueLatticeElement V = LV->second;
if (V.isOverdefined())
return V;
- V.mergeIn(getValueFromCondition(Val, R, isTrueDest, Visited));
- return V;
+ if (RV != Visited.end()) {
+ V.mergeIn(RV->second);
+ return V;
+ }
}
- return intersect(getValueFromCondition(Val, L, isTrueDest, Visited),
- getValueFromCondition(Val, R, isTrueDest, Visited));
-}
-
-static ValueLatticeElement
-getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest,
- SmallDenseMap<Value*, ValueLatticeElement> &Visited) {
- auto I = Visited.find(Cond);
- if (I != Visited.end())
- return I->second;
+ if (LV == Visited.end() || RV == Visited.end()) {
+ assert(!isRevisit);
+ if (LV == Visited.end())
+ Worklist.push_back(L);
+ if (RV == Visited.end())
+ Worklist.push_back(R);
+ return None;
+ }
- auto Result = getValueFromConditionImpl(Val, Cond, isTrueDest, Visited);
- Visited[Cond] = Result;
- return Result;
+ return intersect(LV->second, RV->second);
}
ValueLatticeElement getValueFromCondition(Value *Val, Value *Cond,
bool isTrueDest) {
assert(Cond && "precondition");
SmallDenseMap<Value*, ValueLatticeElement> Visited;
- return getValueFromCondition(Val, Cond, isTrueDest, Visited);
+ SmallVector<Value *> Worklist;
+
+ Worklist.push_back(Cond);
+ do {
+ Value *CurrentCond = Worklist.back();
+ // Insert an Overdefined placeholder into the set to prevent
+ // infinite recursion if there exists IRs that use not
+ // dominated by its def as in this example:
+ // "%tmp3 = or i1 undef, %tmp4"
+ // "%tmp4 = or i1 undef, %tmp3"
+ auto Iter =
+ Visited.try_emplace(CurrentCond, ValueLatticeElement::getOverdefined());
+ bool isRevisit = !Iter.second;
+ Optional<ValueLatticeElement> Result = getValueFromConditionImpl(
+ Val, CurrentCond, isTrueDest, isRevisit, Visited, Worklist);
+ if (Result) {
+ Visited[CurrentCond] = *Result;
+ Worklist.pop_back();
+ }
+ } while (!Worklist.empty());
+
+ auto Result = Visited.find(Cond);
+ assert(Result != Visited.end());
+ return Result->second;
}
// Return true if Usr has Op as an operand, otherwise false.
@@ -1857,6 +1839,24 @@ LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C,
return Unknown;
}
+LazyValueInfo::Tristate LazyValueInfo::getPredicateAt(unsigned P, Value *LHS,
+ Value *RHS,
+ Instruction *CxtI,
+ bool UseBlockValue) {
+ CmpInst::Predicate Pred = (CmpInst::Predicate)P;
+
+ if (auto *C = dyn_cast<Constant>(RHS))
+ return getPredicateAt(P, LHS, C, CxtI, UseBlockValue);
+ if (auto *C = dyn_cast<Constant>(LHS))
+ return getPredicateAt(CmpInst::getSwappedPredicate(Pred), RHS, C, CxtI,
+ UseBlockValue);
+
+ // Got two non-Constant values. While we could handle them somewhat,
+ // by getting their constant ranges, and applying ConstantRange::icmp(),
+ // so far it did not appear to be profitable.
+ return LazyValueInfo::Unknown;
+}
+
void LazyValueInfo::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
BasicBlock *NewSucc) {
if (PImpl) {