43using namespace PatternMatch;
45#define DEBUG_TYPE "lazy-value-info"
56 "Lazy Value Information Analysis",
false,
true)
106 if (
A.isOverdefined())
108 if (
B.isOverdefined())
118 if (!
A.isConstantRange() || !
B.isConstantRange()) {
125 A.getConstantRange().intersectWith(
B.getConstantRange());
129 std::move(Range),
A.isConstantRangeIncludingUndef() ||
130 B.isConstantRangeIncludingUndef());
139 class LazyValueInfoCache;
140 struct LVIValueHandle final :
public CallbackVH {
141 LazyValueInfoCache *Parent;
143 LVIValueHandle(
Value *V, LazyValueInfoCache *
P =
nullptr)
146 void deleted()
override;
147 void allUsesReplacedWith(
Value *V)
override {
158 class LazyValueInfoCache {
163 struct BlockCacheEntry {
168 std::optional<NonNullPointerSet> NonNullPointers;
177 const BlockCacheEntry *getBlockEntry(
BasicBlock *BB)
const {
178 auto It = BlockCache.
find_as(BB);
179 if (It == BlockCache.
end())
181 return It->second.get();
184 BlockCacheEntry *getOrCreateBlockEntry(
BasicBlock *BB) {
185 auto It = BlockCache.
find_as(BB);
186 if (It == BlockCache.
end())
187 It = BlockCache.
insert({ BB, std::make_unique<BlockCacheEntry>() })
190 return It->second.get();
193 void addValueHandle(
Value *Val) {
194 auto HandleIt = ValueHandles.
find_as(Val);
195 if (HandleIt == ValueHandles.
end())
196 ValueHandles.
insert({ Val,
this });
202 BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
206 if (
Result.isOverdefined())
207 Entry->OverDefined.insert(Val);
209 Entry->LatticeElements.insert({ Val,
Result });
214 std::optional<ValueLatticeElement>
216 const BlockCacheEntry *Entry = getBlockEntry(BB);
220 if (Entry->OverDefined.count(V))
223 auto LatticeIt = Entry->LatticeElements.find_as(V);
224 if (LatticeIt == Entry->LatticeElements.end())
227 return LatticeIt->second;
230 bool isNonNullAtEndOfBlock(
233 BlockCacheEntry *Entry = getOrCreateBlockEntry(BB);
234 if (!Entry->NonNullPointers) {
235 Entry->NonNullPointers = InitFn(BB);
236 for (
Value *V : *Entry->NonNullPointers)
240 return Entry->NonNullPointers->count(V);
246 ValueHandles.
clear();
250 void eraseValue(
Value *V);
263void LazyValueInfoCache::eraseValue(
Value *V) {
264 for (
auto &Pair : BlockCache) {
265 Pair.second->LatticeElements.erase(V);
266 Pair.second->OverDefined.erase(V);
267 if (Pair.second->NonNullPointers)
268 Pair.second->NonNullPointers->erase(V);
271 auto HandleIt = ValueHandles.
find_as(V);
272 if (HandleIt != ValueHandles.
end())
273 ValueHandles.
erase(HandleIt);
276void LVIValueHandle::deleted() {
279 Parent->eraseValue(*
this);
282void LazyValueInfoCache::eraseBlock(
BasicBlock *BB) {
283 BlockCache.erase(BB);
286void LazyValueInfoCache::threadEdgeImpl(
BasicBlock *OldSucc,
298 std::vector<BasicBlock*> worklist;
299 worklist.push_back(OldSucc);
301 const BlockCacheEntry *Entry = getBlockEntry(OldSucc);
302 if (!Entry || Entry->OverDefined.empty())
305 Entry->OverDefined.end());
311 while (!worklist.empty()) {
316 if (ToUpdate == NewSucc)
continue;
319 auto OI = BlockCache.find_as(ToUpdate);
320 if (OI == BlockCache.end() || OI->second->OverDefined.empty())
322 auto &ValueSet = OI->second->OverDefined;
324 bool changed =
false;
325 for (
Value *V : ValsToClear) {
326 if (!ValueSet.erase(V))
334 if (!changed)
continue;
352 : LVIImpl(
L), DT(DTree) {}
354 void emitBasicBlockStartAnnot(
const BasicBlock *BB,
367 LazyValueInfoCache TheCache;
379 bool pushBlockValue(
const std::pair<BasicBlock *, Value *> &BV) {
380 if (!BlockValueSet.
insert(BV).second)
384 << BV.first->getName() <<
"\n");
396 std::optional<ValueLatticeElement> getBlockValue(
Value *Val,
BasicBlock *BB,
406 std::optional<ValueLatticeElement> solveBlockValueImpl(
Value *Val,
408 std::optional<ValueLatticeElement> solveBlockValueNonLocal(
Value *Val,
410 std::optional<ValueLatticeElement> solveBlockValuePHINode(
PHINode *PN,
412 std::optional<ValueLatticeElement> solveBlockValueSelect(
SelectInst *S,
416 std::optional<ValueLatticeElement> solveBlockValueBinaryOpImpl(
420 std::optional<ValueLatticeElement>
422 std::optional<ValueLatticeElement> solveBlockValueCast(
CastInst *CI,
424 std::optional<ValueLatticeElement>
426 std::optional<ValueLatticeElement> solveBlockValueIntrinsic(
IntrinsicInst *II,
428 std::optional<ValueLatticeElement>
431 void intersectAssumeOrGuardBlockValueConstantRange(
Value *Val,
463 LazyValueInfoAnnotatedWriter Writer(
this, DTree);
464 F.print(
OS, &Writer);
474 TheCache.eraseBlock(BB);
483 : AC(AC),
DL(
DL), GuardDecl(GuardDecl) {}
487void LazyValueInfoImpl::solve() {
489 BlockValueStack.begin(), BlockValueStack.end());
491 unsigned processedCount = 0;
492 while (!BlockValueStack.empty()) {
504 dbgs() <<
"Giving up on stack because we are getting too deep\n");
506 while (!StartingStack.empty()) {
507 std::pair<BasicBlock *, Value *> &
e = StartingStack.back();
508 TheCache.insertResult(
e.second,
e.first,
510 StartingStack.pop_back();
512 BlockValueSet.clear();
513 BlockValueStack.clear();
516 std::pair<BasicBlock *, Value *>
e = BlockValueStack.back();
517 assert(BlockValueSet.count(e) &&
"Stack value should be in BlockValueSet!");
519 if (solveBlockValue(
e.second,
e.first)) {
521 assert(BlockValueStack.back() == e &&
"Nothing should have been pushed!");
523 std::optional<ValueLatticeElement> BBLV =
524 TheCache.getCachedValueInfo(
e.second,
e.first);
525 assert(BBLV &&
"Result should be in cache!");
527 dbgs() <<
"POP " << *
e.second <<
" in " <<
e.first->getName() <<
" = "
531 BlockValueStack.pop_back();
532 BlockValueSet.erase(e);
535 assert(BlockValueStack.back() != e &&
"Stack should have been pushed!");
540std::optional<ValueLatticeElement>
544 if (
Constant *VC = dyn_cast<Constant>(Val))
547 if (std::optional<ValueLatticeElement> OptLatticeVal =
548 TheCache.getCachedValueInfo(Val, BB)) {
549 intersectAssumeOrGuardBlockValueConstantRange(Val, *OptLatticeVal, CxtI);
550 return OptLatticeVal;
554 if (!pushBlockValue({ BB, Val }))
564 case Instruction::Load:
565 case Instruction::Call:
566 case Instruction::Invoke:
568 if (isa<IntegerType>(BBI->
getType())) {
579 assert(!isa<Constant>(Val) &&
"Value should not be constant");
580 assert(!TheCache.getCachedValueInfo(Val, BB) &&
581 "Value should not be in cache");
585 std::optional<ValueLatticeElement> Res = solveBlockValueImpl(Val, BB);
590 TheCache.insertResult(Val, BB, *Res);
594std::optional<ValueLatticeElement>
598 return solveBlockValueNonLocal(Val, BB);
600 if (
PHINode *PN = dyn_cast<PHINode>(BBI))
601 return solveBlockValuePHINode(PN, BB);
603 if (
auto *SI = dyn_cast<SelectInst>(BBI))
604 return solveBlockValueSelect(SI, BB);
620 if (
auto *CI = dyn_cast<CastInst>(BBI))
621 return solveBlockValueCast(CI, BB);
624 return solveBlockValueBinaryOp(BO, BB);
626 if (
auto *EVI = dyn_cast<ExtractValueInst>(BBI))
627 return solveBlockValueExtractValue(EVI, BB);
629 if (
auto *II = dyn_cast<IntrinsicInst>(BBI))
630 return solveBlockValueIntrinsic(II, BB);
634 <<
"' - unknown inst def found.\n");
640 if (
Ptr->getType()->getPointerAddressSpace() == 0)
646 if (
LoadInst *L = dyn_cast<LoadInst>(
I)) {
648 }
else if (
StoreInst *S = dyn_cast<StoreInst>(
I)) {
651 if (
MI->isVolatile())
return;
655 if (!Len || Len->isZero())
return;
663bool LazyValueInfoImpl::isNonNullAtEndOfBlock(
Value *Val,
BasicBlock *BB) {
669 return TheCache.isNonNullAtEndOfBlock(Val, BB, [](
BasicBlock *BB) {
670 NonNullPointerSet NonNullPointers;
673 return NonNullPointers;
677std::optional<ValueLatticeElement>
678LazyValueInfoImpl::solveBlockValueNonLocal(
Value *Val,
BasicBlock *BB) {
684 assert(isa<Argument>(Val) &&
"Unknown live-in to the entry block");
698 std::optional<ValueLatticeElement> EdgeResult = getEdgeValue(Val, Pred, BB);
703 Result.mergeIn(*EdgeResult);
707 if (
Result.isOverdefined()) {
709 <<
"' - overdefined because of pred '"
710 << Pred->getName() <<
"' (non local).\n");
720std::optional<ValueLatticeElement>
733 std::optional<ValueLatticeElement> EdgeResult =
734 getEdgeValue(PhiVal, PhiBB, BB, PN);
739 Result.mergeIn(*EdgeResult);
743 if (
Result.isOverdefined()) {
745 <<
"' - overdefined because of pred (local).\n");
752 assert(!
Result.isOverdefined() &&
"Possible PHI in entry block?");
757 bool isTrueDest =
true);
761void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
763 BBI = BBI ? BBI : dyn_cast<Instruction>(Val);
775 auto *
I = cast<CallInst>(AssumeVH);
783 if (GuardDecl && !GuardDecl->
use_empty() &&
798 isNonNullAtEndOfBlock(Val, BB))
807 return ConstantRange::getFull(
DL.getTypeSizeInBits(Ty));
810std::optional<ValueLatticeElement>
813 std::optional<ValueLatticeElement> OptTrueVal =
814 getBlockValue(
SI->getTrueValue(), BB, SI);
819 std::optional<ValueLatticeElement> OptFalseVal =
820 getBlockValue(
SI->getFalseValue(), BB, SI);
836 ((LHS ==
SI->getTrueValue() && RHS ==
SI->getFalseValue()) ||
837 (RHS ==
SI->getTrueValue() && LHS ==
SI->getFalseValue()))) {
843 return TrueCR.
smin(FalseCR);
845 return TrueCR.
umin(FalseCR);
847 return TrueCR.
smax(FalseCR);
849 return TrueCR.
umax(FalseCR);
853 ResultCR,
TrueVal.isConstantRangeIncludingUndef() ||
854 FalseVal.isConstantRangeIncludingUndef());
858 if (LHS ==
SI->getTrueValue())
860 TrueCR.
abs(),
TrueVal.isConstantRangeIncludingUndef());
861 if (LHS ==
SI->getFalseValue())
863 FalseCR.
abs(),
FalseVal.isConstantRangeIncludingUndef());
868 if (LHS ==
SI->getTrueValue())
871 if (LHS ==
SI->getFalseValue())
895std::optional<ConstantRange>
897 std::optional<ValueLatticeElement> OptVal = getBlockValue(V, BB, CxtI);
903std::optional<ValueLatticeElement>
914 case Instruction::Trunc:
915 case Instruction::SExt:
916 case Instruction::ZExt:
917 case Instruction::BitCast:
922 <<
"' - overdefined (unknown cast).\n");
929 std::optional<ConstantRange> LHSRes = getRangeFor(CI->
getOperand(0), CI, BB);
944std::optional<ValueLatticeElement>
945LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
953 std::optional<ConstantRange> LHSRes = getRangeFor(
I->getOperand(0),
I, BB);
954 std::optional<ConstantRange> RHSRes = getRangeFor(
I->getOperand(1),
I, BB);
955 if (!LHSRes || !RHSRes)
964std::optional<ValueLatticeElement>
967 "all operands to binary operators are sized");
968 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO)) {
969 unsigned NoWrapKind = 0;
970 if (OBO->hasNoUnsignedWrap())
972 if (OBO->hasNoSignedWrap())
975 return solveBlockValueBinaryOpImpl(
982 return solveBlockValueBinaryOpImpl(
988std::optional<ValueLatticeElement>
991 return solveBlockValueBinaryOpImpl(
997std::optional<ValueLatticeElement>
1002 <<
"' - unknown intrinsic.\n");
1008 std::optional<ConstantRange>
Range = getRangeFor(
Op, II, BB);
1010 return std::nullopt;
1019std::optional<ValueLatticeElement>
1024 return solveBlockValueOverflowIntrinsic(WO, BB);
1031 return getBlockValue(V, BB, EVI);
1034 <<
"' - overdefined (unknown extractvalue).\n");
1079 if (
auto *Ranges =
I->getMetadata(LLVMContext::MD_range))
1087static std::optional<ConstantRange>
1090 bool Invert =
false;
1097 if (
RHS.isMaxSignedValue())
1098 return std::nullopt;
1102 if (
auto CR = Fn(
RHS))
1103 return Invert ? CR->inverse() : CR;
1104 return std::nullopt;
1116 if (isa<Constant>(
RHS)) {
1120 else if (!isa<UndefValue>(
RHS))
1145 Known.
Zero = ~*
C & *Mask;
1146 Known.
One = *
C & *Mask;
1175 const APInt *ShAmtC;
1180 EdgePred, *
C, [&](
const APInt &
RHS) -> std::optional<ConstantRange> {
1182 if ((New.ashr(*ShAmtC)) !=
RHS)
1183 return std::nullopt;
1225 bool isTrueDest = CondVal.
getInt();
1230 if (
auto *EVI = dyn_cast<ExtractValueInst>(
Cond))
1239 auto NV = Visited.
find(NKey);
1240 if (NV == Visited.
end()) {
1242 return std::nullopt;
1263 if ((isTrueDest ^ IsAnd) && (LV != Visited.
end())) {
1265 if (V.isOverdefined())
1267 if (RV != Visited.
end()) {
1268 V.mergeIn(RV->second);
1273 if (LV == Visited.
end() || RV == Visited.
end()) {
1275 if (LV == Visited.
end())
1277 if (RV == Visited.
end())
1279 return std::nullopt;
1282 return intersect(LV->second, RV->second);
1302 bool isRevisit = !Iter.second;
1304 Val, CurrentCond, isRevisit, Visited, Worklist);
1306 Visited[CurrentCond] = *Result;
1309 }
while (!Worklist.
empty());
1311 auto Result = Visited.
find(CondKey);
1313 return Result->second;
1326 return isa<CastInst>(Usr) || isa<BinaryOperator>(Usr) || isa<FreezeInst>(Usr);
1334 const APInt &OpConstVal,
1339 if (
auto *CI = dyn_cast<CastInst>(Usr)) {
1341 if (
auto *
C = dyn_cast_or_null<ConstantInt>(
1346 }
else if (
auto *BO = dyn_cast<BinaryOperator>(Usr)) {
1349 assert((Op0Match || Op1Match) &&
1350 "Operand 0 nor Operand 1 isn't a match");
1353 if (
auto *
C = dyn_cast_or_null<ConstantInt>(
1357 }
else if (isa<FreezeInst>(Usr)) {
1358 assert(cast<FreezeInst>(Usr)->getOperand(0) ==
Op &&
"Operand 0 isn't Op");
1375 if (BI->isConditional() &&
1376 BI->getSuccessor(0) != BI->getSuccessor(1)) {
1377 bool isTrueDest = BI->getSuccessor(0) == BBTo;
1378 assert(BI->getSuccessor(!isTrueDest) == BBTo &&
1379 "BBTo isn't a successor of BBFrom");
1380 Value *Condition = BI->getCondition();
1384 if (Condition == Val)
1392 if (!Result.isOverdefined())
1395 if (
User *Usr = dyn_cast<User>(Val)) {
1396 assert(Result.isOverdefined() &&
"Result isn't overdefined");
1410 APInt ConditionVal(1, isTrueDest ? 1 : 0);
1420 for (
unsigned i = 0; i < Usr->getNumOperands(); ++i) {
1421 Value *
Op = Usr->getOperand(i);
1424 if (std::optional<APInt> OpConst =
1433 if (!Result.isOverdefined())
1441 Value *Condition = SI->getCondition();
1442 if (!isa<IntegerType>(Val->
getType()))
1443 return std::nullopt;
1444 bool ValUsesConditionAndMayBeFoldable =
false;
1445 if (Condition != Val) {
1447 if (
User *Usr = dyn_cast<User>(Val))
1450 if (!ValUsesConditionAndMayBeFoldable)
1451 return std::nullopt;
1453 assert((Condition == Val || ValUsesConditionAndMayBeFoldable) &&
1454 "Condition != Val nor Val doesn't use Condition");
1456 bool DefaultCase = SI->getDefaultDest() == BBTo;
1460 for (
auto Case : SI->cases()) {
1461 APInt CaseValue = Case.getCaseValue()->getValue();
1463 if (ValUsesConditionAndMayBeFoldable) {
1464 User *Usr = cast<User>(Val);
1469 return std::nullopt;
1479 if (Case.getCaseSuccessor() != BBTo && Condition == Val)
1481 }
else if (Case.getCaseSuccessor() == BBTo)
1482 EdgesVals = EdgesVals.
unionWith(EdgeVal);
1486 return std::nullopt;
1491std::optional<ValueLatticeElement>
1495 if (
Constant *VC = dyn_cast<Constant>(Val))
1505 std::optional<ValueLatticeElement> OptInBlock =
1508 return std::nullopt;
1519 intersectAssumeOrGuardBlockValueConstantRange(Val,
InBlock, CxtI);
1526 LLVM_DEBUG(
dbgs() <<
"LVI Getting block end value " << *V <<
" at '"
1529 assert(BlockValueStack.empty() && BlockValueSet.empty());
1530 std::optional<ValueLatticeElement> OptResult = getBlockValue(V, BB, CxtI);
1533 OptResult = getBlockValue(V, BB, CxtI);
1534 assert(OptResult &&
"Value not available after solving");
1546 if (
auto *
C = dyn_cast<Constant>(V))
1550 if (
auto *
I = dyn_cast<Instruction>(V))
1552 intersectAssumeOrGuardBlockValueConstantRange(V, Result, CxtI);
1561 LLVM_DEBUG(
dbgs() <<
"LVI Getting edge value " << *V <<
" from '"
1565 std::optional<ValueLatticeElement> Result =
1566 getEdgeValue(V, FromBB, ToBB, CxtI);
1569 Result = getEdgeValue(V, FromBB, ToBB, CxtI);
1570 assert(Result &&
"More work to do after problem solved?");
1579 TheCache.threadEdgeImpl(OldSucc, NewSucc);
1587 Info.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F);
1588 Info.TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1590 if (
auto *Impl = Info.getImpl())
1608 assert(M &&
"getCache() called with a null Module");
1627 if (
auto *Impl = getImpl()) {
1651 return LazyValueInfo(&AC, &
F.getParent()->getDataLayout(), &TLI);
1661 V = V->stripPointerCasts();
1663 if (isa<AllocaInst>(V))
1677 if (Result.isConstant())
1678 return Result.getConstant();
1679 if (Result.isConstantRange()) {
1688 bool UndefAllowed) {
1689 assert(V->getType()->isIntegerTy());
1690 unsigned Width = V->getType()->getIntegerBitWidth();
1694 if (Result.isUnknown())
1695 return ConstantRange::getEmpty(Width);
1696 if (Result.isConstantRange(UndefAllowed))
1697 return Result.getConstantRange(UndefAllowed);
1700 assert(!(Result.isConstant() && isa<ConstantInt>(Result.getConstant())) &&
1701 "ConstantInt value must be represented as constantrange");
1702 return ConstantRange::getFull(Width);
1706 bool UndefAllowed) {
1713 const Use *CurrU = &U;
1715 const unsigned MaxUsesToInspect = 3;
1716 for (
unsigned I = 0;
I < MaxUsesToInspect; ++
I) {
1717 std::optional<ValueLatticeElement> CondVal;
1718 auto *CurrI = cast<Instruction>(CurrU->getUser());
1719 if (
auto *SI = dyn_cast<SelectInst>(CurrI)) {
1724 if (CurrU->getOperandNo() == 1)
1726 else if (CurrU->getOperandNo() == 2)
1728 }
else if (
auto *
PHI = dyn_cast<PHINode>(CurrI)) {
1733 if (CondVal && CondVal->isConstantRange())
1761 if (Result.isConstant())
1762 return Result.getConstant();
1763 if (Result.isConstantRange()) {
1775 unsigned Width = V->getType()->getIntegerBitWidth();
1780 if (Result.isUnknown())
1781 return ConstantRange::getEmpty(Width);
1782 if (Result.isConstantRange())
1783 return Result.getConstantRange();
1786 assert(!(Result.isConstant() && isa<ConstantInt>(Result.getConstant())) &&
1787 "ConstantInt value must be represented as constantrange");
1788 return ConstantRange::getFull(Width);
1798 if (
ConstantInt *ResCI = dyn_cast_or_null<ConstantInt>(Res))
1878 if (V->getType()->isPointerTy() &&
C->isNullValue() &&
1886 auto &Impl = getOrCreateImpl(M);
1888 UseBlockValue ? Impl.getValueInBlock(V, CxtI->
getParent(), CxtI)
1889 : Impl.getValueAt(V, CxtI);
1928 if (
auto *
PHI = dyn_cast<PHINode>(V))
1929 if (
PHI->getParent() == BB) {
1931 for (
unsigned i = 0, e =
PHI->getNumIncomingValues(); i < e; i++) {
1932 Value *Incoming =
PHI->getIncomingValue(i);
1940 Baseline = (i == 0) ? Result
1941 : (Baseline == Result ? Baseline
1953 if (!isa<Instruction>(V) || cast<Instruction>(V)->getParent() != BB) {
1960 while (++PI != PE) {
1962 if (Ret != Baseline)
1978 bool UseBlockValue) {
1981 if (
auto *
C = dyn_cast<Constant>(
RHS))
1983 if (
auto *
C = dyn_cast<Constant>(
LHS))
1990 if (UseBlockValue) {
1994 if (L.isOverdefined())
2001 M->getDataLayout())) {
2002 if (Res->isNullValue())
2004 if (Res->isOneValue())
2013 if (
auto *Impl = getImpl())
2014 Impl->threadEdge(PredBB, OldSucc, NewSucc);
2018 if (
auto *Impl = getImpl())
2019 Impl->forgetValue(V);
2023 if (
auto *Impl = getImpl())
2024 Impl->eraseBlock(BB);
2028 if (
auto *Impl = getImpl())
2033 if (
auto *Impl = getImpl())
2034 Impl->printLVI(
F, DTree,
OS);
2038void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
2042 for (
const auto &Arg :
F->args()) {
2045 if (Result.isUnknown())
2047 OS <<
"; LatticeVal for: '" << Arg <<
"' is: " << Result <<
"\n";
2055void LazyValueInfoAnnotatedWriter::emitInstructionAnnot(
2058 auto *ParentBB =
I->getParent();
2065 auto printResult = [&](
const BasicBlock *BB) {
2066 if (!BlocksContainingLVI.
insert(BB).second)
2070 OS <<
"; LatticeVal for: '" << *
I <<
"' in BB: '";
2075 printResult(ParentBB);
2078 for (
const auto *BBSucc :
successors(ParentBB))
2079 if (DT.dominates(ParentBB, BBSucc))
2080 printResult(BBSucc);
2083 for (
const auto *U :
I->users())
2084 if (
auto *UseI = dyn_cast<Instruction>(U))
2085 if (!isa<PHINode>(UseI) || DT.dominates(ParentBB, UseI->getParent()))
2086 printResult(UseI->getParent());
2092 OS <<
"LVI for function '" <<
F.getName() <<
"':\n";
2095 LVI.printLVI(
F, DTree,
OS);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
block Block Frequency Analysis
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void clear(coro::Shape &Shape)
Given that RA is a live value
This file defines the DenseSet and SmallDenseSet classes.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
static bool isOperationFoldable(User *Usr)
static ValueLatticeElement getValueFromSimpleICmpCondition(CmpInst::Predicate Pred, Value *RHS, const APInt &Offset)
Get value range for a "(Val + Offset) Pred RHS" condition.
static ValueLatticeElement getValueFromCondition(Value *Val, Value *Cond, bool isTrueDest=true)
static std::optional< ValueLatticeElement > getValueFromConditionImpl(Value *Val, CondValue CondVal, bool isRevisit, SmallDenseMap< CondValue, ValueLatticeElement > &Visited, SmallVectorImpl< CondValue > &Worklist)
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 bool hasSingleValue(const ValueLatticeElement &Val)
Returns true if this lattice value represents at most one possible value.
static const unsigned MaxProcessedPerValue
static std::optional< ValueLatticeElement > getEdgeValueLocal(Value *Val, BasicBlock *BBFrom, BasicBlock *BBTo)
Compute the value of Val on the edge BBFrom -> BBTo.
static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI, bool isTrueDest)
static bool usesOperand(User *Usr, Value *Op)
static ValueLatticeElement constantFoldUser(User *Usr, Value *Op, const APInt &OpConstVal, const DataLayout &DL)
static void AddNonNullPointer(Value *Ptr, NonNullPointerSet &PtrSet)
static ValueLatticeElement getFromRangeMetadata(Instruction *BBI)
static ValueLatticeElement intersect(const ValueLatticeElement &A, const ValueLatticeElement &B)
Combine two sets of facts about the same value into a single set of facts.
static ConstantRange getConstantRangeOrFull(const ValueLatticeElement &Val, Type *Ty, const DataLayout &DL)
static ValueLatticeElement getValueFromOverflowCondition(Value *Val, WithOverflowInst *WO, bool IsTrueDest)
static LazyValueInfo::Tristate getPredicateResult(unsigned Pred, Constant *C, const ValueLatticeElement &Val, const DataLayout &DL, TargetLibraryInfo *TLI)
static bool isKnownNonConstant(Value *V)
Returns true if we can statically tell that this value will never be a "useful" constant.
PointerIntPair< Value *, 1, bool > CondValue
static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val, ICmpInst::Predicate Pred)
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.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
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.
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 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.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
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 Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
const APInt & getValue() const
Return the constant as an APInt value reference.
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).
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.
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
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 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...
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(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
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.
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.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
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.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
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...
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.
ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed=true)
Return the ConstantRange constraint that is known to hold for the value at a specific use-site.
void eraseBlock(BasicBlock *BB)
Inform the analysis cache that we have erased a block.
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...
Tristate
This is used to return true/false/dunno results.
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...
Tristate getPredicateOnEdge(unsigned 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 ...
Tristate getPredicateAt(unsigned 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 ...
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.
bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle invalidation events in the new pass manager.
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed=true)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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...
PointerIntPair - This class implements a pair of a pointer and small integer.
PointerTy getPointer() const
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
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
Constant * getConstant() const
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.
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.
@ C
The default llvm calling convention, compatible with C.
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
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.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
CastOperator_match< OpTy, Instruction::Trunc > m_Trunc(const OpTy &Op)
Matches Trunc.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
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.
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 isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to be non-zero when defined.
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 and pointer casts from the specified value,...
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.
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.
Interval::pred_iterator pred_end(Interval *I)
@ 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.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Value * simplifyExtractValueInst(Value *Agg, ArrayRef< unsigned > Idxs, const SimplifyQuery &Q)
Given operands for an ExtractValueInst, fold the result or return null.
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
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
constexpr unsigned BitWidth
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void initializeLazyValueInfoWrapperPassPass(PassRegistry &)
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
A special type used by analysis passes to provide an address that identifies that particular analysis...
SelectPatternFlavor Flavor
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?