diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:06:42 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:06:42 +0000 |
commit | 6f8fc217eaa12bf657be1c6468ed9938d10168b3 (patch) | |
tree | a1fd89b864d9b93e2ad68fe1dcf7afee2e3c8d76 /llvm/lib/Analysis/LazyValueInfo.cpp | |
parent | 77fc4c146f0870ffb09c1afb823ccbe742c5e6ff (diff) | |
download | src-6f8fc217eaa12bf657be1c6468ed9938d10168b3.tar.gz src-6f8fc217eaa12bf657be1c6468ed9938d10168b3.zip |
Vendor import of llvm-project main llvmorg-14-init-17616-g024a1fab5c35.vendor/llvm-project/llvmorg-14-init-17616-g024a1fab5c35
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r-- | llvm/lib/Analysis/LazyValueInfo.cpp | 65 |
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; } |