44using namespace PatternMatch;
46#define DEBUG_TYPE "lazy-value-info"
57 "Lazy Value Information Analysis",
false,
true)
109 if (
A.isOverdefined())
111 if (
B.isOverdefined())
121 if (!
A.isConstantRange() || !
B.isConstantRange()) {
128 A.getConstantRange().intersectWith(
B.getConstantRange());
132 std::move(
Range),
A.isConstantRangeIncludingUndef() ||
133 B.isConstantRangeIncludingUndef());
142 class LazyValueInfoCache;
143 struct LVIValueHandle final :
public CallbackVH {
144 LazyValueInfoCache *Parent;
146 LVIValueHandle(
Value *V, LazyValueInfoCache *
P =
nullptr)
149 void deleted()
override;
150 void allUsesReplacedWith(
Value *V)
override {
161class LazyValueInfoCache {
166 struct BlockCacheEntry {
171 std::optional<NonNullPointerSet> NonNullPointers;
180 const BlockCacheEntry *getBlockEntry(
BasicBlock *BB)
const {
181 auto It = BlockCache.
find_as(BB);
182 if (It == BlockCache.
end())
184 return It->second.get();
187 BlockCacheEntry *getOrCreateBlockEntry(
BasicBlock *BB) {
188 auto It = BlockCache.
find_as(BB);
189 if (It == BlockCache.
end())
190 It = BlockCache.
insert({BB, std::make_unique<BlockCacheEntry>()}).first;
192 return It->second.get();
195 void addValueHandle(
Value *Val) {
196 auto HandleIt = ValueHandles.
find_as(Val);
197 if (HandleIt == ValueHandles.
end())
198 ValueHandles.
insert({Val,
this});
204 BlockCacheEntry *
Entry = getOrCreateBlockEntry(BB);
208 if (
Result.isOverdefined())
209 Entry->OverDefined.insert(Val);
216 std::optional<ValueLatticeElement> getCachedValueInfo(
Value *V,
218 const BlockCacheEntry *
Entry = getBlockEntry(BB);
222 if (
Entry->OverDefined.count(V))
225 auto LatticeIt =
Entry->LatticeElements.find_as(V);
226 if (LatticeIt ==
Entry->LatticeElements.end())
229 return LatticeIt->second;
235 BlockCacheEntry *
Entry = getOrCreateBlockEntry(BB);
236 if (!
Entry->NonNullPointers) {
237 Entry->NonNullPointers = InitFn(BB);
242 return Entry->NonNullPointers->count(V);
248 ValueHandles.
clear();
252 void eraseValue(
Value *V);
265void LazyValueInfoCache::eraseValue(
Value *V) {
266 for (
auto &Pair : BlockCache) {
267 Pair.second->LatticeElements.erase(V);
268 Pair.second->OverDefined.erase(V);
269 if (Pair.second->NonNullPointers)
270 Pair.second->NonNullPointers->erase(V);
273 auto HandleIt = ValueHandles.
find_as(V);
274 if (HandleIt != ValueHandles.
end())
275 ValueHandles.
erase(HandleIt);
278void LVIValueHandle::deleted() {
281 Parent->eraseValue(*
this);
284void LazyValueInfoCache::eraseBlock(
BasicBlock *BB) {
285 BlockCache.erase(BB);
288void LazyValueInfoCache::threadEdgeImpl(
BasicBlock *OldSucc,
300 std::vector<BasicBlock*> worklist;
301 worklist.push_back(OldSucc);
303 const BlockCacheEntry *
Entry = getBlockEntry(OldSucc);
304 if (!Entry ||
Entry->OverDefined.empty())
307 Entry->OverDefined.end());
313 while (!worklist.empty()) {
318 if (ToUpdate == NewSucc)
continue;
321 auto OI = BlockCache.find_as(ToUpdate);
322 if (OI == BlockCache.end() || OI->second->OverDefined.empty())
324 auto &ValueSet = OI->second->OverDefined;
326 bool changed =
false;
327 for (
Value *V : ValsToClear) {
328 if (!ValueSet.erase(V))
336 if (!changed)
continue;
354 : LVIImpl(
L), DT(DTree) {}
356 void emitBasicBlockStartAnnot(
const BasicBlock *BB,
369 LazyValueInfoCache TheCache;
381 bool pushBlockValue(
const std::pair<BasicBlock *, Value *> &BV) {
382 if (!BlockValueSet.
insert(BV).second)
386 << BV.first->getName() <<
"\n");
398 std::optional<ValueLatticeElement> getBlockValue(
Value *Val,
BasicBlock *BB,
408 std::optional<ValueLatticeElement> solveBlockValueImpl(
Value *Val,
410 std::optional<ValueLatticeElement> solveBlockValueNonLocal(
Value *Val,
412 std::optional<ValueLatticeElement> solveBlockValuePHINode(
PHINode *PN,
414 std::optional<ValueLatticeElement> solveBlockValueSelect(
SelectInst *S,
418 std::optional<ValueLatticeElement> solveBlockValueBinaryOpImpl(
422 std::optional<ValueLatticeElement>
424 std::optional<ValueLatticeElement> solveBlockValueCast(
CastInst *CI,
426 std::optional<ValueLatticeElement>
428 std::optional<ValueLatticeElement> solveBlockValueIntrinsic(
IntrinsicInst *
II,
430 std::optional<ValueLatticeElement>
433 void intersectAssumeOrGuardBlockValueConstantRange(
Value *Val,
443 std::optional<ValueLatticeElement>
448 std::optional<ValueLatticeElement>
449 getValueFromICmpCondition(
Value *Val,
ICmpInst *ICI,
bool isTrueDest,
452 std::optional<ValueLatticeElement>
454 bool UseBlockValue,
unsigned Depth = 0);
456 std::optional<ValueLatticeElement> getEdgeValueLocal(
Value *Val,
489 LazyValueInfoAnnotatedWriter Writer(
this, DTree);
490 F.print(
OS, &Writer);
500 TheCache.eraseBlock(BB);
509 : AC(AC),
DL(
DL), GuardDecl(GuardDecl) {}
513void LazyValueInfoImpl::solve() {
515 BlockValueStack.begin(), BlockValueStack.end());
517 unsigned processedCount = 0;
518 while (!BlockValueStack.empty()) {
530 dbgs() <<
"Giving up on stack because we are getting too deep\n");
532 while (!StartingStack.empty()) {
533 std::pair<BasicBlock *, Value *> &
e = StartingStack.back();
534 TheCache.insertResult(
e.second,
e.first,
536 StartingStack.pop_back();
538 BlockValueSet.clear();
539 BlockValueStack.clear();
542 std::pair<BasicBlock *, Value *>
e = BlockValueStack.back();
543 assert(BlockValueSet.count(e) &&
"Stack value should be in BlockValueSet!");
544 unsigned StackSize = BlockValueStack.size();
547 if (solveBlockValue(
e.second,
e.first)) {
549 assert(BlockValueStack.size() == StackSize &&
550 BlockValueStack.back() == e &&
"Nothing should have been pushed!");
552 std::optional<ValueLatticeElement> BBLV =
553 TheCache.getCachedValueInfo(
e.second,
e.first);
554 assert(BBLV &&
"Result should be in cache!");
556 dbgs() <<
"POP " << *
e.second <<
" in " <<
e.first->getName() <<
" = "
560 BlockValueStack.pop_back();
561 BlockValueSet.erase(e);
564 assert(BlockValueStack.size() == StackSize + 1 &&
565 "Exactly one element should have been pushed!");
570std::optional<ValueLatticeElement>
574 if (
Constant *VC = dyn_cast<Constant>(Val))
577 if (std::optional<ValueLatticeElement> OptLatticeVal =
578 TheCache.getCachedValueInfo(Val, BB)) {
579 intersectAssumeOrGuardBlockValueConstantRange(Val, *OptLatticeVal, CxtI);
580 return OptLatticeVal;
584 if (!pushBlockValue({ BB, Val }))
595 case Instruction::Call:
596 case Instruction::Invoke:
597 if (std::optional<ConstantRange>
Range = cast<CallBase>(BBI)->
getRange())
600 case Instruction::Load:
602 if (isa<IntegerType>(BBI->
getType())) {
613 assert(!isa<Constant>(Val) &&
"Value should not be constant");
614 assert(!TheCache.getCachedValueInfo(Val, BB) &&
615 "Value should not be in cache");
619 std::optional<ValueLatticeElement> Res = solveBlockValueImpl(Val, BB);
624 TheCache.insertResult(Val, BB, *Res);
628std::optional<ValueLatticeElement>
632 return solveBlockValueNonLocal(Val, BB);
634 if (
PHINode *PN = dyn_cast<PHINode>(BBI))
635 return solveBlockValuePHINode(PN, BB);
637 if (
auto *SI = dyn_cast<SelectInst>(BBI))
638 return solveBlockValueSelect(SI, BB);
654 if (
auto *CI = dyn_cast<CastInst>(BBI))
655 return solveBlockValueCast(CI, BB);
658 return solveBlockValueBinaryOp(BO, BB);
660 if (
auto *EVI = dyn_cast<ExtractValueInst>(BBI))
661 return solveBlockValueExtractValue(EVI, BB);
663 if (
auto *
II = dyn_cast<IntrinsicInst>(BBI))
664 return solveBlockValueIntrinsic(
II, BB);
668 <<
"' - unknown inst def found.\n");
674 if (
Ptr->getType()->getPointerAddressSpace() == 0)
680 if (
LoadInst *L = dyn_cast<LoadInst>(
I)) {
682 }
else if (
StoreInst *S = dyn_cast<StoreInst>(
I)) {
685 if (
MI->isVolatile())
return;
689 if (!Len || Len->isZero())
return;
697bool LazyValueInfoImpl::isNonNullAtEndOfBlock(
Value *Val,
BasicBlock *BB) {
703 return TheCache.isNonNullAtEndOfBlock(Val, BB, [](
BasicBlock *BB) {
704 NonNullPointerSet NonNullPointers;
707 return NonNullPointers;
711std::optional<ValueLatticeElement>
712LazyValueInfoImpl::solveBlockValueNonLocal(
Value *Val,
BasicBlock *BB) {
717 assert(isa<Argument>(Val) &&
"Unknown live-in to the entry block");
718 if (std::optional<ConstantRange>
Range = cast<Argument>(Val)->
getRange())
733 std::optional<ValueLatticeElement> EdgeResult = getEdgeValue(Val, Pred, BB);
738 Result.mergeIn(*EdgeResult);
742 if (
Result.isOverdefined()) {
744 <<
"' - overdefined because of pred '"
745 << Pred->getName() <<
"' (non local).\n");
755std::optional<ValueLatticeElement>
768 std::optional<ValueLatticeElement> EdgeResult =
769 getEdgeValue(PhiVal, PhiBB, BB, PN);
774 Result.mergeIn(*EdgeResult);
778 if (
Result.isOverdefined()) {
780 <<
"' - overdefined because of pred (local).\n");
787 assert(!
Result.isOverdefined() &&
"Possible PHI in entry block?");
793void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
795 BBI = BBI ? BBI : dyn_cast<Instruction>(Val);
807 auto *
I = cast<CallInst>(AssumeVH);
811 BBLV =
intersect(BBLV, *getValueFromCondition(Val,
I->getArgOperand(0),
817 if (GuardDecl && !GuardDecl->
use_empty() &&
824 *getValueFromCondition(Val,
Cond,
true,
834 isNonNullAtEndOfBlock(Val, BB))
840 Type *Ty,
bool UndefAllowed =
false) {
846 return ConstantRange::getEmpty(BW);
847 return ConstantRange::getFull(BW);
850std::optional<ValueLatticeElement>
853 std::optional<ValueLatticeElement> OptTrueVal =
854 getBlockValue(
SI->getTrueValue(), BB, SI);
859 std::optional<ValueLatticeElement> OptFalseVal =
860 getBlockValue(
SI->getFalseValue(), BB, SI);
874 ((LHS ==
SI->getTrueValue() && RHS ==
SI->getFalseValue()) ||
875 (RHS ==
SI->getTrueValue() && LHS ==
SI->getFalseValue()))) {
881 return TrueCR.
smin(FalseCR);
883 return TrueCR.
umin(FalseCR);
885 return TrueCR.
smax(FalseCR);
887 return TrueCR.
umax(FalseCR);
891 ResultCR,
TrueVal.isConstantRangeIncludingUndef() ||
892 FalseVal.isConstantRangeIncludingUndef());
896 if (LHS ==
SI->getTrueValue())
898 TrueCR.
abs(),
TrueVal.isConstantRangeIncludingUndef());
899 if (LHS ==
SI->getFalseValue())
901 FalseCR.
abs(),
FalseVal.isConstantRangeIncludingUndef());
906 if (LHS ==
SI->getTrueValue())
909 if (LHS ==
SI->getFalseValue())
937std::optional<ConstantRange>
939 std::optional<ValueLatticeElement> OptVal = getBlockValue(V, BB, CxtI);
945std::optional<ValueLatticeElement>
951 case Instruction::Trunc:
952 case Instruction::SExt:
953 case Instruction::ZExt:
958 <<
"' - overdefined (unknown cast).\n");
965 std::optional<ConstantRange> LHSRes = getRangeFor(CI->
getOperand(0), CI, BB);
980std::optional<ValueLatticeElement>
981LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
989 std::optional<ConstantRange> LHSRes = getRangeFor(
I->getOperand(0),
I, BB);
993 std::optional<ConstantRange> RHSRes = getRangeFor(
I->getOperand(1),
I, BB);
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;
1048 II->getIntrinsicID(), OpRanges)),
1052std::optional<ValueLatticeElement>
1057 return solveBlockValueOverflowIntrinsic(WO, BB);
1064 return getBlockValue(V, BB, EVI);
1067 <<
"' - overdefined (unknown extractvalue).\n");
1105std::optional<ValueLatticeElement>
1110 bool UseBlockValue) {
1113 if (
ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
1115 }
else if (UseBlockValue) {
1116 std::optional<ValueLatticeElement>
R =
1117 getBlockValue(RHS, CxtI->
getParent(), CxtI);
1119 return std::nullopt;
1128static std::optional<ConstantRange>
1131 bool Invert =
false;
1138 if (
RHS.isMaxSignedValue())
1139 return std::nullopt;
1143 if (
auto CR = Fn(
RHS))
1144 return Invert ? CR->inverse() : CR;
1145 return std::nullopt;
1148std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
1149 Value *Val,
ICmpInst *ICI,
bool isTrueDest,
bool UseBlockValue) {
1157 if (isa<Constant>(RHS)) {
1161 else if (!isa<UndefValue>(RHS))
1173 return getValueFromSimpleICmpCondition(EdgePred, RHS,
Offset, ICI,
1178 return getValueFromSimpleICmpCondition(SwappedPred, LHS,
Offset, ICI,
1215 const APInt *ShAmtC;
1220 EdgePred, *
C, [&](
const APInt &RHS) -> std::optional<ConstantRange> {
1222 if ((
New.ashr(*ShAmtC)) != RHS)
1223 return std::nullopt;
1256std::optional<ValueLatticeElement>
1258 bool IsTrueDest,
bool UseBlockValue,
1261 return getValueFromICmpCondition(Val, ICI, IsTrueDest, UseBlockValue);
1263 if (
auto *EVI = dyn_cast<ExtractValueInst>(
Cond))
1273 return getValueFromCondition(Val,
N, !IsTrueDest, UseBlockValue,
Depth);
1284 std::optional<ValueLatticeElement> LV =
1285 getValueFromCondition(Val, L, IsTrueDest, UseBlockValue,
Depth);
1287 return std::nullopt;
1288 std::optional<ValueLatticeElement> RV =
1289 getValueFromCondition(Val, R, IsTrueDest, UseBlockValue,
Depth);
1291 return std::nullopt;
1297 if (IsTrueDest ^ IsAnd) {
1315 return isa<CastInst>(Usr) || isa<BinaryOperator>(Usr) || isa<FreezeInst>(Usr);
1323 const APInt &OpConstVal,
1328 if (
auto *CI = dyn_cast<CastInst>(Usr)) {
1330 if (
auto *
C = dyn_cast_or_null<ConstantInt>(
1335 }
else if (
auto *BO = dyn_cast<BinaryOperator>(Usr)) {
1338 assert((Op0Match || Op1Match) &&
1339 "Operand 0 nor Operand 1 isn't a match");
1342 if (
auto *
C = dyn_cast_or_null<ConstantInt>(
1346 }
else if (isa<FreezeInst>(Usr)) {
1347 assert(cast<FreezeInst>(Usr)->getOperand(0) ==
Op &&
"Operand 0 isn't Op");
1354std::optional<ValueLatticeElement>
1362 if (BI->isConditional() &&
1363 BI->getSuccessor(0) != BI->getSuccessor(1)) {
1364 bool isTrueDest = BI->getSuccessor(0) == BBTo;
1365 assert(BI->getSuccessor(!isTrueDest) == BBTo &&
1366 "BBTo isn't a successor of BBFrom");
1367 Value *Condition = BI->getCondition();
1371 if (Condition == Val)
1377 std::optional<ValueLatticeElement>
Result =
1378 getValueFromCondition(Val, Condition, isTrueDest, UseBlockValue);
1380 return std::nullopt;
1382 if (!
Result->isOverdefined())
1385 if (
User *Usr = dyn_cast<User>(Val)) {
1386 assert(
Result->isOverdefined() &&
"Result isn't overdefined");
1400 APInt ConditionVal(1, isTrueDest ? 1 : 0);
1410 for (
unsigned i = 0; i < Usr->getNumOperands(); ++i) {
1411 Value *
Op = Usr->getOperand(i);
1413 Op, Condition, isTrueDest,
false);
1414 if (std::optional<APInt> OpConst =
1423 if (!
Result->isOverdefined())
1431 Value *Condition =
SI->getCondition();
1432 if (!isa<IntegerType>(Val->
getType()))
1434 bool ValUsesConditionAndMayBeFoldable =
false;
1435 if (Condition != Val) {
1437 if (
User *Usr = dyn_cast<User>(Val))
1440 if (!ValUsesConditionAndMayBeFoldable)
1443 assert((Condition == Val || ValUsesConditionAndMayBeFoldable) &&
1444 "Condition != Val nor Val doesn't use Condition");
1446 bool DefaultCase =
SI->getDefaultDest() == BBTo;
1450 for (
auto Case :
SI->cases()) {
1451 APInt CaseValue = Case.getCaseValue()->getValue();
1453 if (ValUsesConditionAndMayBeFoldable) {
1454 User *Usr = cast<User>(Val);
1469 if (Case.getCaseSuccessor() != BBTo && Condition == Val)
1471 }
else if (Case.getCaseSuccessor() == BBTo)
1472 EdgesVals = EdgesVals.
unionWith(EdgeVal);
1481std::optional<ValueLatticeElement>
1485 if (
Constant *VC = dyn_cast<Constant>(Val))
1488 std::optional<ValueLatticeElement> LocalResult =
1489 getEdgeValueLocal(Val, BBFrom, BBTo,
true);
1491 return std::nullopt;
1497 std::optional<ValueLatticeElement> OptInBlock =
1500 return std::nullopt;
1511 intersectAssumeOrGuardBlockValueConstantRange(Val,
InBlock, CxtI);
1518 LLVM_DEBUG(
dbgs() <<
"LVI Getting block end value " << *V <<
" at '"
1521 assert(BlockValueStack.empty() && BlockValueSet.empty());
1522 std::optional<ValueLatticeElement> OptResult = getBlockValue(V, BB, CxtI);
1525 OptResult = getBlockValue(V, BB, CxtI);
1526 assert(OptResult &&
"Value not available after solving");
1538 if (
auto *
C = dyn_cast<Constant>(V))
1542 if (
auto *
I = dyn_cast<Instruction>(V))
1544 intersectAssumeOrGuardBlockValueConstantRange(V, Result, CxtI);
1553 LLVM_DEBUG(
dbgs() <<
"LVI Getting edge value " << *V <<
" from '"
1557 std::optional<ValueLatticeElement> Result =
1558 getEdgeValue(V, FromBB, ToBB, CxtI);
1564 Result = getEdgeValue(V, FromBB, ToBB, CxtI);
1573 auto *CxtI = cast<Instruction>(U.getUser());
1578 const Use *CurrU = &U;
1580 const unsigned MaxUsesToInspect = 3;
1581 for (
unsigned I = 0;
I < MaxUsesToInspect; ++
I) {
1582 std::optional<ValueLatticeElement> CondVal;
1583 auto *CurrI = cast<Instruction>(CurrU->getUser());
1584 if (
auto *SI = dyn_cast<SelectInst>(CurrI)) {
1589 if (CurrU->getOperandNo() == 1)
1591 *getValueFromCondition(V, SI->getCondition(),
true,
1593 else if (CurrU->getOperandNo() == 2)
1595 *getValueFromCondition(V, SI->getCondition(),
false,
1597 }
else if (
auto *
PHI = dyn_cast<PHINode>(CurrI)) {
1599 CondVal = *getEdgeValueLocal(V,
PHI->getIncomingBlock(*CurrU),
1600 PHI->getParent(),
false);
1623 TheCache.threadEdgeImpl(OldSucc, NewSucc);
1631 Info.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F);
1633 if (
auto *Impl = Info.getImpl())
1651 assert(M &&
"getCache() called with a null Module");
1670 if (
auto *Impl = getImpl()) {
1703 V = V->stripPointerCasts();
1705 if (isa<AllocaInst>(V))
1719 if (Result.isConstant())
1720 return Result.getConstant();
1721 if (Result.isConstantRange()) {
1724 return ConstantInt::get(V->getContext(), *SingleVal);
1730 bool UndefAllowed) {
1731 assert(V->getType()->isIntegerTy());
1739 bool UndefAllowed) {
1740 auto *Inst = cast<Instruction>(U.getUser());
1755 if (Result.isConstant())
1756 return Result.getConstant();
1757 if (Result.isConstantRange()) {
1760 return ConstantInt::get(V->getContext(), *SingleVal);
1783 if (
ConstantInt *ResCI = dyn_cast_or_null<ConstantInt>(Res))
1861 if (V->getType()->isPointerTy() &&
C->isNullValue() &&
1869 auto &Impl = getOrCreateImpl(M);
1871 UseBlockValue ? Impl.getValueInBlock(V, CxtI->
getParent(), CxtI)
1872 : Impl.getValueAt(V, CxtI);
1911 if (
auto *
PHI = dyn_cast<PHINode>(V))
1912 if (
PHI->getParent() == BB) {
1914 for (
unsigned i = 0, e =
PHI->getNumIncomingValues(); i < e; i++) {
1923 Baseline = (i == 0) ? Result
1924 : (Baseline == Result ? Baseline
1936 if (!isa<Instruction>(V) || cast<Instruction>(V)->getParent() != BB) {
1943 while (++PI != PE) {
1945 if (Ret != Baseline)
1961 bool UseBlockValue) {
1964 if (
auto *
C = dyn_cast<Constant>(
RHS))
1966 if (
auto *
C = dyn_cast<Constant>(
LHS))
1973 if (UseBlockValue) {
1977 if (L.isOverdefined())
1984 M->getDataLayout())) {
1985 if (Res->isNullValue())
1987 if (Res->isOneValue())
1996 if (
auto *Impl = getImpl())
1997 Impl->threadEdge(PredBB, OldSucc, NewSucc);
2001 if (
auto *Impl = getImpl())
2002 Impl->forgetValue(V);
2006 if (
auto *Impl = getImpl())
2007 Impl->eraseBlock(BB);
2011 if (
auto *Impl = getImpl())
2016 if (
auto *Impl = getImpl())
2017 Impl->printLVI(
F, DTree,
OS);
2021void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
2025 for (
const auto &Arg :
F->args()) {
2028 if (Result.isUnknown())
2030 OS <<
"; LatticeVal for: '" << Arg <<
"' is: " << Result <<
"\n";
2038void LazyValueInfoAnnotatedWriter::emitInstructionAnnot(
2041 auto *ParentBB =
I->getParent();
2048 auto printResult = [&](
const BasicBlock *BB) {
2049 if (!BlocksContainingLVI.
insert(BB).second)
2053 OS <<
"; LatticeVal for: '" << *
I <<
"' in BB: '";
2058 printResult(ParentBB);
2061 for (
const auto *BBSucc :
successors(ParentBB))
2062 if (DT.dominates(ParentBB, BBSucc))
2063 printResult(BBSucc);
2066 for (
const auto *U :
I->users())
2067 if (
auto *UseI = dyn_cast<Instruction>(U))
2068 if (!isa<PHINode>(UseI) || DT.dominates(ParentBB, UseI->getParent()))
2069 printResult(UseI->getParent());
2075 OS <<
"LVI for function '" <<
F.getName() <<
"':\n";
2078 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 std::optional< ConstantRange > getRange(Value *V, const InstrInfoQuery &IIQ)
Helper method to get range from metadata or attribute.
static bool isOperationFoldable(User *Usr)
static ConstantRange toConstantRange(const ValueLatticeElement &Val, Type *Ty, bool UndefAllowed=false)
static LazyValueInfo::Tristate getPredicateResult(unsigned Pred, Constant *C, const ValueLatticeElement &Val, const DataLayout &DL)
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 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 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)
Module.h This file contains the declarations for the Module class.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
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.
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.
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.
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...
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.
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...
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...
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.
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.
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
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.
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.
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::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.
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.
pred_iterator pred_end(BasicBlock *BB)
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,...
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.
pred_iterator pred_begin(BasicBlock *BB)
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
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 &)
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?