45using namespace PatternMatch;
47#define DEBUG_TYPE "lazy-value-info"
58 "Lazy Value Information Analysis",
false,
true)
92 class LazyValueInfoCache;
93 struct LVIValueHandle final :
public CallbackVH {
94 LazyValueInfoCache *Parent;
96 LVIValueHandle(
Value *V, LazyValueInfoCache *
P =
nullptr)
99 void deleted()
override;
100 void allUsesReplacedWith(
Value *V)
override {
111class LazyValueInfoCache {
116 struct BlockCacheEntry {
121 std::optional<NonNullPointerSet> NonNullPointers;
130 const BlockCacheEntry *getBlockEntry(
BasicBlock *BB)
const {
131 auto It = BlockCache.
find_as(BB);
132 if (It == BlockCache.
end())
134 return It->second.get();
137 BlockCacheEntry *getOrCreateBlockEntry(
BasicBlock *BB) {
138 auto It = BlockCache.
find_as(BB);
139 if (It == BlockCache.
end())
140 It = BlockCache.
insert({BB, std::make_unique<BlockCacheEntry>()}).first;
142 return It->second.get();
145 void addValueHandle(
Value *Val) {
146 auto HandleIt = ValueHandles.
find_as(Val);
147 if (HandleIt == ValueHandles.
end())
148 ValueHandles.
insert({Val,
this});
154 BlockCacheEntry *
Entry = getOrCreateBlockEntry(BB);
158 if (
Result.isOverdefined())
159 Entry->OverDefined.insert(Val);
166 std::optional<ValueLatticeElement> getCachedValueInfo(
Value *V,
168 const BlockCacheEntry *
Entry = getBlockEntry(BB);
172 if (
Entry->OverDefined.count(V))
175 auto LatticeIt =
Entry->LatticeElements.find_as(V);
176 if (LatticeIt ==
Entry->LatticeElements.end())
179 return LatticeIt->second;
185 BlockCacheEntry *
Entry = getOrCreateBlockEntry(BB);
186 if (!
Entry->NonNullPointers) {
187 Entry->NonNullPointers = InitFn(BB);
192 return Entry->NonNullPointers->count(V);
198 ValueHandles.
clear();
202 void eraseValue(
Value *V);
215void LazyValueInfoCache::eraseValue(
Value *V) {
216 for (
auto &Pair : BlockCache) {
217 Pair.second->LatticeElements.erase(V);
218 Pair.second->OverDefined.erase(V);
219 if (Pair.second->NonNullPointers)
220 Pair.second->NonNullPointers->erase(V);
223 auto HandleIt = ValueHandles.
find_as(V);
224 if (HandleIt != ValueHandles.
end())
225 ValueHandles.
erase(HandleIt);
228void LVIValueHandle::deleted() {
231 Parent->eraseValue(*
this);
234void LazyValueInfoCache::eraseBlock(
BasicBlock *BB) {
235 BlockCache.erase(BB);
238void LazyValueInfoCache::threadEdgeImpl(
BasicBlock *OldSucc,
250 std::vector<BasicBlock*> worklist;
251 worklist.push_back(OldSucc);
253 const BlockCacheEntry *
Entry = getBlockEntry(OldSucc);
254 if (!Entry ||
Entry->OverDefined.empty())
257 Entry->OverDefined.end());
263 while (!worklist.empty()) {
268 if (ToUpdate == NewSucc)
continue;
271 auto OI = BlockCache.find_as(ToUpdate);
272 if (OI == BlockCache.end() || OI->second->OverDefined.empty())
274 auto &ValueSet = OI->second->OverDefined;
276 bool changed =
false;
277 for (
Value *V : ValsToClear) {
278 if (!ValueSet.erase(V))
286 if (!changed)
continue;
304 : LVIImpl(
L), DT(DTree) {}
306 void emitBasicBlockStartAnnot(
const BasicBlock *BB,
317 LazyValueInfoCache TheCache;
329 bool pushBlockValue(
const std::pair<BasicBlock *, Value *> &BV) {
330 if (!BlockValueSet.
insert(BV).second)
334 << BV.first->getName() <<
"\n");
346 std::optional<ValueLatticeElement> getBlockValue(
Value *Val,
BasicBlock *BB,
356 std::optional<ValueLatticeElement> solveBlockValueImpl(
Value *Val,
358 std::optional<ValueLatticeElement> solveBlockValueNonLocal(
Value *Val,
360 std::optional<ValueLatticeElement> solveBlockValuePHINode(
PHINode *PN,
362 std::optional<ValueLatticeElement> solveBlockValueSelect(
SelectInst *S,
366 std::optional<ValueLatticeElement> solveBlockValueBinaryOpImpl(
370 std::optional<ValueLatticeElement>
372 std::optional<ValueLatticeElement> solveBlockValueCast(
CastInst *CI,
374 std::optional<ValueLatticeElement>
376 std::optional<ValueLatticeElement> solveBlockValueIntrinsic(
IntrinsicInst *
II,
378 std::optional<ValueLatticeElement>
380 std::optional<ValueLatticeElement>
383 void intersectAssumeOrGuardBlockValueConstantRange(
Value *Val,
393 std::optional<ValueLatticeElement>
398 std::optional<ValueLatticeElement>
399 getValueFromICmpCondition(
Value *Val,
ICmpInst *ICI,
bool isTrueDest,
404 std::optional<ValueLatticeElement>
406 bool UseBlockValue,
unsigned Depth = 0);
408 std::optional<ValueLatticeElement> getEdgeValueLocal(
Value *Val,
441 LazyValueInfoAnnotatedWriter Writer(
this, DTree);
442 F.print(
OS, &Writer);
452 TheCache.eraseBlock(BB);
461 : AC(AC),
DL(
DL), GuardDecl(GuardDecl) {}
465void LazyValueInfoImpl::solve() {
469 unsigned processedCount = 0;
470 while (!BlockValueStack.empty()) {
482 dbgs() <<
"Giving up on stack because we are getting too deep\n");
484 while (!StartingStack.
empty()) {
485 std::pair<BasicBlock *, Value *> &
e = StartingStack.
back();
486 TheCache.insertResult(
e.second,
e.first,
490 BlockValueSet.clear();
491 BlockValueStack.clear();
494 std::pair<BasicBlock *, Value *>
e = BlockValueStack.back();
495 assert(BlockValueSet.count(e) &&
"Stack value should be in BlockValueSet!");
496 unsigned StackSize = BlockValueStack.size();
499 if (solveBlockValue(
e.second,
e.first)) {
501 assert(BlockValueStack.size() == StackSize &&
502 BlockValueStack.back() == e &&
"Nothing should have been pushed!");
504 std::optional<ValueLatticeElement> BBLV =
505 TheCache.getCachedValueInfo(
e.second,
e.first);
506 assert(BBLV &&
"Result should be in cache!");
508 dbgs() <<
"POP " << *
e.second <<
" in " <<
e.first->getName() <<
" = "
512 BlockValueStack.pop_back();
513 BlockValueSet.erase(e);
516 assert(BlockValueStack.size() == StackSize + 1 &&
517 "Exactly one element should have been pushed!");
522std::optional<ValueLatticeElement>
526 if (
Constant *VC = dyn_cast<Constant>(Val))
529 if (std::optional<ValueLatticeElement> OptLatticeVal =
530 TheCache.getCachedValueInfo(Val, BB)) {
531 intersectAssumeOrGuardBlockValueConstantRange(Val, *OptLatticeVal, CxtI);
532 return OptLatticeVal;
536 if (!pushBlockValue({ BB, Val }))
547 case Instruction::Call:
548 case Instruction::Invoke:
549 if (std::optional<ConstantRange>
Range = cast<CallBase>(BBI)->
getRange())
552 case Instruction::Load:
554 if (isa<IntegerType>(BBI->
getType())) {
565 assert(!isa<Constant>(Val) &&
"Value should not be constant");
566 assert(!TheCache.getCachedValueInfo(Val, BB) &&
567 "Value should not be in cache");
571 std::optional<ValueLatticeElement> Res = solveBlockValueImpl(Val, BB);
576 TheCache.insertResult(Val, BB, *Res);
580std::optional<ValueLatticeElement>
584 return solveBlockValueNonLocal(Val, BB);
586 if (
PHINode *PN = dyn_cast<PHINode>(BBI))
587 return solveBlockValuePHINode(PN, BB);
589 if (
auto *SI = dyn_cast<SelectInst>(BBI))
590 return solveBlockValueSelect(SI, BB);
606 if (
auto *CI = dyn_cast<CastInst>(BBI))
607 return solveBlockValueCast(CI, BB);
610 return solveBlockValueBinaryOp(BO, BB);
612 if (
auto *IEI = dyn_cast<InsertElementInst>(BBI))
613 return solveBlockValueInsertElement(IEI, BB);
615 if (
auto *EVI = dyn_cast<ExtractValueInst>(BBI))
616 return solveBlockValueExtractValue(EVI, BB);
618 if (
auto *
II = dyn_cast<IntrinsicInst>(BBI))
619 return solveBlockValueIntrinsic(
II, BB);
623 <<
"' - unknown inst def found.\n");
628 bool IsDereferenced =
true) {
630 if (
Ptr->getType()->getPointerAddressSpace() == 0)
632 :
Ptr->stripInBoundsOffsets());
637 if (
LoadInst *L = dyn_cast<LoadInst>(
I)) {
639 }
else if (
StoreInst *S = dyn_cast<StoreInst>(
I)) {
642 if (
MI->isVolatile())
return;
646 if (!Len || Len->isZero())
return;
651 }
else if (
auto *CB = dyn_cast<CallBase>(
I)) {
652 for (
auto &U : CB->args()) {
653 if (U->getType()->isPointerTy() &&
654 CB->paramHasNonNullAttr(CB->getArgOperandNo(&U),
661bool LazyValueInfoImpl::isNonNullAtEndOfBlock(
Value *Val,
BasicBlock *BB) {
667 return TheCache.isNonNullAtEndOfBlock(Val, BB, [](
BasicBlock *BB) {
668 NonNullPointerSet NonNullPointers;
671 return NonNullPointers;
675std::optional<ValueLatticeElement>
676LazyValueInfoImpl::solveBlockValueNonLocal(
Value *Val,
BasicBlock *BB) {
681 assert(isa<Argument>(Val) &&
"Unknown live-in to the entry block");
682 if (std::optional<ConstantRange>
Range = cast<Argument>(Val)->
getRange())
697 std::optional<ValueLatticeElement> EdgeResult = getEdgeValue(Val, Pred, BB);
702 Result.mergeIn(*EdgeResult);
706 if (
Result.isOverdefined()) {
708 <<
"' - overdefined because of pred '"
709 << Pred->getName() <<
"' (non local).\n");
719std::optional<ValueLatticeElement>
732 std::optional<ValueLatticeElement> EdgeResult =
733 getEdgeValue(PhiVal, PhiBB, BB, PN);
738 Result.mergeIn(*EdgeResult);
742 if (
Result.isOverdefined()) {
744 <<
"' - overdefined because of pred (local).\n");
751 assert(!
Result.isOverdefined() &&
"Possible PHI in entry block?");
757void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
759 BBI = BBI ? BBI : dyn_cast<Instruction>(Val);
771 auto *
I = cast<CallInst>(AssumeVH);
775 BBLV = BBLV.
intersect(*getValueFromCondition(Val,
I->getArgOperand(0),
781 if (GuardDecl && !GuardDecl->
use_empty() &&
798 isNonNullAtEndOfBlock(Val, BB))
803std::optional<ValueLatticeElement>
806 std::optional<ValueLatticeElement> OptTrueVal =
807 getBlockValue(
SI->getTrueValue(), BB, SI);
812 std::optional<ValueLatticeElement> OptFalseVal =
813 getBlockValue(
SI->getFalseValue(), BB, SI);
827 ((LHS ==
SI->getTrueValue() && RHS ==
SI->getFalseValue()) ||
828 (RHS ==
SI->getTrueValue() && LHS ==
SI->getFalseValue()))) {
834 return TrueCR.
smin(FalseCR);
836 return TrueCR.
umin(FalseCR);
838 return TrueCR.
smax(FalseCR);
840 return TrueCR.
umax(FalseCR);
844 ResultCR,
TrueVal.isConstantRangeIncludingUndef() ||
845 FalseVal.isConstantRangeIncludingUndef());
849 if (LHS ==
SI->getTrueValue())
851 TrueCR.
abs(),
TrueVal.isConstantRangeIncludingUndef());
852 if (LHS ==
SI->getFalseValue())
854 FalseCR.
abs(),
FalseVal.isConstantRangeIncludingUndef());
859 if (LHS ==
SI->getTrueValue())
862 if (LHS ==
SI->getFalseValue())
876 TrueVal.intersect(*getValueFromCondition(
SI->getTrueValue(),
Cond,
880 FalseVal.intersect(*getValueFromCondition(
SI->getFalseValue(),
Cond,
890std::optional<ConstantRange>
892 std::optional<ValueLatticeElement> OptVal = getBlockValue(V, BB, CxtI);
895 return OptVal->asConstantRange(
V->getType());
898std::optional<ValueLatticeElement>
904 case Instruction::Trunc:
905 case Instruction::SExt:
906 case Instruction::ZExt:
911 <<
"' - overdefined (unknown cast).\n");
918 std::optional<ConstantRange> LHSRes = getRangeFor(CI->
getOperand(0), CI, BB);
933std::optional<ValueLatticeElement>
934LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
941 auto ThreadBinOpOverSelect =
943 bool XIsLHS) -> std::optional<ValueLatticeElement> {
946 Constant *TrueC = dyn_cast<Constant>(
Y->getTrueValue());
949 Constant *FalseC = dyn_cast<Constant>(
Y->getFalseValue());
958 ->asConstantRange(
X->getType()));
962 ->asConstantRange(
X->getType()));
968 OpFn(TrueX, TrueY).unionWith(OpFn(FalseX, FalseY)));
970 OpFn(TrueY, TrueX).unionWith(OpFn(FalseY, FalseX)));
977 std::optional<ConstantRange> LHSRes = getRangeFor(LHS,
I, BB);
982 if (
auto *SI = dyn_cast<SelectInst>(RHS)) {
983 if (
auto Res = ThreadBinOpOverSelect(LHS, *LHSRes, SI,
true))
987 std::optional<ConstantRange> RHSRes = getRangeFor(RHS,
I, BB);
992 if (
auto *SI = dyn_cast<SelectInst>(LHS)) {
993 if (
auto Res = ThreadBinOpOverSelect(RHS, *RHSRes, SI,
false))
1002std::optional<ValueLatticeElement>
1005 "all operands to binary operators are sized");
1006 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO)) {
1007 unsigned NoWrapKind = OBO->getNoWrapKind();
1008 return solveBlockValueBinaryOpImpl(
1015 return solveBlockValueBinaryOpImpl(
1021std::optional<ValueLatticeElement>
1024 return solveBlockValueBinaryOpImpl(
1030std::optional<ValueLatticeElement>
1035 <<
"' - unknown intrinsic.\n");
1041 std::optional<ConstantRange>
Range = getRangeFor(
Op,
II, BB);
1043 return std::nullopt;
1052std::optional<ValueLatticeElement>
1055 std::optional<ValueLatticeElement> OptEltVal =
1058 return std::nullopt;
1061 std::optional<ValueLatticeElement> OptVecVal =
1064 return std::nullopt;
1070 if (OptEltVal->isConstant())
1077std::optional<ValueLatticeElement>
1082 return solveBlockValueOverflowIntrinsic(WO, BB);
1089 return getBlockValue(V, BB, EVI);
1092 <<
"' - overdefined (unknown extractvalue).\n");
1130std::optional<ValueLatticeElement>
1135 bool UseBlockValue) {
1138 if (
ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
1140 }
else if (UseBlockValue) {
1141 std::optional<ValueLatticeElement>
R =
1142 getBlockValue(RHS, CxtI->
getParent(), CxtI);
1144 return std::nullopt;
1153static std::optional<ConstantRange>
1156 bool Invert =
false;
1163 if (
RHS.isMaxSignedValue())
1164 return std::nullopt;
1168 if (
auto CR = Fn(
RHS))
1169 return Invert ? CR->inverse() : CR;
1170 return std::nullopt;
1178 auto *RHSConst = dyn_cast<ConstantInt>(
RHS);
1194std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
1195 Value *Val,
ICmpInst *ICI,
bool isTrueDest,
bool UseBlockValue) {
1203 if (isa<Constant>(RHS)) {
1207 else if (!isa<UndefValue>(RHS))
1219 return getValueFromSimpleICmpCondition(EdgePred, RHS,
Offset, ICI,
1224 return getValueFromSimpleICmpCondition(SwappedPred, LHS,
Offset, ICI,
1264 const APInt *ShAmtC;
1269 EdgePred, *
C, [&](
const APInt &RHS) -> std::optional<ConstantRange> {
1271 if ((
New.ashr(*ShAmtC)) != RHS)
1272 return std::nullopt;
1286 if ((
X == LHS &&
Y == RHS) || (
X == RHS &&
Y == LHS)) {
1340std::optional<ValueLatticeElement>
1342 bool IsTrueDest,
bool UseBlockValue,
1345 return getValueFromICmpCondition(Val, ICI, IsTrueDest, UseBlockValue);
1347 if (
auto *Trunc = dyn_cast<TruncInst>(
Cond))
1348 return getValueFromTrunc(Val, Trunc, IsTrueDest);
1350 if (
auto *EVI = dyn_cast<ExtractValueInst>(
Cond))
1360 return getValueFromCondition(Val,
N, !IsTrueDest, UseBlockValue,
Depth);
1371 std::optional<ValueLatticeElement> LV =
1372 getValueFromCondition(Val, L, IsTrueDest, UseBlockValue,
Depth);
1374 return std::nullopt;
1375 std::optional<ValueLatticeElement> RV =
1376 getValueFromCondition(Val, R, IsTrueDest, UseBlockValue,
Depth);
1378 return std::nullopt;
1384 if (IsTrueDest ^ IsAnd) {
1389 return LV->intersect(*RV);
1402 return isa<CastInst>(Usr) || isa<BinaryOperator>(Usr) || isa<FreezeInst>(Usr);
1410 const APInt &OpConstVal,
1415 if (
auto *CI = dyn_cast<CastInst>(Usr)) {
1417 if (
auto *
C = dyn_cast_or_null<ConstantInt>(
1422 }
else if (
auto *BO = dyn_cast<BinaryOperator>(Usr)) {
1425 assert((Op0Match || Op1Match) &&
1426 "Operand 0 nor Operand 1 isn't a match");
1429 if (
auto *
C = dyn_cast_or_null<ConstantInt>(
1433 }
else if (isa<FreezeInst>(Usr)) {
1434 assert(cast<FreezeInst>(Usr)->getOperand(0) ==
Op &&
"Operand 0 isn't Op");
1441std::optional<ValueLatticeElement>
1449 if (BI->isConditional() &&
1450 BI->getSuccessor(0) != BI->getSuccessor(1)) {
1451 bool isTrueDest = BI->getSuccessor(0) == BBTo;
1452 assert(BI->getSuccessor(!isTrueDest) == BBTo &&
1453 "BBTo isn't a successor of BBFrom");
1454 Value *Condition = BI->getCondition();
1459 if (Condition == Val)
1465 std::optional<ValueLatticeElement>
Result =
1466 getValueFromCondition(Val, Condition, isTrueDest, UseBlockValue);
1468 return std::nullopt;
1470 if (!
Result->isOverdefined())
1473 if (
User *Usr = dyn_cast<User>(Val)) {
1474 assert(
Result->isOverdefined() &&
"Result isn't overdefined");
1488 APInt ConditionVal(1, isTrueDest ? 1 : 0);
1498 for (
unsigned i = 0; i < Usr->getNumOperands(); ++i) {
1499 Value *
Op = Usr->getOperand(i);
1501 Op, Condition, isTrueDest,
false);
1502 if (std::optional<APInt> OpConst =
1511 if (!
Result->isOverdefined())
1519 Value *Condition =
SI->getCondition();
1520 if (!isa<IntegerType>(Val->
getType()))
1522 bool ValUsesConditionAndMayBeFoldable =
false;
1523 if (Condition != Val) {
1525 if (
User *Usr = dyn_cast<User>(Val))
1528 if (!ValUsesConditionAndMayBeFoldable)
1531 assert((Condition == Val || ValUsesConditionAndMayBeFoldable) &&
1532 "Condition != Val nor Val doesn't use Condition");
1534 bool DefaultCase =
SI->getDefaultDest() == BBTo;
1538 for (
auto Case :
SI->cases()) {
1539 APInt CaseValue = Case.getCaseValue()->getValue();
1541 if (ValUsesConditionAndMayBeFoldable) {
1542 User *Usr = cast<User>(Val);
1557 if (Case.getCaseSuccessor() != BBTo && Condition == Val)
1559 }
else if (Case.getCaseSuccessor() == BBTo)
1560 EdgesVals = EdgesVals.
unionWith(EdgeVal);
1569std::optional<ValueLatticeElement>
1573 if (
Constant *VC = dyn_cast<Constant>(Val))
1576 std::optional<ValueLatticeElement> LocalResult =
1577 getEdgeValueLocal(Val, BBFrom, BBTo,
true);
1579 return std::nullopt;
1585 std::optional<ValueLatticeElement> OptInBlock =
1588 return std::nullopt;
1599 intersectAssumeOrGuardBlockValueConstantRange(Val,
InBlock, CxtI);
1601 return LocalResult->intersect(
InBlock);
1606 LLVM_DEBUG(
dbgs() <<
"LVI Getting block end value " << *V <<
" at '"
1609 assert(BlockValueStack.empty() && BlockValueSet.empty());
1610 std::optional<ValueLatticeElement> OptResult = getBlockValue(V, BB, CxtI);
1613 OptResult = getBlockValue(V, BB, CxtI);
1614 assert(OptResult &&
"Value not available after solving");
1626 if (
auto *
C = dyn_cast<Constant>(V))
1630 if (
auto *
I = dyn_cast<Instruction>(V))
1632 intersectAssumeOrGuardBlockValueConstantRange(V, Result, CxtI);
1641 LLVM_DEBUG(
dbgs() <<
"LVI Getting edge value " << *V <<
" from '"
1645 std::optional<ValueLatticeElement> Result =
1646 getEdgeValue(V, FromBB, ToBB, CxtI);
1652 Result = getEdgeValue(V, FromBB, ToBB, CxtI);
1661 auto *CxtI = cast<Instruction>(U.getUser());
1666 const Use *CurrU = &U;
1668 const unsigned MaxUsesToInspect = 3;
1669 for (
unsigned I = 0;
I < MaxUsesToInspect; ++
I) {
1670 std::optional<ValueLatticeElement> CondVal;
1671 auto *CurrI = cast<Instruction>(CurrU->getUser());
1672 if (
auto *SI = dyn_cast<SelectInst>(CurrI)) {
1677 if (CurrU->getOperandNo() == 1)
1679 *getValueFromCondition(V, SI->getCondition(),
true,
1681 else if (CurrU->getOperandNo() == 2)
1683 *getValueFromCondition(V, SI->getCondition(),
false,
1685 }
else if (
auto *
PHI = dyn_cast<PHINode>(CurrI)) {
1687 CondVal = *getEdgeValueLocal(V,
PHI->getIncomingBlock(*CurrU),
1688 PHI->getParent(),
false);
1702 if (!CurrI->hasOneUse() ||
1712 TheCache.threadEdgeImpl(OldSucc, NewSucc);
1720 Info.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F);
1722 if (
auto *Impl = Info.getImpl())
1740 assert(M &&
"getCache() called with a null Module");
1759 if (
auto *Impl = getImpl()) {
1792 V = V->stripPointerCasts();
1794 if (isa<AllocaInst>(V))
1808 if (Result.isConstant())
1809 return Result.getConstant();
1810 if (Result.isConstantRange()) {
1813 return ConstantInt::get(V->getType(), *SingleVal);
1819 bool UndefAllowed) {
1823 return Result.asConstantRange(V->getType(), UndefAllowed);
1827 bool UndefAllowed) {
1828 auto *Inst = cast<Instruction>(U.getUser());
1831 return Result.asConstantRange(U->getType(), UndefAllowed);
1843 if (Result.isConstant())
1844 return Result.getConstant();
1845 if (Result.isConstantRange()) {
1848 return ConstantInt::get(V->getType(), *SingleVal);
1861 return Result.asConstantRange(V->getType(),
true);
1919 bool UseBlockValue) {
1926 if (V->getType()->isPointerTy() &&
C->isNullValue() &&
1935 auto &Impl = getOrCreateImpl(M);
1937 UseBlockValue ? Impl.getValueInBlock(V, CxtI->
getParent(), CxtI)
1938 : Impl.getValueAt(V, CxtI);
1977 if (
auto *
PHI = dyn_cast<PHINode>(V))
1978 if (
PHI->getParent() == BB) {
1980 for (
unsigned i = 0, e =
PHI->getNumIncomingValues(); i < e; i++) {
1989 Baseline = (i == 0) ? Result
1990 : (Baseline == Result ? Baseline
2002 if (!isa<Instruction>(V) || cast<Instruction>(V)->getParent() != BB) {
2009 while (++PI != PE) {
2011 if (Ret != Baseline)
2026 bool UseBlockValue) {
2027 if (
auto *
C = dyn_cast<Constant>(
RHS))
2029 if (
auto *
C = dyn_cast<Constant>(
LHS))
2036 if (UseBlockValue) {
2040 if (L.isOverdefined())
2046 return L.getCompare(Pred, Ty, R, M->getDataLayout());
2053 if (
auto *Impl = getImpl())
2054 Impl->threadEdge(PredBB, OldSucc, NewSucc);
2058 if (
auto *Impl = getImpl())
2059 Impl->forgetValue(V);
2063 if (
auto *Impl = getImpl())
2064 Impl->eraseBlock(BB);
2068 if (
auto *Impl = getImpl())
2073 if (
auto *Impl = getImpl())
2074 Impl->printLVI(
F, DTree,
OS);
2078void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
2082 for (
const auto &Arg :
F->args()) {
2085 if (Result.isUnknown())
2087 OS <<
"; LatticeVal for: '" << Arg <<
"' is: " << Result <<
"\n";
2095void LazyValueInfoAnnotatedWriter::emitInstructionAnnot(
2098 auto *ParentBB =
I->getParent();
2105 auto printResult = [&](
const BasicBlock *BB) {
2106 if (!BlocksContainingLVI.
insert(BB).second)
2110 OS <<
"; LatticeVal for: '" << *
I <<
"' in BB: '";
2115 printResult(ParentBB);
2118 for (
const auto *BBSucc :
successors(ParentBB))
2120 printResult(BBSucc);
2123 for (
const auto *U :
I->users())
2124 if (
auto *UseI = dyn_cast<Instruction>(U))
2125 if (!isa<PHINode>(UseI) || DT.
dominates(ParentBB, UseI->getParent()))
2126 printResult(UseI->getParent());
2132 OS <<
"LVI for function '" <<
F.getName() <<
"':\n";
2135 LVI.printLVI(
F, DTree,
OS);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
block Block Frequency Analysis
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Given that RA is a live value
This file defines the DenseSet and SmallDenseSet classes.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
static std::optional< ConstantRange > getRange(Value *V, const InstrInfoQuery &IIQ)
Helper method to get range from metadata or attribute.
static bool isOperationFoldable(User *Usr)
static void AddNonNullPointer(Value *Ptr, NonNullPointerSet &PtrSet, bool IsDereferenced=true)
static void AddNonNullPointersByInstruction(Instruction *I, NonNullPointerSet &PtrSet)
static std::optional< ConstantRange > getRangeViaSLT(CmpInst::Predicate Pred, APInt RHS, function_ref< std::optional< ConstantRange >(const APInt &)> Fn)
static const unsigned MaxProcessedPerValue
static ValueLatticeElement getValueFromICmpCtpop(ICmpInst::Predicate Pred, Value *RHS)
Get value range for a "ctpop(Val) Pred RHS" condition.
static bool usesOperand(User *Usr, Value *Op)
static ValueLatticeElement constantFoldUser(User *Usr, Value *Op, const APInt &OpConstVal, const DataLayout &DL)
static ValueLatticeElement getFromRangeMetadata(Instruction *BBI)
static Constant * getPredicateResult(CmpInst::Predicate Pred, Constant *C, const ValueLatticeElement &Val, const DataLayout &DL)
static ValueLatticeElement getValueFromOverflowCondition(Value *Val, WithOverflowInst *WO, bool IsTrueDest)
static bool isKnownNonConstant(Value *V)
Returns true if we can statically tell that this value will never be a "useful" constant.
static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val, ICmpInst::Predicate Pred)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool InBlock(const Value *V, const BasicBlock *BB)
Class for arbitrary precision integers.
APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
API to communicate dependencies between analyses during invalidation.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
This class represents an incoming formal argument to a Function.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
void clear()
Clear the cache of @llvm.assume intrinsics for a function.
MutableArrayRef< ResultElem > assumptionsFor(const Value *V)
Access the list of assumptions which affect this value.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
bool isEntryBlock() const
Return true if this is the entry block of the containing function.
const Function * getParent() const
Return the enclosing method, or null if none.
const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
const Instruction & back() const
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
unsigned getNoWrapKind() const
Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
BinaryOps getOpcode() const
Conditional or Unconditional Branch instruction.
Value handle with callbacks on RAUW and destruction.
This is the base class for all instructions that perform data casts.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Type * getDestTy() const
Return the destination type, as a convenience.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
This is the shared class of boolean and integer constants.
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getFalse(LLVMContext &Context)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This class represents a range of values.
ConstantRange subtract(const APInt &CI) const
Subtract the specified constant from the endpoints of this constant range.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
static ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned)
Initialize a range based on a known bits constraint.
ConstantRange castOp(Instruction::CastOps CastOp, uint32_t BitWidth) const
Return a new range representing the possible values resulting from an application of the specified ca...
ConstantRange umin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned minimum of a value in ...
APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
ConstantRange difference(const ConstantRange &CR) const
Subtract the specified range from this range (aka relative complement of the sets).
bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const
Does the predicate Pred hold between ranges this and Other? NOTE: false does not mean that inverse pr...
static ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
bool isEmptySet() const
Return true if this set contains no members.
ConstantRange abs(bool IntMinIsPoison=false) const
Calculate absolute value range.
static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID)
Returns true if ConstantRange calculations are supported for intrinsic with IntrinsicID.
ConstantRange overflowingBinaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind) const
Return a new range representing the possible values resulting from an application of the specified ov...
bool isSingleElement() const
Return true if this set contains exactly one member.
ConstantRange umax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an unsigned maximum of a value in ...
static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, const APInt &Other)
Produce the exact range such that all values in the returned range satisfy the given predicate with a...
ConstantRange inverse() const
Return a new range that is the logical not of the current set.
APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
static ConstantRange makeMaskNotEqualRange(const APInt &Mask, const APInt &C)
Initialize a range containing all values X that satisfy (X & Mask) != C.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
ConstantRange smin(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed minimum of a value in thi...
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
ConstantRange smax(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a signed maximum of a value in thi...
ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
static ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, const APInt &Other, unsigned NoWrapKind)
Produce the range that contains X if and only if "X BinOp Other" does not wrap.
This is an important base class in LLVM.
static Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
ConstantRange toConstantRange() const
Convert constant to an approximate constant range.
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive,...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
This instruction compares its operands according to the predicate given to the constructor.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
This instruction inserts a single (scalar) element into a VectorType value.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
Analysis to compute lazy value information.
Result run(Function &F, FunctionAnalysisManager &FAM)
ValueLatticeElement getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
This is the query interface to determine the lattice value for the specified Value* that is true on t...
ValueLatticeElement getValueAt(Value *V, Instruction *CxtI)
This is the query interface to determine the lattice value for the specified Value* at the specified ...
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc)
This is the update interface to inform the cache that an edge from PredBB to OldSucc has been threade...
void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS)
Printing the LazyValueInfo Analysis.
void forgetValue(Value *V)
This is part of the update interface to remove information related to this value from the cache.
void eraseBlock(BasicBlock *BB)
This is part of the update interface to inform the cache that a block has been deleted.
void clear()
Complete flush all previously computed values.
LazyValueInfoImpl(AssumptionCache *AC, const DataLayout &DL, Function *GuardDecl)
ValueLatticeElement getValueInBlock(Value *V, BasicBlock *BB, Instruction *CxtI=nullptr)
This is the query interface to determine the lattice value for the specified Value* at the context in...
ValueLatticeElement getValueAtUse(const Use &U)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Wrapper around LazyValueInfo.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
LazyValueInfoWrapperPass()
This pass computes, caches, and vends lazy value constraint information.
void eraseBlock(BasicBlock *BB)
Inform the analysis cache that we have erased a block.
ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the value at a specific use-site.
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc)
Inform the analysis cache that we have threaded an edge from PredBB to OldSucc to be from PredBB to N...
Constant * getPredicateOnEdge(CmpInst::Predicate Pred, Value *V, Constant *C, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
Determine whether the specified value comparison with a constant is known to be true or false on the ...
Constant * getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
Determine whether the specified value is known to be a constant on the specified edge.
ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI=nullptr)
Return the ConstantRage constraint that is known to hold for the specified value on the specified edg...
Constant * getConstant(Value *V, Instruction *CxtI)
Determine whether the specified value is known to be a constant at the specified instruction.
void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS)
Print the \LazyValueInfo Analysis.
void forgetValue(Value *V)
Remove information related to this value from the cache.
void clear()
Complete flush all previously computed values.
Constant * getPredicateAt(CmpInst::Predicate Pred, Value *V, Constant *C, Instruction *CxtI, bool UseBlockValue)
Determine whether the specified value comparison with a constant is known to be true or false at the ...
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle invalidation events in the new pass manager.
An instruction for reading from memory.
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
This class represents the LLVM 'select' instruction.
Implements a dense probed hash-table based set with some number of buckets stored inline.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class represents a truncation of integer types.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
static IntegerType * getInt1Ty(LLVMContext &C)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
This class represents lattice values for constants.
static ValueLatticeElement getRange(ConstantRange CR, bool MayIncludeUndef=false)
bool isOverdefined() const
static ValueLatticeElement getNot(Constant *C)
bool isNotConstant() const
std::optional< APInt > asConstantInteger() const
const ConstantRange & getConstantRange(bool UndefAllowed=true) const
Returns the constant range for this value.
bool isConstantRange(bool UndefAllowed=true) const
Returns true if this value is a constant range.
static ValueLatticeElement get(Constant *C)
Constant * getNotConstant() const
ValueLatticeElement intersect(const ValueLatticeElement &Other) const
Combine two sets of facts about the same value into a single set of facts.
Constant * getConstant() const
bool mergeIn(const ValueLatticeElement &RHS, MergeOptions Opts=MergeOptions())
Updates this object to approximate both this object and RHS.
static ValueLatticeElement getOverdefined()
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
Represents an op.with.overflow intrinsic.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find_as(const LookupKeyT &Val)
Alternative version of find() which allows a different, and possibly less expensive,...
bool erase(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)
This version supports overloaded intrinsics.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
PtrToIntSameSize_match< OpTy > m_PtrToIntSameSize(const DataLayout &DL, const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
match_combine_or< BinaryOp_match< LHS, RHS, Instruction::Add >, DisjointOr_match< LHS, RHS > > m_AddLike(const LHS &L, const RHS &R)
Match either "add" or "or disjoint".
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
This is an optimization pass for GlobalISel generic memory operations.
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
bool isSafeToSpeculativelyExecuteWithVariableReplaced(const Instruction *I)
Don't use information from its non-constant operands.
auto pred_end(const MachineBasicBlock *BB)
auto successors(const MachineBasicBlock *BB)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
bool isGuaranteedNotToBeUndef(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.
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
FunctionPass * createLazyValueInfoPass()
createLazyValueInfoPass - This creates an instance of the LazyValueInfo pass.
constexpr unsigned MaxAnalysisRecursionDepth
@ SPF_ABS
Floating point maxnum.
@ SPF_NABS
Absolute value.
@ SPF_UMIN
Signed minimum.
@ SPF_UMAX
Signed maximum.
@ SPF_SMAX
Unsigned minimum.
SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an ExtractValueInst, fold the result or return null.
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
static bool hasSingleValue(const ValueLatticeElement &Val)
constexpr unsigned BitWidth
auto pred_begin(const MachineBasicBlock *BB)
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void initializeLazyValueInfoWrapperPassPass(PassRegistry &)
A special type used by analysis passes to provide an address that identifies that particular analysis...
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?