33#define DEBUG_TYPE "sccp"
46 bool UndefAllowed =
true) {
73 return isa<LoadInst>(
I);
84 CallBase *CB = dyn_cast<CallBase>(V);
95 <<
" as a constant\n");
99 LLVM_DEBUG(
dbgs() <<
" Constant: " << *Const <<
" = " << *V <<
'\n');
102 V->replaceAllUsesWith(Const);
110 bool Changed =
false;
111 auto GetRange = [&Solver, &InsertedValues](
Value *
Op) {
112 if (
auto *Const = dyn_cast<ConstantInt>(
Op))
115 unsigned Bitwidth =
Op->getType()->getScalarSizeInBits();
116 return ConstantRange::getFull(Bitwidth);
122 if (isa<OverflowingBinaryOperator>(Inst)) {
132 if (NUWRange.contains(RangeA)) {
141 if (NSWRange.contains(RangeA)) {
146 }
else if (isa<ZExtInst>(Inst) && !Inst.
hasNonNeg()) {
148 if (Range.isAllNonNegative()) {
152 }
else if (
TruncInst *TI = dyn_cast<TruncInst>(&Inst)) {
153 if (TI->hasNoSignedWrap() && TI->hasNoUnsignedWrap())
157 uint64_t DestWidth = TI->getDestTy()->getScalarSizeInBits();
158 if (!TI->hasNoUnsignedWrap()) {
159 if (Range.getActiveBits() <= DestWidth) {
160 TI->setHasNoUnsignedWrap(
true);
164 if (!TI->hasNoSignedWrap()) {
165 if (Range.getMinSignedBits() <= DestWidth) {
166 TI->setHasNoSignedWrap(
true);
180 auto isNonNegative = [&Solver](
Value *V) {
183 if (
auto *
C = dyn_cast<Constant>(V)) {
184 auto *CInt = dyn_cast<ConstantInt>(
C);
185 return CInt && !CInt->isNegative();
188 return IV.isConstantRange(
false) &&
189 IV.getConstantRange().isAllNonNegative();
196 case Instruction::SExt: {
199 if (InsertedValues.
count(Op0) || !isNonNegative(Op0))
205 case Instruction::AShr: {
208 if (InsertedValues.
count(Op0) || !isNonNegative(Op0))
214 case Instruction::SDiv:
215 case Instruction::SRem: {
218 if (InsertedValues.
count(Op0) || InsertedValues.
count(Op1) ||
219 !isNonNegative(Op0) || !isNonNegative(Op1))
221 auto NewOpcode = Inst.
getOpcode() == Instruction::SDiv ? Instruction::UDiv
224 if (Inst.
getOpcode() == Instruction::SDiv)
233 assert(NewInst &&
"Expected replacement instruction");
235 InsertedValues.
insert(NewInst);
246 bool MadeChanges =
false;
248 if (Inst.getType()->isVoidTy())
252 Inst.eraseFromParent();
269 bool HasNonFeasibleEdges =
false;
272 FeasibleSuccessors.
insert(Succ);
274 HasNonFeasibleEdges =
true;
278 if (!HasNonFeasibleEdges)
283 assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
284 isa<IndirectBrInst>(TI)) &&
285 "Terminator must be a br, switch or indirectbr");
287 if (FeasibleSuccessors.
size() == 0) {
292 Succ->removePredecessor(BB);
293 if (SeenSuccs.
insert(Succ).second)
299 }
else if (FeasibleSuccessors.
size() == 1) {
303 bool HaveSeenOnlyFeasibleSuccessor =
false;
305 if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
308 HaveSeenOnlyFeasibleSuccessor =
true;
312 Succ->removePredecessor(BB);
319 }
else if (FeasibleSuccessors.
size() > 1) {
325 BasicBlock *DefaultDest = SI->getDefaultDest();
326 if (!FeasibleSuccessors.
contains(DefaultDest)) {
327 if (!NewUnreachableBB) {
335 SI->setDefaultDest(NewUnreachableBB);
340 for (
auto CI = SI->case_begin(); CI != SI->case_end();) {
341 if (FeasibleSuccessors.
contains(CI->getCaseSuccessor())) {
387 TrackedMultipleRetVals;
420 using Edge = std::pair<BasicBlock *, BasicBlock *>;
445 bool MayIncludeUndef =
false);
448 assert(!V->getType()->isStructTy() &&
"structs should use mergeInValue");
449 return markConstant(ValueState[V], V,
C);
474 assert(!V->getType()->isStructTy() &&
475 "non-structs should use markConstant");
476 return mergeInValue(ValueState[V], V, MergeWithV, Opts);
483 assert(!V->getType()->isStructTy() &&
"Should use getStructValueState");
491 if (
auto *
C = dyn_cast<Constant>(V))
502 assert(V->getType()->isStructTy() &&
"Should use getValueState");
503 assert(i < cast<StructType>(V->getType())->getNumElements() &&
504 "Invalid element #");
506 auto I = StructValueState.
insert(
513 if (
auto *
C = dyn_cast<Constant>(V)) {
514 Constant *Elt =
C->getAggregateElement(i);
532 while (!ToInvalidate.
empty()) {
538 if (!BBExecutable.count(Inst->
getParent()))
544 if (
auto *RetInst = dyn_cast<ReturnInst>(Inst)) {
545 Function *
F = RetInst->getParent()->getParent();
546 if (
auto It = TrackedRetVals.
find(
F); It != TrackedRetVals.
end()) {
549 }
else if (MRVFunctionsTracked.
count(
F)) {
550 auto *STy = cast<StructType>(
F->getReturnType());
551 for (
unsigned I = 0, E = STy->getNumElements();
I != E; ++
I)
555 }
else if (
auto *STy = dyn_cast<StructType>(Inst->
getType())) {
556 for (
unsigned I = 0, E = STy->getNumElements();
I != E; ++
I) {
557 if (
auto It = StructValueState.
find({Inst, I});
558 It != StructValueState.
end()) {
563 }
else if (
auto It = ValueState.
find(Inst); It != ValueState.
end()) {
571 for (
User *U : V->users())
572 if (
auto *UI = dyn_cast<Instruction>(U))
575 auto It = AdditionalUsers.
find(V);
576 if (It != AdditionalUsers.
end())
577 for (
User *U : It->second)
578 if (
auto *UI = dyn_cast<Instruction>(U))
596 if (BBExecutable.count(
I->getParent()))
601 void addAdditionalUser(
Value *V,
User *U) {
602 auto Iter = AdditionalUsers.
insert({V, {}});
603 Iter.first->second.insert(U);
607 void markUsersAsChanged(
Value *
I) {
612 if (isa<Function>(
I)) {
613 for (
User *U :
I->users()) {
614 if (
auto *CB = dyn_cast<CallBase>(U))
615 handleCallResult(*CB);
618 for (
User *U :
I->users())
619 if (
auto *UI = dyn_cast<Instruction>(U))
620 operandChangedState(UI);
623 auto Iter = AdditionalUsers.
find(
I);
624 if (Iter != AdditionalUsers.
end()) {
628 for (
User *U : Iter->second)
629 if (
auto *UI = dyn_cast<Instruction>(U))
632 operandChangedState(UI);
635 void handleCallOverdefined(
CallBase &CB);
636 void handleCallResult(
CallBase &CB);
637 void handleCallArguments(
CallBase &CB);
664 markOverdefined(&CPI);
665 visitTerminator(CPI);
681 visitTerminator(CBI);
696 FnPredicateInfo.
insert({&
F, std::make_unique<PredicateInfo>(
F, DT, AC)});
704 auto It = FnPredicateInfo.
find(
I->getParent()->getParent());
705 if (It == FnPredicateInfo.
end())
707 return It->second->getPredicateInfoFor(
I);
713 :
DL(
DL), GetTLI(GetTLI), Ctx(Ctx) {}
725 if (
auto *STy = dyn_cast<StructType>(
F->getReturnType())) {
727 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
728 TrackedMultipleRetVals.
insert(
730 }
else if (!
F->getReturnType()->isVoidTy())
735 MustPreserveReturnsInFunctions.
insert(
F);
739 return MustPreserveReturnsInFunctions.
count(
F);
743 TrackingIncomingArguments.
insert(
F);
747 return TrackingIncomingArguments.
count(
F);
757 return BBExecutable.count(BB);
763 std::vector<ValueLatticeElement> StructValues;
764 auto *STy = dyn_cast<StructType>(V->getType());
765 assert(STy &&
"getStructLatticeValueFor() can be called only on structs");
766 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
767 auto I = StructValueState.
find(std::make_pair(V, i));
768 assert(
I != StructValueState.
end() &&
"Value not in valuemap!");
769 StructValues.push_back(
I->second);
782 assert(!
F->getReturnType()->isVoidTy() &&
783 (TrackedRetVals.
count(
F) || MRVFunctionsTracked.
count(
F)) &&
784 "All non void specializations should be tracked");
786 handleCallResult(*Call);
790 assert(!V->getType()->isStructTy() &&
791 "Should use getStructLatticeValueFor");
795 "V not found in ValueState nor Paramstate map!");
800 return TrackedRetVals;
804 return TrackedGlobals;
808 return MRVFunctionsTracked;
812 if (
auto *STy = dyn_cast<StructType>(V->getType()))
813 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
814 markOverdefined(getStructValueState(V, i), V);
816 markOverdefined(ValueState[V], V);
820 if (
A->getType()->isIntegerTy()) {
821 if (std::optional<ConstantRange> Range =
A->getRange()) {
822 markConstantRange(ValueState[
A],
A, *Range);
837 return TrackingIncomingArguments;
845 BBExecutable.erase(&BB);
849 bool ResolvedUndefs =
true;
850 while (ResolvedUndefs) {
852 ResolvedUndefs =
false;
859 bool ResolvedUndefs =
true;
860 while (ResolvedUndefs) {
862 ResolvedUndefs =
false;
869 bool ResolvedUndefs =
true;
870 while (ResolvedUndefs) {
872 ResolvedUndefs =
false;
874 if (
auto *
I = dyn_cast<Instruction>(V))
884 if (!BBExecutable.insert(BB).second)
887 BBWorkList.push_back(BB);
892 if (
IV.isOverdefined()) {
893 if (OverdefinedInstWorkList.empty() || OverdefinedInstWorkList.back() != V)
894 OverdefinedInstWorkList.push_back(V);
897 if (InstWorkList.empty() || InstWorkList.back() != V)
898 InstWorkList.push_back(V);
903 pushToWorkList(
IV, V);
908 if (!
IV.markConstant(
C, MayIncludeUndef))
911 pushToWorkList(
IV, V);
917 if (!
IV.markConstantRange(CR))
919 LLVM_DEBUG(
dbgs() <<
"markConstantRange: " << CR <<
": " << *V <<
'\n');
920 pushToWorkList(
IV, V);
925 if (!
IV.markOverdefined())
929 if (
auto *
F = dyn_cast<Function>(V))
dbgs()
930 <<
"Function '" <<
F->getName() <<
"'\n";
931 else dbgs() << *V <<
'\n');
933 pushToWorkList(
IV, V);
939 const auto &It = TrackedMultipleRetVals.find(std::make_pair(
F, i));
940 assert(It != TrackedMultipleRetVals.end());
952 assert(
C->getType() == Ty &&
"Type mismatch");
966 if (V->getType()->isStructTy()) {
970 std::vector<Constant *> ConstVals;
971 auto *ST = cast<StructType>(V->getType());
972 for (
unsigned I = 0,
E = ST->getNumElements();
I !=
E; ++
I) {
986 assert(Const &&
"Constant is nullptr here!");
992 assert(!Args.empty() &&
"Specialization without arguments");
993 assert(
F->arg_size() == Args[0].Formal->getParent()->arg_size() &&
994 "Functions should have the same number of arguments");
996 auto Iter = Args.begin();
999 for (
auto End =
F->arg_end(); NewArg !=
End; ++NewArg, ++OldArg) {
1006 if (Iter != Args.end() && Iter->Formal == &*OldArg) {
1007 if (
auto *STy = dyn_cast<StructType>(NewArg->
getType())) {
1008 for (
unsigned I = 0,
E = STy->getNumElements();
I !=
E; ++
I) {
1010 NewValue.
markConstant(Iter->Actual->getAggregateElement(
I));
1013 ValueState[&*NewArg].markConstant(Iter->Actual);
1017 if (
auto *STy = dyn_cast<StructType>(NewArg->
getType())) {
1018 for (
unsigned I = 0,
E = STy->getNumElements();
I !=
E; ++
I) {
1020 NewValue = StructValueState[{&*OldArg,
I}];
1024 NewValue = ValueState[&*OldArg];
1030void SCCPInstVisitor::visitInstruction(
Instruction &
I) {
1033 LLVM_DEBUG(
dbgs() <<
"SCCP: Don't know how to handle: " <<
I <<
'\n');
1034 markOverdefined(&
I);
1040 if (
IV.mergeIn(MergeWithV, Opts)) {
1041 pushToWorkList(
IV, V);
1042 LLVM_DEBUG(
dbgs() <<
"Merged " << MergeWithV <<
" into " << *V <<
" : "
1050 if (!KnownFeasibleEdges.
insert(Edge(Source, Dest)).second)
1058 <<
" -> " << Dest->
getName() <<
'\n');
1068void SCCPInstVisitor::getFeasibleSuccessors(
Instruction &TI,
1071 if (
auto *BI = dyn_cast<BranchInst>(&TI)) {
1072 if (BI->isUnconditional()) {
1078 ConstantInt *CI = getConstantInt(BCValue, BI->getCondition()->getType());
1083 Succs[0] = Succs[1] =
true;
1088 Succs[CI->
isZero()] =
true;
1099 if (
auto *SI = dyn_cast<SwitchInst>(&TI)) {
1100 if (!
SI->getNumCases()) {
1106 getConstantInt(SCValue,
SI->getCondition()->getType())) {
1107 Succs[
SI->findCaseValue(CI)->getSuccessorIndex()] =
true;
1115 unsigned ReachableCaseCount = 0;
1116 for (
const auto &Case :
SI->cases()) {
1117 const APInt &CaseValue = Case.getCaseValue()->getValue();
1118 if (
Range.contains(CaseValue)) {
1119 Succs[Case.getSuccessorIndex()] =
true;
1120 ++ReachableCaseCount;
1124 Succs[
SI->case_default()->getSuccessorIndex()] =
1125 Range.isSizeLargerThan(ReachableCaseCount);
1137 if (
auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
1141 getConstant(IBRValue, IBR->getAddress()->getType()));
1151 "Block address of a different function ?");
1152 for (
unsigned i = 0; i < IBR->getNumSuccessors(); ++i) {
1154 if (IBR->getDestination(i) ==
T) {
1165 LLVM_DEBUG(
dbgs() <<
"Unknown terminator instruction: " << TI <<
'\n');
1175 return KnownFeasibleEdges.
count(Edge(
From, To));
1195void SCCPInstVisitor::visitPHINode(
PHINode &PN) {
1199 return (
void)markOverdefined(&PN);
1201 if (getValueState(&PN).isOverdefined())
1207 return (
void)markOverdefined(&PN);
1209 unsigned NumActiveIncoming = 0;
1223 NumActiveIncoming++;
1233 mergeInValue(&PN, PhiState,
1235 NumActiveIncoming + 1));
1241void SCCPInstVisitor::visitReturnInst(
ReturnInst &
I) {
1242 if (
I.getNumOperands() == 0)
1246 Value *ResultOp =
I.getOperand(0);
1250 auto TFRVI = TrackedRetVals.find(
F);
1251 if (TFRVI != TrackedRetVals.end()) {
1252 mergeInValue(TFRVI->second,
F, getValueState(ResultOp));
1258 if (!TrackedMultipleRetVals.empty()) {
1259 if (
auto *STy = dyn_cast<StructType>(ResultOp->
getType()))
1260 if (MRVFunctionsTracked.count(
F))
1261 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1262 mergeInValue(TrackedMultipleRetVals[std::make_pair(
F, i)],
F,
1263 getStructValueState(ResultOp, i));
1267void SCCPInstVisitor::visitTerminator(
Instruction &TI) {
1269 getFeasibleSuccessors(TI, SuccFeasible);
1274 for (
unsigned i = 0, e = SuccFeasible.
size(); i != e; ++i)
1275 if (SuccFeasible[i])
1279void SCCPInstVisitor::visitCastInst(
CastInst &
I) {
1282 if (ValueState[&
I].isOverdefined())
1293 return (
void)markConstant(&
I,
C);
1296 if (
I.getDestTy()->isIntegerTy() &&
I.getSrcTy()->isIntOrIntVectorTy()) {
1297 auto &LV = getValueState(&
I);
1300 Type *DestTy =
I.getDestTy();
1306 if (
I.getOpcode() == Instruction::BitCast &&
1307 I.getOperand(0)->getType()->isVectorTy() &&
1309 return (
void)markOverdefined(&
I);
1312 OpRange.
castOp(
I.getOpcode(),
DL.getTypeSizeInBits(DestTy));
1315 markOverdefined(&
I);
1324 addAdditionalUser(
LHS, &EVI);
1325 addAdditionalUser(
RHS, &EVI);
1326 if (
L.isUnknownOrUndef() ||
R.isUnknownOrUndef())
1336 assert(
Idx == 1 &&
"Index can only be 0 or 1");
1341 markOverdefined(&EVI);
1349 return (
void)markOverdefined(&EVI);
1353 if (ValueState[&EVI].isOverdefined())
1354 return (
void)markOverdefined(&EVI);
1358 return (
void)markOverdefined(&EVI);
1363 if (
auto *WO = dyn_cast<WithOverflowInst>(AggVal))
1364 return handleExtractOfWithOverflow(EVI, WO, i);
1366 mergeInValue(getValueState(&EVI), &EVI, EltVal);
1369 return (
void)markOverdefined(&EVI);
1374 auto *STy = dyn_cast<StructType>(IVI.
getType());
1376 return (
void)markOverdefined(&IVI);
1381 return (
void)markOverdefined(&IVI);
1385 if (IVI.getNumIndices() != 1)
1386 return (
void)markOverdefined(&IVI);
1388 Value *Aggr = IVI.getAggregateOperand();
1389 unsigned Idx = *IVI.idx_begin();
1392 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1396 mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
1400 Value *Val = IVI.getInsertedValueOperand();
1403 markOverdefined(getStructValueState(&IVI, i), &IVI);
1406 mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
1411void SCCPInstVisitor::visitSelectInst(
SelectInst &
I) {
1414 if (
I.getType()->isStructTy())
1415 return (
void)markOverdefined(&
I);
1419 if (ValueState[&
I].isOverdefined())
1420 return (
void)markOverdefined(&
I);
1427 getConstantInt(CondValue,
I.getCondition()->getType())) {
1428 Value *OpVal = CondCB->isZero() ?
I.getFalseValue() :
I.getTrueValue();
1429 mergeInValue(&
I, getValueState(OpVal));
1439 bool Changed = ValueState[&
I].mergeIn(TVal);
1440 Changed |= ValueState[&
I].mergeIn(FVal);
1442 pushToWorkListMsg(ValueState[&
I], &
I);
1446void SCCPInstVisitor::visitUnaryOperator(
Instruction &
I) {
1453 return (
void)markOverdefined(&
I);
1462 return (
void)markConstant(
IV, &
I,
C);
1464 markOverdefined(&
I);
1467void SCCPInstVisitor::visitFreezeInst(
FreezeInst &
I) {
1470 if (
I.getType()->isStructTy())
1471 return (
void)markOverdefined(&
I);
1478 return (
void)markOverdefined(&
I);
1488 markOverdefined(&
I);
1492void SCCPInstVisitor::visitBinaryOperator(
Instruction &
I) {
1497 if (
IV.isOverdefined())
1505 return (
void)markOverdefined(&
I);
1517 auto *
C = dyn_cast_or_null<Constant>(R);
1526 return (
void)mergeInValue(&
I, NewV);
1531 if (!
I.getType()->isIntegerTy())
1532 return markOverdefined(&
I);
1538 auto *BO = cast<BinaryOperator>(&
I);
1539 ConstantRange R = ConstantRange::getEmpty(
I.getType()->getScalarSizeInBits());
1540 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO))
1541 R =
A.overflowingBinaryOp(BO->getOpcode(),
B, OBO->getNoWrapKind());
1543 R =
A.binaryOp(BO->getOpcode(),
B);
1552void SCCPInstVisitor::visitCmpInst(
CmpInst &
I) {
1556 return (
void)markOverdefined(&
I);
1558 Value *Op1 =
I.getOperand(0);
1559 Value *Op2 =
I.getOperand(1);
1563 auto V1State = getValueState(Op1);
1564 auto V2State = getValueState(Op2);
1570 mergeInValue(&
I, CV);
1579 markOverdefined(&
I);
1586 return (
void)markOverdefined(&
I);
1591 for (
unsigned i = 0, e =
I.getNumOperands(); i != e; ++i) {
1597 return (
void)markOverdefined(&
I);
1604 return (
void)markOverdefined(&
I);
1608 markConstant(&
I,
C);
1611void SCCPInstVisitor::visitStoreInst(
StoreInst &SI) {
1613 if (
SI.getOperand(0)->getType()->isStructTy())
1616 if (TrackedGlobals.empty() || !isa<GlobalVariable>(
SI.getOperand(1)))
1620 auto I = TrackedGlobals.find(GV);
1621 if (
I == TrackedGlobals.end())
1625 mergeInValue(
I->second, GV, getValueState(
SI.getOperand(0)),
1627 if (
I->second.isOverdefined())
1628 TrackedGlobals.erase(
I);
1632 if (
I->getType()->isIntegerTy()) {
1633 if (
MDNode *Ranges =
I->getMetadata(LLVMContext::MD_range))
1637 if (
const auto *CB = dyn_cast<CallBase>(
I))
1638 if (std::optional<ConstantRange> Range = CB->getRange())
1641 if (
I->hasMetadata(LLVMContext::MD_nonnull))
1649void SCCPInstVisitor::visitLoadInst(
LoadInst &
I) {
1652 if (
I.getType()->isStructTy() ||
I.isVolatile())
1653 return (
void)markOverdefined(&
I);
1657 if (ValueState[&
I].isOverdefined())
1658 return (
void)markOverdefined(&
I);
1670 if (isa<ConstantPointerNull>(
Ptr)) {
1672 return (
void)markOverdefined(
IV, &
I);
1678 if (
auto *GV = dyn_cast<GlobalVariable>(
Ptr)) {
1679 if (!TrackedGlobals.empty()) {
1681 auto It = TrackedGlobals.find(GV);
1682 if (It != TrackedGlobals.end()) {
1691 return (
void)markConstant(
IV, &
I,
C);
1698void SCCPInstVisitor::visitCallBase(
CallBase &CB) {
1699 handleCallResult(CB);
1700 handleCallArguments(CB);
1703void SCCPInstVisitor::handleCallOverdefined(
CallBase &CB) {
1712 return (
void)markOverdefined(&CB);
1719 if (
A.get()->getType()->isStructTy())
1720 return markOverdefined(&CB);
1721 if (
A.get()->getType()->isMetadataTy())
1728 return (
void)markOverdefined(&CB);
1734 return (
void)markOverdefined(&CB);
1739 return (
void)markConstant(&CB,
C);
1746void SCCPInstVisitor::handleCallArguments(
CallBase &CB) {
1751 if (TrackingIncomingArguments.count(
F)) {
1760 if (AI->hasByValAttr() && !
F->onlyReadsMemory()) {
1761 markOverdefined(&*AI);
1765 if (
auto *STy = dyn_cast<StructType>(AI->getType())) {
1766 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1768 mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg,
1777void SCCPInstVisitor::handleCallResult(
CallBase &CB) {
1780 if (
auto *II = dyn_cast<IntrinsicInst>(&CB)) {
1781 if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
1782 if (ValueState[&CB].isOverdefined())
1788 assert(PI &&
"Missing predicate info for ssa.copy");
1790 const std::optional<PredicateConstraint> &Constraint =
1791 PI->getConstraint();
1793 mergeInValue(ValueState[&CB], &CB, CopyOfVal);
1798 Value *OtherOp = Constraint->OtherOp;
1801 if (getValueState(OtherOp).isUnknown()) {
1802 addAdditionalUser(OtherOp, &CB);
1810 ConstantRange::getFull(
DL.getTypeSizeInBits(CopyOf->
getType()));
1820 auto NewCR = ImposedCR.intersectWith(CopyOfCR);
1824 if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
1832 addAdditionalUser(OtherOp, &CB);
1841 addAdditionalUser(OtherOp, &CB);
1842 mergeInValue(
IV, &CB, CondVal);
1846 addAdditionalUser(OtherOp, &CB);
1847 mergeInValue(
IV, &CB,
1852 return (
void)mergeInValue(
IV, &CB, CopyOfVal);
1860 for (
Value *
Op : II->args()) {
1876 if (!
F ||
F->isDeclaration())
1877 return handleCallOverdefined(CB);
1880 if (
auto *STy = dyn_cast<StructType>(
F->getReturnType())) {
1881 if (!MRVFunctionsTracked.count(
F))
1882 return handleCallOverdefined(CB);
1886 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1887 mergeInValue(getStructValueState(&CB, i), &CB,
1888 TrackedMultipleRetVals[std::make_pair(
F, i)],
1891 auto TFRVI = TrackedRetVals.find(
F);
1892 if (TFRVI == TrackedRetVals.end())
1893 return handleCallOverdefined(CB);
1902 while (!BBWorkList.empty() || !InstWorkList.empty() ||
1903 !OverdefinedInstWorkList.empty()) {
1906 while (!OverdefinedInstWorkList.empty()) {
1907 Value *
I = OverdefinedInstWorkList.pop_back_val();
1919 markUsersAsChanged(
I);
1923 while (!InstWorkList.empty()) {
1924 Value *
I = InstWorkList.pop_back_val();
1936 if (
I->getType()->isStructTy() || !getValueState(
I).isOverdefined())
1937 markUsersAsChanged(
I);
1941 while (!BBWorkList.empty()) {
1955 if (
I.getType()->isVoidTy())
1958 if (
auto *STy = dyn_cast<StructType>(
I.getType())) {
1962 if (
auto *CB = dyn_cast<CallBase>(&
I))
1964 if (MRVFunctionsTracked.count(
F))
1969 if (isa<ExtractValueInst>(
I) || isa<InsertValueInst>(
I))
1973 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1976 markOverdefined(LV, &
I);
1992 if (
auto *CB = dyn_cast<CallBase>(&
I))
1994 if (TrackedRetVals.count(
F))
1997 if (isa<LoadInst>(
I)) {
2004 markOverdefined(&
I);
2022 bool MadeChange =
false;
2024 if (!BBExecutable.count(&BB))
2032 <<
"\nResolved undefs in " <<
F.getName() <<
'\n');
2051 Visitor->addPredicateInfo(
F, DT, AC);
2055 return Visitor->markBlockExecutable(BB);
2059 return Visitor->getPredicateInfoFor(
I);
2063 Visitor->trackValueOfGlobalVariable(GV);
2067 Visitor->addTrackedFunction(
F);
2071 Visitor->addToMustPreserveReturnsInFunctions(
F);
2075 return Visitor->mustPreserveReturn(
F);
2079 Visitor->addArgumentTrackedFunction(
F);
2083 return Visitor->isArgumentTrackedFunction(
F);
2089 return Visitor->resolvedUndefsIn(
F);
2093 Visitor->solveWhileResolvedUndefsIn(M);
2098 Visitor->solveWhileResolvedUndefsIn(WorkList);
2102 Visitor->solveWhileResolvedUndefs();
2106 return Visitor->isBlockExecutable(BB);
2110 return Visitor->isEdgeFeasible(
From, To);
2113std::vector<ValueLatticeElement>
2115 return Visitor->getStructLatticeValueFor(V);
2119 return Visitor->removeLatticeValueFor(V);
2123 Visitor->resetLatticeValueFor(Call);
2127 return Visitor->getLatticeValueFor(V);
2132 return Visitor->getTrackedRetVals();
2137 return Visitor->getTrackedGlobals();
2141 return Visitor->getMRVFunctionsTracked();
2147 Visitor->trackValueOfArgument(V);
2151 return Visitor->isStructLatticeConstant(
F, STy);
2156 return Visitor->getConstant(LV, Ty);
2160 return Visitor->getConstantOrNull(V);
2164 return Visitor->getArgumentTrackedFunctions();
2169 Visitor->setLatticeValueForSpecializationArguments(
F, Args);
2173 Visitor->markFunctionUnreachable(
F);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
mir Rename Register Operands
static ValueLatticeElement::MergeOptions getMaxWidenStepsOpts()
Returns MergeOptions with MaxWidenSteps set to MaxNumRangeExtensions.
static const unsigned MaxNumRangeExtensions
static ValueLatticeElement getValueFromMetadata(const Instruction *I)
static ConstantRange getConstantRange(const ValueLatticeElement &LV, Type *Ty, bool UndefAllowed=true)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const uint32_t IV[8]
Class for arbitrary precision integers.
This class represents an incoming formal argument to a Function.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVMContext & getContext() const
Get the context in which this basic block lives.
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...
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
unsigned getNoWrapKind() const
Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, BasicBlock::iterator InsertBefore)
Construct a binary instruction, given the opcode and the two operands.
The address of a basic block.
static BranchInst * Create(BasicBlock *IfTrue, BasicBlock::iterator InsertBefore)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
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.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
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...
static ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID)
Returns true if ConstantRange calculations are supported for intrinsic with IntrinsicID.
bool isSingleElement() const
Return true if this set contains exactly one member.
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...
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind)
Produce the largest range containing all X such that "X BinOp Y" is guaranteed not to wrap (overflow)...
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
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 Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
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)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void applyUpdatesPermissive(ArrayRef< DominatorTree::UpdateType > Updates)
Submit updates to all available trees.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
An instruction for ordering other memory operations.
This class represents a freeze function that returns random concrete value if an operand is either a ...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This instruction inserts a struct field of array element value into an aggregate value.
Base class for instruction visitors.
void visit(Iterator Start, Iterator End)
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const BasicBlock * getParent() const
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
void setNonNeg(bool b=true)
Set or clear the nneg flag on this instruction, which must be a zext instruction.
bool hasNonNeg() const LLVM_READONLY
Determine whether the the nneg flag is set.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
bool isSpecialTerminator() const
This is an important class for using LLVM in a threaded context.
@ OB_clang_arc_attachedcall
An instruction for reading from memory.
This class implements a map that also provides access to all stored values in a deterministic order.
size_type count(const KeyT &Key) const
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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.
Resume the propagation of an exception.
Return a value (possibly void), from a function.
Helper class for SCCPSolver.
const PredicateBase * getPredicateInfoFor(Instruction *I)
std::vector< ValueLatticeElement > getStructLatticeValueFor(Value *V) const
bool resolvedUndef(Instruction &I)
void markFunctionUnreachable(Function *F)
bool markBlockExecutable(BasicBlock *BB)
bool resolvedUndefsIn(Function &F)
While solving the dataflow for a function, we don't compute a result for operations with an undef ope...
Constant * getConstant(const ValueLatticeElement &LV, Type *Ty) const
SCCPInstVisitor(const DataLayout &DL, std::function< const TargetLibraryInfo &(Function &)> GetTLI, LLVMContext &Ctx)
const ValueLatticeElement & getLatticeValueFor(Value *V) const
void removeLatticeValueFor(Value *V)
const DenseMap< GlobalVariable *, ValueLatticeElement > & getTrackedGlobals()
void trackValueOfArgument(Argument *A)
void visitCallInst(CallInst &I)
void markOverdefined(Value *V)
bool isArgumentTrackedFunction(Function *F)
void addTrackedFunction(Function *F)
void solveWhileResolvedUndefs()
SmallPtrSetImpl< Function * > & getArgumentTrackedFunctions()
void solveWhileResolvedUndefsIn(Module &M)
void trackValueOfGlobalVariable(GlobalVariable *GV)
Constant * getConstantOrNull(Value *V) const
const SmallPtrSet< Function *, 16 > getMRVFunctionsTracked()
void resetLatticeValueFor(CallBase *Call)
Invalidate the Lattice Value of Call and its users after specializing the call.
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals()
void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC)
void addToMustPreserveReturnsInFunctions(Function *F)
void addArgumentTrackedFunction(Function *F)
bool isStructLatticeConstant(Function *F, StructType *STy)
void solveWhileResolvedUndefsIn(SmallVectorImpl< Function * > &WorkList)
bool isBlockExecutable(BasicBlock *BB) const
bool mustPreserveReturn(Function *F)
void setLatticeValueForSpecializationArguments(Function *F, const SmallVectorImpl< ArgInfo > &Args)
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
void visitCall(CallInst &I)
const DenseMap< GlobalVariable *, ValueLatticeElement > & getTrackedGlobals()
getTrackedGlobals - Get and return the set of inferred initializers for global variables.
void resetLatticeValueFor(CallBase *Call)
Invalidate the Lattice Value of Call and its users after specializing the call.
void trackValueOfGlobalVariable(GlobalVariable *GV)
trackValueOfGlobalVariable - Clients can use this method to inform the SCCPSolver that it should trac...
bool tryToReplaceWithConstant(Value *V)
bool isStructLatticeConstant(Function *F, StructType *STy)
void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC)
void solve()
Solve - Solve for constants and executable blocks.
void visit(Instruction *I)
void trackValueOfArgument(Argument *V)
trackValueOfArgument - Mark the specified argument overdefined unless it have range attribute.
void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals()
getTrackedRetVals - Get the inferred return value map.
void solveWhileResolvedUndefsIn(Module &M)
const PredicateBase * getPredicateInfoFor(Instruction *I)
bool resolvedUndefsIn(Function &F)
resolvedUndefsIn - While solving the dataflow for a function, we assume that branches on undef values...
void addArgumentTrackedFunction(Function *F)
void solveWhileResolvedUndefs()
void removeLatticeValueFor(Value *V)
std::vector< ValueLatticeElement > getStructLatticeValueFor(Value *V) const
const SmallPtrSet< Function *, 16 > getMRVFunctionsTracked()
getMRVFunctionsTracked - Get the set of functions which return multiple values tracked by the pass.
Constant * getConstantOrNull(Value *V) const
Return either a Constant or nullptr for a given Value.
bool simplifyInstsInBlock(BasicBlock &BB, SmallPtrSetImpl< Value * > &InsertedValues, Statistic &InstRemovedStat, Statistic &InstReplacedStat)
Constant * getConstant(const ValueLatticeElement &LV, Type *Ty) const
Helper to return a Constant if LV is either a constant or a constant range with a single element.
const ValueLatticeElement & getLatticeValueFor(Value *V) const
void addToMustPreserveReturnsInFunctions(Function *F)
Add function to the list of functions whose return cannot be modified.
bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, BasicBlock *&NewUnreachableBB) const
bool isBlockExecutable(BasicBlock *BB) const
bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
void setLatticeValueForSpecializationArguments(Function *F, const SmallVectorImpl< ArgInfo > &Args)
Set the Lattice Value for the arguments of a specialization F.
static bool isConstant(const ValueLatticeElement &LV)
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const
bool mustPreserveReturn(Function *F)
Returns true if the return of the given function cannot be modified.
static bool isOverdefined(const ValueLatticeElement &LV)
void markFunctionUnreachable(Function *F)
Mark all of the blocks in function F non-executable.
bool isArgumentTrackedFunction(Function *F)
Returns true if the given function is in the solver's set of argument-tracked functions.
SCCPSolver(const DataLayout &DL, std::function< const TargetLibraryInfo &(Function &)> GetTLI, LLVMContext &Ctx)
SmallPtrSetImpl< Function * > & getArgumentTrackedFunctions()
Return a reference to the set of argument tracked functions.
void markOverdefined(Value *V)
markOverdefined - Mark the specified value overdefined.
This class represents the LLVM 'select' instruction.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
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 assign(size_type NumElts, ValueParamT Elt)
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.
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
A wrapper class to simplify modification of SwitchInst cases along with their prof branch_weights met...
Provides information about what library functions are available for the current target.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isStructTy() const
True if this is an instance of StructType.
bool isVoidTy() const
Return true if this is 'void'.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
This function has undefined behavior.
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
Constant * getCompare(CmpInst::Predicate Pred, Type *Ty, const ValueLatticeElement &Other, const DataLayout &DL) const
true, false or undef constants, or nullptr if the comparison cannot be evaluated.
static ValueLatticeElement getNot(Constant *C)
bool isNotConstant() const
void setNumRangeExtensions(unsigned N)
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.
unsigned getNumRangeExtensions() const
bool isUnknownOrUndef() const
Constant * getConstant() const
bool mergeIn(const ValueLatticeElement &RHS, MergeOptions Opts=MergeOptions())
Updates this object to approximate both this object and RHS.
bool markConstant(Constant *V, bool MayIncludeUndef=false)
static ValueLatticeElement getOverdefined()
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
std::string getNameOrAsOperand() const
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
Represents an op.with.overflow intrinsic.
This class represents zero extension of integer types.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
static bool replaceSignedInst(SCCPSolver &Solver, SmallPtrSetImpl< Value * > &InsertedValues, Instruction &Inst)
Try to replace signed instructions with their unsigned equivalent.
bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
auto successors(const MachineBasicBlock *BB)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
Constant * ConstantFoldInstOperands(Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
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.
bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
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.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
static bool canRemoveInstruction(Instruction *I)
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
static bool refineInstruction(SCCPSolver &Solver, const SmallPtrSetImpl< Value * > &InsertedValues, Instruction &Inst)
Try to use Inst's value range from Solver to infer the NUW flag.
Implement std::hash so that hash_code can be used in STL containers.
Struct to control some aspects related to merging constant ranges.
MergeOptions & setMaxWidenSteps(unsigned Steps=1)
MergeOptions & setCheckWiden(bool V=true)