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.cpp65
1 files changed, 35 insertions, 30 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 5b5d48bf6fe5..e311b40ab25c 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -395,7 +395,8 @@ class LazyValueInfoImpl {
/// if it exists in the module.
Function *GuardDecl;
- Optional<ValueLatticeElement> getBlockValue(Value *Val, BasicBlock *BB);
+ Optional<ValueLatticeElement> getBlockValue(Value *Val, BasicBlock *BB,
+ Instruction *CxtI);
Optional<ValueLatticeElement> getEdgeValue(Value *V, BasicBlock *F,
BasicBlock *T, Instruction *CxtI = nullptr);
@@ -533,15 +534,17 @@ void LazyValueInfoImpl::solve() {
}
}
-Optional<ValueLatticeElement> LazyValueInfoImpl::getBlockValue(Value *Val,
- BasicBlock *BB) {
+Optional<ValueLatticeElement> LazyValueInfoImpl::getBlockValue(
+ Value *Val, BasicBlock *BB, Instruction *CxtI) {
// If already a constant, there is nothing to compute.
if (Constant *VC = dyn_cast<Constant>(Val))
return ValueLatticeElement::get(VC);
if (Optional<ValueLatticeElement> OptLatticeVal =
- TheCache.getCachedValueInfo(Val, BB))
+ TheCache.getCachedValueInfo(Val, BB)) {
+ intersectAssumeOrGuardBlockValueConstantRange(Val, *OptLatticeVal, CxtI);
return OptLatticeVal;
+ }
// We have hit a cycle, assume overdefined.
if (!pushBlockValue({ BB, Val }))
@@ -792,31 +795,41 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
}
}
+static ConstantRange getConstantRangeOrFull(const ValueLatticeElement &Val,
+ Type *Ty, const DataLayout &DL) {
+ if (Val.isConstantRange())
+ return Val.getConstantRange();
+ return ConstantRange::getFull(DL.getTypeSizeInBits(Ty));
+}
+
Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueSelect(
SelectInst *SI, BasicBlock *BB) {
// Recurse on our inputs if needed
Optional<ValueLatticeElement> OptTrueVal =
- getBlockValue(SI->getTrueValue(), BB);
+ getBlockValue(SI->getTrueValue(), BB, SI);
if (!OptTrueVal)
return None;
ValueLatticeElement &TrueVal = *OptTrueVal;
Optional<ValueLatticeElement> OptFalseVal =
- getBlockValue(SI->getFalseValue(), BB);
+ getBlockValue(SI->getFalseValue(), BB, SI);
if (!OptFalseVal)
return None;
ValueLatticeElement &FalseVal = *OptFalseVal;
- if (TrueVal.isConstantRange() && FalseVal.isConstantRange()) {
- const ConstantRange &TrueCR = TrueVal.getConstantRange();
- const ConstantRange &FalseCR = FalseVal.getConstantRange();
+ if (TrueVal.isConstantRange() || FalseVal.isConstantRange()) {
+ const ConstantRange &TrueCR =
+ getConstantRangeOrFull(TrueVal, SI->getType(), DL);
+ const ConstantRange &FalseCR =
+ getConstantRangeOrFull(FalseVal, SI->getType(), DL);
Value *LHS = nullptr;
Value *RHS = nullptr;
SelectPatternResult SPR = matchSelectPattern(SI, LHS, RHS);
// Is this a min specifically of our two inputs? (Avoid the risk of
// ValueTracking getting smarter looking back past our immediate inputs.)
if (SelectPatternResult::isMinOrMax(SPR.Flavor) &&
- LHS == SI->getTrueValue() && RHS == SI->getFalseValue()) {
+ ((LHS == SI->getTrueValue() && RHS == SI->getFalseValue()) ||
+ (RHS == SI->getTrueValue() && LHS == SI->getFalseValue()))) {
ConstantRange ResultCR = [&]() {
switch (SPR.Flavor) {
default:
@@ -873,17 +886,10 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueSelect(
Optional<ConstantRange> LazyValueInfoImpl::getRangeFor(Value *V,
Instruction *CxtI,
BasicBlock *BB) {
- Optional<ValueLatticeElement> OptVal = getBlockValue(V, BB);
+ Optional<ValueLatticeElement> OptVal = getBlockValue(V, BB, CxtI);
if (!OptVal)
return None;
-
- ValueLatticeElement &Val = *OptVal;
- intersectAssumeOrGuardBlockValueConstantRange(V, Val, CxtI);
- if (Val.isConstantRange())
- return Val.getConstantRange();
-
- const unsigned OperandBitWidth = DL.getTypeSizeInBits(V->getType());
- return ConstantRange::getFull(OperandBitWidth);
+ return getConstantRangeOrFull(*OptVal, V->getType(), DL);
}
Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueCast(
@@ -1017,7 +1023,7 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::solveBlockValueExtractValue(
if (Value *V = SimplifyExtractValueInst(
EVI->getAggregateOperand(), EVI->getIndices(),
EVI->getModule()->getDataLayout()))
- return getBlockValue(V, BB);
+ return getBlockValue(V, BB, EVI);
LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
<< "' - overdefined (unknown extractvalue).\n");
@@ -1126,14 +1132,16 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
}
// If (X urem Modulus) >= C, then X >= C.
+ // If trunc X >= C, then X >= C.
// TODO: An upper bound could be computed as well.
- if (match(LHS, m_URem(m_Specific(Val), m_Value())) &&
+ if (match(LHS, m_CombineOr(m_URem(m_Specific(Val), m_Value()),
+ m_Trunc(m_Specific(Val)))) &&
match(RHS, m_APInt(C))) {
// Use the icmp region so we don't have to deal with different predicates.
ConstantRange CR = ConstantRange::makeExactICmpRegion(EdgePred, *C);
if (!CR.isEmptySet())
return ValueLatticeElement::getRange(ConstantRange::getNonEmpty(
- CR.getUnsignedMin(), APInt(BitWidth, 0)));
+ CR.getUnsignedMin().zextOrSelf(BitWidth), APInt(BitWidth, 0)));
}
return ValueLatticeElement::getOverdefined();
@@ -1430,14 +1438,12 @@ Optional<ValueLatticeElement> LazyValueInfoImpl::getEdgeValue(
// Can't get any more precise here
return LocalResult;
- Optional<ValueLatticeElement> OptInBlock = getBlockValue(Val, BBFrom);
+ Optional<ValueLatticeElement> OptInBlock =
+ getBlockValue(Val, BBFrom, BBFrom->getTerminator());
if (!OptInBlock)
return None;
ValueLatticeElement &InBlock = *OptInBlock;
- // Try to intersect ranges of the BB and the constraint on the edge.
- intersectAssumeOrGuardBlockValueConstantRange(Val, InBlock,
- BBFrom->getTerminator());
// We can use the context instruction (generically the ultimate instruction
// the calling pass is trying to simplify) here, even though the result of
// this function is generally cached when called from the solve* functions
@@ -1457,15 +1463,14 @@ ValueLatticeElement LazyValueInfoImpl::getValueInBlock(Value *V, BasicBlock *BB,
<< BB->getName() << "'\n");
assert(BlockValueStack.empty() && BlockValueSet.empty());
- Optional<ValueLatticeElement> OptResult = getBlockValue(V, BB);
+ Optional<ValueLatticeElement> OptResult = getBlockValue(V, BB, CxtI);
if (!OptResult) {
solve();
- OptResult = getBlockValue(V, BB);
+ OptResult = getBlockValue(V, BB, CxtI);
assert(OptResult && "Value not available after solving");
}
- ValueLatticeElement Result = *OptResult;
- intersectAssumeOrGuardBlockValueConstantRange(V, Result, CxtI);
+ ValueLatticeElement Result = *OptResult;
LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
return Result;
}