36#define DEBUG_TYPE "indvars"
38STATISTIC(NumElimIdentity,
"Number of IV identities eliminated");
39STATISTIC(NumElimOperand,
"Number of IV operands folded into a use");
40STATISTIC(NumFoldedUser,
"Number of IV users folded into a constant");
41STATISTIC(NumElimRem ,
"Number of IV remainder operations eliminated");
44 "Number of IV signed division operations converted to unsigned division");
47 "Number of IV signed remainder operations converted to unsigned remainder");
48STATISTIC(NumElimCmp,
"Number of IV comparisons eliminated");
49STATISTIC(NumInvariantCmp,
"Number of IV comparisons made loop invariant");
50STATISTIC(NumSameSign,
"Number of IV comparisons with new samesign flags");
57 class SimplifyIndvar {
67 bool RunUnswitching =
false;
74 : L(
Loop), LI(LI), SE(SE), DT(DT),
TTI(
TTI), Rewriter(Rewriter),
76 assert(LI &&
"IV simplification requires LoopInfo");
79 bool hasChanged()
const {
return Changed; }
80 bool runUnswitching()
const {
return RunUnswitching; }
85 void simplifyUsers(PHINode *CurrIV, IVVisitor *V =
nullptr);
87 void pushIVUsers(Instruction *Def,
88 SmallPtrSet<Instruction *, 16> &Simplified,
89 SmallVectorImpl<std::pair<Instruction *, Instruction *>>
92 Value *foldIVUser(Instruction *UseInst, Instruction *IVOperand);
94 bool eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand);
95 bool replaceIVUserWithLoopInvariant(Instruction *UseInst);
96 bool replaceFloatIVWithIntegerIV(Instruction *UseInst);
98 bool eliminateOverflowIntrinsic(WithOverflowInst *WO);
99 bool eliminateSaturatingIntrinsic(SaturatingInst *SI);
100 bool eliminateTrunc(TruncInst *TI);
101 bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand);
102 bool makeIVComparisonInvariant(ICmpInst *ICmp, Instruction *IVOperand);
103 void eliminateIVComparison(ICmpInst *ICmp, Instruction *IVOperand);
104 void simplifyIVRemainder(BinaryOperator *Rem, Instruction *IVOperand,
106 void replaceRemWithNumerator(BinaryOperator *Rem);
107 void replaceRemWithNumeratorOrZero(BinaryOperator *Rem);
108 bool replaceRemWithNumeratorOrZeroUpdateProfiles(SelectInst &SI);
109 void replaceSRemWithURem(BinaryOperator *Rem);
110 bool eliminateSDiv(BinaryOperator *SDiv);
111 bool strengthenBinaryOp(BinaryOperator *BO, Instruction *IVOperand);
112 bool strengthenOverflowingOperation(BinaryOperator *OBO,
113 Instruction *IVOperand);
114 bool strengthenRightShift(BinaryOperator *BO, Instruction *IVOperand);
124 for (
auto *Insn : Instructions)
127 assert(CommonDom &&
"Common dominator not found?");
140 Value *IVSrc =
nullptr;
141 const unsigned OperIdx = 0;
142 const SCEV *FoldedExpr =
nullptr;
143 bool MustDropExactFlag =
false;
147 case Instruction::UDiv:
148 case Instruction::LShr:
151 if (IVOperand != UseInst->
getOperand(OperIdx) ||
166 if (UseInst->
getOpcode() == Instruction::LShr) {
181 MustDropExactFlag =
true;
188 if (SE->
getSCEV(UseInst) != FoldedExpr)
191 LLVM_DEBUG(
dbgs() <<
"INDVARS: Eliminated IV operand: " << *IVOperand
192 <<
" -> " << *UseInst <<
'\n');
195 assert(SE->
getSCEV(UseInst) == FoldedExpr &&
"bad SCEV with folded oper");
197 if (MustDropExactFlag)
203 DeadInsts.emplace_back(IVOperand);
207bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp,
208 Instruction *IVOperand) {
212 unsigned IVOperIdx = 0;
229 ICmpInst::Predicate InvariantPredicate = LIP->Pred;
230 const SCEV *InvariantLHS = LIP->LHS;
231 const SCEV *InvariantRHS = LIP->RHS;
234 auto *PHTerm = Preheader->getTerminator();
235 if (
Rewriter.isHighCostExpansion({InvariantLHS, InvariantRHS}, L,
237 !
Rewriter.isSafeToExpandAt(InvariantLHS, PHTerm) ||
238 !
Rewriter.isSafeToExpandAt(InvariantRHS, PHTerm))
244 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified comparison: " << *ICmp <<
'\n');
248 RunUnswitching =
true;
254void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp,
255 Instruction *IVOperand) {
256 unsigned IVOperIdx = 0;
258 ICmpInst::Predicate OriginalPred = Pred;
274 SmallVector<Instruction *, 4>
Users;
275 for (
auto *U : ICmp->
users())
281 DeadInsts.emplace_back(ICmp);
282 LLVM_DEBUG(
dbgs() <<
"INDVARS: Eliminated comparison: " << *ICmp <<
'\n');
288 if (makeIVComparisonInvariant(ICmp, IVOperand)) {
294 if ((ICmpInst::isSigned(OriginalPred) ||
295 (ICmpInst::isUnsigned(OriginalPred) && !ICmp->
hasSameSign())) &&
302 LLVM_DEBUG(
dbgs() <<
"INDVARS: Marking comparison samesign: " << *ICmp
312bool SimplifyIndvar::eliminateSDiv(BinaryOperator *SDiv) {
327 UDiv->setIsExact(SDiv->
isExact());
330 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified sdiv: " << *SDiv <<
'\n');
333 DeadInsts.push_back(SDiv);
341void SimplifyIndvar::replaceSRemWithURem(BinaryOperator *Rem) {
347 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified srem: " << *Rem <<
'\n');
350 DeadInsts.emplace_back(Rem);
354void SimplifyIndvar::replaceRemWithNumerator(BinaryOperator *Rem) {
356 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified rem: " << *Rem <<
'\n');
359 DeadInsts.emplace_back(Rem);
362bool SimplifyIndvar::replaceRemWithNumeratorOrZeroUpdateProfiles(
372 if (
L->getExitingBlock() != Latch || !DT->
dominates(
SI.getParent(), Latch))
377 if (
L->getExitingBlock() ==
nullptr ||
L->getExitingBlock() != Latch)
391void SimplifyIndvar::replaceRemWithNumeratorOrZero(BinaryOperator *Rem) {
394 ICmpInst *ICmp =
new ICmpInst(Rem->
getIterator(), ICmpInst::ICMP_EQ,
N,
D);
400 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified rem: " << *Rem <<
'\n');
403 DeadInsts.emplace_back(Rem);
404 if (!replaceRemWithNumeratorOrZeroUpdateProfiles(*Sel))
410void SimplifyIndvar::simplifyIVRemainder(BinaryOperator *Rem,
411 Instruction *IVOperand,
418 bool UsedAsNumerator = IVOperand == NValue;
419 if (!UsedAsNumerator && !IsSigned)
422 const SCEV *
N = SE->
getSCEV(NValue);
431 if (!IsNumeratorNonNegative)
434 const SCEV *
D = SE->
getSCEV(DValue);
437 if (UsedAsNumerator) {
438 auto LT = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
440 replaceRemWithNumerator(Rem);
447 replaceRemWithNumeratorOrZero(Rem);
457 replaceSRemWithURem(Rem);
460bool SimplifyIndvar::eliminateOverflowIntrinsic(WithOverflowInst *WO) {
479 for (
auto *U : WO->
users()) {
481 if (EVI->getIndices()[0] == 1)
484 assert(EVI->getIndices()[0] == 0 &&
"Only two possibilities!");
485 EVI->replaceAllUsesWith(NewResult);
492 for (
auto *EVI : ToDelete)
493 EVI->eraseFromParent();
502bool SimplifyIndvar::eliminateSaturatingIntrinsic(SaturatingInst *SI) {
509 SI->getBinaryOp(),
SI->getLHS(),
SI->getRHS(),
SI->getName(),
SI->getIterator());
515 SI->replaceAllUsesWith(BO);
517 DeadInsts.emplace_back(SI);
522bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) {
540 Type *IVTy =
IV->getType();
542 const SCEV *TISCEV = SE->
getSCEV(TI);
546 bool DoesSExtCollapse =
false;
547 bool DoesZExtCollapse =
false;
549 DoesSExtCollapse =
true;
551 DoesZExtCollapse =
true;
555 if (!DoesSExtCollapse && !DoesZExtCollapse)
561 for (
auto *U : TI->
users()) {
567 if (!ICI)
return false;
573 if (ICI->
isSigned() && !DoesSExtCollapse)
581 auto CanUseZExt = [&](ICmpInst *ICI) {
586 if (!DoesZExtCollapse)
600 for (
auto *ICI : ICmpUsers) {
601 bool IsSwapped =
L->isLoopInvariant(ICI->
getOperand(0));
604 Value *Ext =
nullptr;
612 if (IsSwapped) Pred = ICmpInst::getSwappedPredicate(Pred);
613 if (CanUseZExt(ICI)) {
614 assert(DoesZExtCollapse &&
"Unprofitable zext?");
615 Ext = Builder.CreateZExt(Op1, IVTy,
"zext");
618 assert(DoesSExtCollapse &&
"Unprofitable sext?");
619 Ext = Builder.CreateSExt(Op1, IVTy,
"sext");
625 auto *NewCmp = Builder.CreateICmp(Pred,
IV, Ext);
627 DeadInsts.emplace_back(ICI);
632 DeadInsts.emplace_back(TI);
639bool SimplifyIndvar::eliminateIVUser(Instruction *UseInst,
640 Instruction *IVOperand) {
642 eliminateIVComparison(ICmp, IVOperand);
646 bool IsSRem =
Bin->getOpcode() == Instruction::SRem;
647 if (IsSRem ||
Bin->getOpcode() == Instruction::URem) {
648 simplifyIVRemainder(
Bin, IVOperand, IsSRem);
652 if (
Bin->getOpcode() == Instruction::SDiv)
653 return eliminateSDiv(
Bin);
657 if (eliminateOverflowIntrinsic(WO))
661 if (eliminateSaturatingIntrinsic(SI))
665 if (eliminateTrunc(TI))
668 if (eliminateIdentitySCEV(UseInst, IVOperand))
675 if (
auto *BB = L->getLoopPreheader())
676 return BB->getTerminator();
682bool SimplifyIndvar::replaceIVUserWithLoopInvariant(Instruction *
I) {
698 if (!
Rewriter.isSafeToExpandAt(S, IP)) {
700 <<
" with non-speculable loop invariant: " << *S <<
'\n');
704 auto *Invariant =
Rewriter.expandCodeFor(S,
I->getType(), IP);
705 bool NeedToEmitLCSSAPhis =
false;
707 NeedToEmitLCSSAPhis =
true;
709 I->replaceAllUsesWith(Invariant);
711 <<
" with loop invariant: " << *S <<
'\n');
713 if (NeedToEmitLCSSAPhis) {
718 <<
" inserting LCSSA Phis" <<
'\n');
722 DeadInsts.emplace_back(
I);
727bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) {
728 if (UseInst->
getOpcode() != CastInst::SIToFP &&
729 UseInst->
getOpcode() != CastInst::UIToFP)
736 if (UseInst->
getOpcode() == CastInst::SIToFP)
741 if (MaskBits <= DestNumSigBits) {
742 for (User *U : UseInst->
users()) {
748 CastInst::CastOps Opcode = CI->getOpcode();
749 if (Opcode != CastInst::FPToSI && Opcode != CastInst::FPToUI)
752 Value *Conv =
nullptr;
753 if (IVOperand->
getType() != CI->getType()) {
760 Conv = Builder.CreateTrunc(IVOperand, CI->getType(), Name +
".trunc");
761 }
else if (Opcode == CastInst::FPToUI ||
762 UseInst->
getOpcode() == CastInst::UIToFP) {
763 Conv = Builder.CreateZExt(IVOperand, CI->getType(), Name +
".zext");
765 Conv = Builder.CreateSExt(IVOperand, CI->getType(), Name +
".sext");
771 DeadInsts.push_back(CI);
773 <<
" with: " << *Conv <<
'\n');
784bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
785 Instruction *IVOperand) {
790 const SCEV *UseSCEV = SE->
getSCEV(UseInst);
791 if (UseSCEV != SE->
getSCEV(IVOperand))
813 if (!DT || !DT->
dominates(IVOperand, UseInst))
821 SmallVector<Instruction *> DropPoisonGeneratingInsts;
825 for (Instruction *
I : DropPoisonGeneratingInsts)
826 I->dropPoisonGeneratingAnnotations();
829 LLVM_DEBUG(
dbgs() <<
"INDVARS: Eliminated identity: " << *UseInst <<
'\n');
835 DeadInsts.emplace_back(UseInst);
839bool SimplifyIndvar::strengthenBinaryOp(BinaryOperator *BO,
840 Instruction *IVOperand) {
842 strengthenOverflowingOperation(BO, IVOperand)) ||
848bool SimplifyIndvar::strengthenOverflowingOperation(BinaryOperator *BO,
849 Instruction *IVOperand) {
872bool SimplifyIndvar::strengthenRightShift(BinaryOperator *BO,
873 Instruction *IVOperand) {
874 if (BO->
getOpcode() == Instruction::Shl) {
877 for (
auto *U : BO->
users()) {
897void SimplifyIndvar::pushIVUsers(
898 Instruction *Def, SmallPtrSet<Instruction *, 16> &Simplified,
899 SmallVectorImpl<std::pair<Instruction *, Instruction *>> &SimpleIVUsers) {
900 for (User *U :
Def->users()) {
912 if (!
L->contains(UI))
919 SimpleIVUsers.push_back(std::make_pair(UI, Def));
956void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
969 pushIVUsers(CurrIV, Simplified, SimpleIVUsers);
971 while (!SimpleIVUsers.
empty()) {
972 std::pair<Instruction*, Instruction*> UseOper =
981 DeadInsts.emplace_back(UseInst);
986 if (UseInst == CurrIV)
continue;
990 if (replaceIVUserWithLoopInvariant(UseInst))
996 for (Use &U : UseInst->
uses()) {
998 if (replaceIVUserWithLoopInvariant(User))
1003 for (
unsigned N = 0; IVOperand; ++
N) {
1007 Value *NewOper = foldIVUser(UseInst, IVOperand);
1015 if (eliminateIVUser(UseInst, IVOperand)) {
1016 pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
1021 if (strengthenBinaryOp(BO, IVOperand)) {
1024 pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
1029 if (replaceFloatIVWithIntegerIV(UseInst)) {
1031 pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
1041 pushIVUsers(UseInst, Simplified, SimpleIVUsers);
1062 SIV.simplifyUsers(CurrIV, V);
1063 return {SIV.hasChanged(), SIV.runUnswitching()};
1072#if LLVM_ENABLE_ABI_BREAKING_CHECKS
1077 const auto &[
C,
_] =
1100 ScalarEvolution *SE;
1107 bool UsePostIncrementRanges;
1110 unsigned NumElimExt = 0;
1111 unsigned NumWidened = 0;
1114 PHINode *WidePhi =
nullptr;
1116 const SCEV *WideIncExpr =
nullptr;
1117 SmallVectorImpl<WeakTrackingVH> &DeadInsts;
1119 SmallPtrSet<Instruction *,16> Widened;
1127 DenseMap<AssertingVH<Instruction>,
ExtendKind> ExtendKindMap;
1129 using DefUserPair = std::pair<AssertingVH<Value>, AssertingVH<Instruction>>;
1135 DenseMap<DefUserPair, ConstantRange> PostIncRangeInfos;
1137 std::optional<ConstantRange> getPostIncRangeInfo(
Value *Def,
1138 Instruction *UseI) {
1139 DefUserPair
Key(Def, UseI);
1140 auto It = PostIncRangeInfos.
find(
Key);
1141 return It == PostIncRangeInfos.
end()
1142 ? std::optional<ConstantRange>(std::nullopt)
1143 : std::optional<ConstantRange>(It->second);
1146 void calculatePostIncRanges(PHINode *OrigPhi);
1147 void calculatePostIncRange(Instruction *NarrowDef, Instruction *NarrowUser);
1149 void updatePostIncRangeInfo(
Value *Def, Instruction *UseI, ConstantRange R) {
1150 DefUserPair
Key(Def, UseI);
1153 It->second =
R.intersectWith(It->second);
1160 struct NarrowIVDefUse {
1168 bool NeverNegative =
false;
1170 NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD,
1172 : NarrowDef(ND), NarrowUse(NU), WideDef(WD),
1173 NeverNegative(NeverNegative) {}
1176 WidenIV(
const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
1177 DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
1178 bool HasGuards,
bool UsePostIncrementRanges =
true);
1182 unsigned getNumElimExt() {
return NumElimExt; };
1183 unsigned getNumWidened() {
return NumWidened; };
1186 Value *createExtendInst(
Value *NarrowOper,
Type *WideType,
bool IsSigned,
1189 Instruction *cloneIVUser(NarrowIVDefUse DU,
const SCEVAddRecExpr *WideAR);
1190 Instruction *cloneArithmeticIVUser(NarrowIVDefUse DU,
1191 const SCEVAddRecExpr *WideAR);
1192 Instruction *cloneBitwiseIVUser(NarrowIVDefUse DU);
1196 using WidenedRecTy = std::pair<const SCEVAddRecExpr *, ExtendKind>;
1198 WidenedRecTy getWideRecurrence(NarrowIVDefUse DU);
1200 WidenedRecTy getExtendedOperandRecurrence(NarrowIVDefUse DU);
1202 const SCEV *getSCEVByOpCode(
const SCEV *
LHS,
const SCEV *
RHS,
1203 unsigned OpCode)
const;
1206 PHINode *OrigPhi, PHINode *WidePhi);
1207 void truncateIVUse(NarrowIVDefUse DU);
1209 bool widenLoopCompare(NarrowIVDefUse DU);
1210 bool widenWithVariantUse(NarrowIVDefUse DU);
1212 void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
1232 for (
unsigned i = 0, e =
PHI->getNumIncomingValues(); i != e; ++i) {
1233 if (
PHI->getIncomingValue(i) != Def)
1258 assert(DT->
dominates(DefI, InsertPt) &&
"def does not dominate all uses");
1263 for (
auto *DTN = (*DT)[InsertPt->
getParent()]; DTN; DTN = DTN->getIDom())
1265 return DTN->getBlock()->getTerminator();
1270WidenIV::WidenIV(
const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
1271 DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
1272 bool HasGuards,
bool UsePostIncrementRanges)
1273 : OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), LI(LInfo),
1274 L(LI->getLoopFor(OrigPhi->
getParent())), SE(SEv), DT(DTree),
1275 HasGuards(HasGuards), UsePostIncrementRanges(UsePostIncrementRanges),
1278 ExtendKindMap[OrigPhi] = WI.
IsSigned ? ExtendKind::Sign : ExtendKind::Zero;
1281Value *WidenIV::createExtendInst(
Value *NarrowOper,
Type *WideType,
1287 L &&
L->getLoopPreheader() &&
L->isLoopInvariant(NarrowOper);
1288 L =
L->getParentLoop())
1289 Builder.SetInsertPoint(
L->getLoopPreheader()->getTerminator());
1291 return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) :
1292 Builder.CreateZExt(NarrowOper, WideType);
1298Instruction *WidenIV::cloneIVUser(WidenIV::NarrowIVDefUse DU,
1299 const SCEVAddRecExpr *WideAR) {
1300 unsigned Opcode = DU.NarrowUse->
getOpcode();
1304 case Instruction::Add:
1305 case Instruction::Mul:
1306 case Instruction::UDiv:
1307 case Instruction::Sub:
1308 return cloneArithmeticIVUser(DU, WideAR);
1310 case Instruction::And:
1311 case Instruction::Or:
1312 case Instruction::Xor:
1313 case Instruction::Shl:
1314 case Instruction::LShr:
1315 case Instruction::AShr:
1316 return cloneBitwiseIVUser(DU);
1320Instruction *WidenIV::cloneBitwiseIVUser(WidenIV::NarrowIVDefUse DU) {
1325 LLVM_DEBUG(
dbgs() <<
"Cloning bitwise IVUser: " << *NarrowUse <<
"\n");
1331 bool IsSigned = getExtendKind(NarrowDef) == ExtendKind::Sign;
1334 : createExtendInst(NarrowUse->
getOperand(0), WideType,
1335 IsSigned, NarrowUse);
1338 : createExtendInst(NarrowUse->
getOperand(1), WideType,
1339 IsSigned, NarrowUse);
1345 Builder.Insert(WideBO);
1346 WideBO->copyIRFlags(NarrowBO);
1350Instruction *WidenIV::cloneArithmeticIVUser(WidenIV::NarrowIVDefUse DU,
1351 const SCEVAddRecExpr *WideAR) {
1356 LLVM_DEBUG(
dbgs() <<
"Cloning arithmetic IVUser: " << *NarrowUse <<
"\n");
1358 unsigned IVOpIdx = (NarrowUse->
getOperand(0) == NarrowDef) ? 0 : 1;
1369 auto GuessNonIVOperand = [&](
bool SignExt) {
1370 const SCEV *WideLHS;
1371 const SCEV *WideRHS;
1373 auto GetExtend = [
this, SignExt](
const SCEV *S,
Type *Ty) {
1380 WideLHS = SE->
getSCEV(WideDef);
1382 WideRHS = GetExtend(NarrowRHS, WideType);
1385 WideLHS = GetExtend(NarrowLHS, WideType);
1386 WideRHS = SE->
getSCEV(WideDef);
1390 const SCEV *WideUse =
1391 getSCEVByOpCode(WideLHS, WideRHS, NarrowUse->
getOpcode());
1393 return WideUse == WideAR;
1396 bool SignExtend = getExtendKind(NarrowDef) == ExtendKind::Sign;
1397 if (!GuessNonIVOperand(SignExtend)) {
1398 SignExtend = !SignExtend;
1399 if (!GuessNonIVOperand(SignExtend))
1405 : createExtendInst(NarrowUse->
getOperand(0), WideType,
1406 SignExtend, NarrowUse);
1409 : createExtendInst(NarrowUse->
getOperand(1), WideType,
1410 SignExtend, NarrowUse);
1417 Builder.Insert(WideBO);
1418 WideBO->copyIRFlags(NarrowBO);
1422WidenIV::ExtendKind WidenIV::getExtendKind(Instruction *
I) {
1423 auto It = ExtendKindMap.
find(
I);
1424 assert(It != ExtendKindMap.
end() &&
"Instruction not yet extended!");
1428const SCEV *WidenIV::getSCEVByOpCode(
const SCEV *
LHS,
const SCEV *
RHS,
1429 unsigned OpCode)
const {
1431 case Instruction::Add:
1433 case Instruction::Sub:
1435 case Instruction::Mul:
1437 case Instruction::UDiv:
1459 IsNSW = OBO->hasNoSignedWrap();
1460 IsNUW = OBO->hasNoUnsignedWrap();
1465 bool IsNSW =
false,
bool IsNUW =
false)
1466 : Opcode(Opcode),
Operands({
LHS,
RHS}), IsNSW(IsNSW), IsNUW(IsNUW) {}
1472 switch (
Op->getOpcode()) {
1473 case Instruction::Add:
1474 case Instruction::Sub:
1475 case Instruction::Mul:
1477 case Instruction::Or: {
1480 return BinaryOp(Instruction::Add,
Op->getOperand(0),
Op->getOperand(1),
1484 case Instruction::Shl: {
1492 if (SA->getValue().ult(
BitWidth)) {
1497 bool IsNUW =
Op->hasNoUnsignedWrap();
1498 bool IsNSW =
Op->hasNoSignedWrap() &&
1499 (IsNUW || SA->getValue().ult(
BitWidth - 1));
1502 ConstantInt::get(
Op->getContext(),
1504 return BinaryOp(Instruction::Mul,
Op->getOperand(0),
X, IsNSW, IsNUW);
1512 return std::nullopt;
1520WidenIV::WidenedRecTy
1521WidenIV::getExtendedOperandRecurrence(WidenIV::NarrowIVDefUse DU) {
1524 return {
nullptr, ExtendKind::Unknown};
1526 assert((
Op->Opcode == Instruction::Add ||
Op->Opcode == Instruction::Sub ||
1527 Op->Opcode == Instruction::Mul) &&
1528 "Unexpected opcode");
1532 const unsigned ExtendOperIdx =
Op->Operands[0] == DU.NarrowDef ? 1 : 0;
1533 assert(
Op->Operands[1 - ExtendOperIdx] == DU.NarrowDef &&
"bad DU");
1535 ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
1536 if (!(ExtKind == ExtendKind::Sign &&
Op->IsNSW) &&
1537 !(ExtKind == ExtendKind::Zero &&
Op->IsNUW)) {
1538 ExtKind = ExtendKind::Unknown;
1544 if (DU.NeverNegative) {
1546 ExtKind = ExtendKind::Sign;
1547 }
else if (
Op->IsNUW) {
1548 ExtKind = ExtendKind::Zero;
1553 const SCEV *ExtendOperExpr = SE->
getSCEV(
Op->Operands[ExtendOperIdx]);
1554 if (ExtKind == ExtendKind::Sign)
1556 else if (ExtKind == ExtendKind::Zero)
1559 return {
nullptr, ExtendKind::Unknown};
1566 const SCEV *lhs = SE->
getSCEV(DU.WideDef);
1567 const SCEV *rhs = ExtendOperExpr;
1571 if (ExtendOperIdx == 0)
1573 const SCEVAddRecExpr *AddRec =
1576 if (!AddRec || AddRec->
getLoop() != L)
1577 return {
nullptr, ExtendKind::Unknown};
1579 return {AddRec, ExtKind};
1587WidenIV::WidenedRecTy WidenIV::getWideRecurrence(WidenIV::NarrowIVDefUse DU) {
1589 return {
nullptr, ExtendKind::Unknown};
1591 const SCEV *NarrowExpr = SE->
getSCEV(DU.NarrowUse);
1596 return {
nullptr, ExtendKind::Unknown};
1599 const SCEV *WideExpr;
1601 if (DU.NeverNegative) {
1604 ExtKind = ExtendKind::Sign;
1607 ExtKind = ExtendKind::Zero;
1609 }
else if (getExtendKind(DU.NarrowDef) == ExtendKind::Sign) {
1611 ExtKind = ExtendKind::Sign;
1614 ExtKind = ExtendKind::Zero;
1617 if (!AddRec || AddRec->
getLoop() != L)
1618 return {
nullptr, ExtendKind::Unknown};
1619 return {AddRec, ExtKind};
1624void WidenIV::truncateIVUse(NarrowIVDefUse DU) {
1628 LLVM_DEBUG(
dbgs() <<
"INDVARS: Truncate IV " << *DU.WideDef <<
" for user "
1629 << *DU.NarrowUse <<
"\n");
1630 ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
1633 Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType(),
"",
1634 DU.NeverNegative || ExtKind == ExtendKind::Zero,
1635 DU.NeverNegative || ExtKind == ExtendKind::Sign);
1636 DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
1642bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
1661 bool IsSigned = getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
1662 bool CmpPreferredSign =
Cmp->hasSameSign() ? IsSigned :
Cmp->isSigned();
1663 if (!DU.NeverNegative && IsSigned != CmpPreferredSign)
1666 Value *
Op =
Cmp->getOperand(
Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
1669 assert(CastWidth <= IVWidth &&
"Unexpected width while widening compare.");
1675 if (CastWidth < IVWidth) {
1680 CmpPreferredSign =
true;
1682 Value *ExtOp = createExtendInst(
Op, WideType, CmpPreferredSign, Cmp);
1708bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
1716 if (OpCode != Instruction::Add && OpCode != Instruction::Sub &&
1717 OpCode != Instruction::Mul)
1726 const OverflowingBinaryOperator *OBO =
1728 ExtendKind ExtKind = getExtendKind(NarrowDef);
1729 bool CanSignExtend = ExtKind == ExtendKind::Sign && OBO->
hasNoSignedWrap();
1731 auto AnotherOpExtKind = ExtKind;
1738 SmallVector<Instruction *, 4> ExtUsers;
1741 for (Use &U : NarrowUse->
uses()) {
1743 if (User == NarrowDef)
1745 if (!
L->contains(User)) {
1749 if (LCSSAPhi->getNumOperands() != 1)
1760 if (ExtKind == ExtendKind::Zero && ICmpInst::isSigned(Pred))
1762 if (ExtKind == ExtendKind::Sign && ICmpInst::isUnsigned(Pred))
1767 if (ExtKind == ExtendKind::Sign)
1771 if (!User ||
User->getType() != WideType)
1775 if (ExtUsers.
empty()) {
1785 if (!CanSignExtend && !CanZeroExtend) {
1788 if (OpCode != Instruction::Add)
1790 if (ExtKind != ExtendKind::Zero)
1808 AnotherOpExtKind = ExtendKind::Sign;
1812 const SCEV *Op1 = SE->
getSCEV(WideDef);
1814 if (!AddRecOp1 || AddRecOp1->
getLoop() != L)
1817 LLVM_DEBUG(
dbgs() <<
"Cloning arithmetic IVUser: " << *NarrowUse <<
"\n");
1823 : createExtendInst(NarrowUse->
getOperand(0), WideType,
1824 AnotherOpExtKind == ExtendKind::Sign, NarrowUse);
1828 : createExtendInst(NarrowUse->
getOperand(1), WideType,
1829 AnotherOpExtKind == ExtendKind::Sign, NarrowUse);
1835 Builder.Insert(WideBO);
1836 WideBO->copyIRFlags(NarrowBO);
1837 ExtendKindMap[NarrowUse] = ExtKind;
1839 for (Instruction *User : ExtUsers) {
1840 assert(
User->getType() == WideType &&
"Checked before!");
1841 LLVM_DEBUG(
dbgs() <<
"INDVARS: eliminating " << *User <<
" replaced by "
1842 << *WideBO <<
"\n");
1844 User->replaceAllUsesWith(WideBO);
1848 for (PHINode *User : LCSSAPhiUsers) {
1849 assert(
User->getNumOperands() == 1 &&
"Checked before!");
1850 Builder.SetInsertPoint(User);
1852 Builder.CreatePHI(WideBO->getType(), 1,
User->getName() +
".wide");
1853 BasicBlock *LoopExitingBlock =
User->getParent()->getSinglePredecessor();
1854 assert(LoopExitingBlock &&
L->contains(LoopExitingBlock) &&
1855 "Not a LCSSA Phi?");
1856 WidePN->addIncoming(WideBO, LoopExitingBlock);
1857 Builder.SetInsertPoint(
User->getParent()->getFirstInsertionPt());
1858 auto *TruncPN = Builder.CreateTrunc(WidePN,
User->getType());
1859 User->replaceAllUsesWith(TruncPN);
1863 for (ICmpInst *User : ICmpUsers) {
1864 Builder.SetInsertPoint(User);
1868 if (ExtKind == ExtendKind::Zero)
1869 return Builder.CreateZExt(V, WideBO->getType());
1871 return Builder.CreateSExt(V, WideBO->getType());
1873 auto Pred =
User->getPredicate();
1874 auto *
LHS = ExtendedOp(
User->getOperand(0));
1875 auto *
RHS = ExtendedOp(
User->getOperand(1));
1877 Builder.CreateICmp(Pred,
LHS,
RHS,
User->getName() +
".wide");
1878 User->replaceAllUsesWith(WideCmp);
1887Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
1888 SCEVExpander &
Rewriter, PHINode *OrigPhi,
1891 "Should already know the kind of extension used to widen NarrowDef");
1895 bool CanWidenBySExt =
1896 DU.NeverNegative || getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
1897 bool CanWidenByZExt =
1898 DU.NeverNegative || getExtendKind(DU.NarrowDef) == ExtendKind::Zero;
1902 if (LI->
getLoopFor(UsePhi->getParent()) != L) {
1906 if (UsePhi->getNumOperands() != 1)
1917 UsePhi->getIterator());
1918 WidePhi->
addIncoming(DU.WideDef, UsePhi->getIncomingBlock(0));
1921 Value *Trunc = Builder.CreateTrunc(WidePhi, DU.NarrowDef->
getType(),
"",
1922 CanWidenByZExt, CanWidenBySExt);
1925 LLVM_DEBUG(
dbgs() <<
"INDVARS: Widen lcssa phi " << *UsePhi <<
" to "
1926 << *WidePhi <<
"\n");
1935 Value *NewDef = DU.WideDef;
1936 if (DU.NarrowUse->
getType() != WideType) {
1939 if (CastWidth < IVWidth) {
1942 NewDef = Builder.CreateTrunc(DU.WideDef, DU.NarrowUse->
getType(),
"",
1943 CanWidenByZExt, CanWidenBySExt);
1950 <<
" not wide enough to subsume " << *DU.NarrowUse
1953 NewDef = DU.NarrowUse;
1956 if (NewDef != DU.NarrowUse) {
1958 <<
" replaced by " << *DU.WideDef <<
"\n");
1973 auto tryAddRecExpansion = [&]() -> Instruction* {
1975 WidenedRecTy WideAddRec = getExtendedOperandRecurrence(DU);
1976 if (!WideAddRec.first)
1977 WideAddRec = getWideRecurrence(DU);
1978 assert((WideAddRec.first ==
nullptr) ==
1979 (WideAddRec.second == ExtendKind::Unknown));
1980 if (!WideAddRec.first)
1983 auto CanUseWideInc = [&]() {
1990 bool NeedToRecomputeFlags =
1992 OrigPhi, WidePhi, DU.NarrowUse, WideInc) ||
1995 return WideAddRec.first == WideIncExpr &&
1996 Rewriter.hoistIVInc(WideInc, DU.NarrowUse, NeedToRecomputeFlags);
2000 if (CanUseWideInc())
2003 WideUse = cloneIVUser(DU, WideAddRec.first);
2012 if (WideAddRec.first != SE->
getSCEV(WideUse)) {
2013 LLVM_DEBUG(
dbgs() <<
"Wide use expression mismatch: " << *WideUse <<
": "
2014 << *SE->
getSCEV(WideUse) <<
" != " << *WideAddRec.first
2024 ExtendKindMap[DU.NarrowUse] = WideAddRec.second;
2029 if (
auto *
I = tryAddRecExpansion())
2034 if (widenLoopCompare(DU))
2042 if (widenWithVariantUse(DU))
2053void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
2054 const SCEV *NarrowSCEV = SE->
getSCEV(NarrowDef);
2055 bool NonNegativeDef =
2058 for (User *U : NarrowDef->
users()) {
2062 if (!Widened.
insert(NarrowUser).second)
2065 bool NonNegativeUse =
false;
2066 if (!NonNegativeDef) {
2068 if (
auto RangeInfo = getPostIncRangeInfo(NarrowDef, NarrowUser))
2069 NonNegativeUse = RangeInfo->getSignedMin().isNonNegative();
2072 NarrowIVUsers.emplace_back(NarrowDef, NarrowUser, WideDef,
2073 NonNegativeDef || NonNegativeUse);
2085PHINode *WidenIV::createWideIV(SCEVExpander &
Rewriter) {
2092 const SCEV *WideIVExpr = getExtendKind(OrigPhi) == ExtendKind::Sign
2097 "Expect the new IV expression to preserve its type");
2101 if (!AddRec || AddRec->
getLoop() != L)
2110 "Loop header phi recurrence inputs do not dominate the loop");
2122 if (UsePostIncrementRanges)
2123 calculatePostIncRanges(OrigPhi);
2129 Instruction *InsertPt = &*
L->getHeader()->getFirstInsertionPt();
2130 Value *ExpandInst =
Rewriter.expandCodeFor(AddRec, WideType, InsertPt);
2147 if (BasicBlock *LatchBlock =
L->getLoopLatch()) {
2151 WideIncExpr = SE->
getSCEV(WideInc);
2168 OrigInc, WideInc) &&
2172 OrigInc->hasNoUnsignedWrap());
2174 OrigInc->hasNoSignedWrap());
2183 assert(Widened.
empty() && NarrowIVUsers.empty() &&
"expect initial state" );
2186 pushNarrowIVUsers(OrigPhi, WidePhi);
2188 while (!NarrowIVUsers.empty()) {
2189 WidenIV::NarrowIVDefUse DU = NarrowIVUsers.pop_back_val();
2197 pushNarrowIVUsers(DU.NarrowUse, WideUse);
2212void WidenIV::calculatePostIncRange(Instruction *NarrowDef,
2213 Instruction *NarrowUser) {
2214 Value *NarrowDefLHS;
2215 const APInt *NarrowDefRHS;
2221 auto UpdateRangeFromCondition = [&](
Value *Condition,
bool TrueDest) {
2231 auto CmpConstrainedLHSRange =
2233 auto NarrowDefRange = CmpConstrainedLHSRange.addWithNoWrap(
2236 updatePostIncRangeInfo(NarrowDef, NarrowUser, NarrowDefRange);
2239 auto UpdateRangeFromGuards = [&](
Instruction *Ctx) {
2243 for (Instruction &
I :
make_range(Ctx->getIterator().getReverse(),
2244 Ctx->getParent()->rend())) {
2247 UpdateRangeFromCondition(
C,
true);
2251 UpdateRangeFromGuards(NarrowUser);
2259 for (
auto *DTB = (*DT)[NarrowUserBB]->getIDom();
2260 L->contains(DTB->getBlock());
2261 DTB = DTB->getIDom()) {
2262 auto *BB = DTB->getBlock();
2263 auto *TI = BB->getTerminator();
2264 UpdateRangeFromGuards(TI);
2270 auto *TrueSuccessor = BI->getSuccessor(0);
2271 auto *FalseSuccessor = BI->getSuccessor(1);
2273 if (DT->
dominates(BasicBlockEdge(BB, TrueSuccessor), NarrowUserBB))
2274 UpdateRangeFromCondition(BI->getCondition(),
true);
2276 if (DT->
dominates(BasicBlockEdge(BB, FalseSuccessor), NarrowUserBB))
2277 UpdateRangeFromCondition(BI->getCondition(),
false);
2282void WidenIV::calculatePostIncRanges(PHINode *OrigPhi) {
2283 SmallPtrSet<Instruction *, 16> Visited;
2288 while (!Worklist.
empty()) {
2291 for (Use &U : NarrowDef->
uses()) {
2295 auto *NarrowUserLoop = (*LI)[NarrowUser->
getParent()];
2296 if (!NarrowUserLoop || !
L->contains(NarrowUserLoop))
2299 if (!Visited.
insert(NarrowUser).second)
2304 calculatePostIncRange(NarrowDef, NarrowUser);
2312 unsigned &NumElimExt,
unsigned &NumWidened,
2313 bool HasGuards,
bool UsePostIncrementRanges) {
2314 WidenIV Widener(WI, LI, SE, DT, DeadInsts, HasGuards, UsePostIncrementRanges);
2315 PHINode *WidePHI = Widener.createWideIV(Rewriter);
2316 NumElimExt = Widener.getNumElimExt();
2317 NumWidened = Widener.getNumWidened();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
iv Induction Variable Users
This file contains the declarations for profiling metadata utility functions.
static Instruction * GetLoopInvariantInsertPosition(Loop *L, Instruction *Hint)
static bool isSimpleIVUser(Instruction *I, const Loop *L, ScalarEvolution *SE)
Return true if this instruction generates a simple SCEV expression in terms of that IV.
static Instruction * findCommonDominator(ArrayRef< Instruction * > Instructions, DominatorTree &DT)
Find a point in code which dominates all given instructions.
static Instruction * getInsertPointForUses(Instruction *User, Value *Def, DominatorTree *DT, LoopInfo *LI)
Determine the insertion point for this user.
static std::optional< BinaryOp > matchBinaryOp(Instruction *Op)
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
virt reg Virtual Register Rewriter
static const uint32_t IV[8]
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
LLVM_ABI bool isSigned() const
Whether the intrinsic is signed or unsigned.
LLVM_ABI Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Predicate getPredicate() const
Return the predicate for this instruction.
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
LLVM_ABI unsigned getActiveBits() const
Compute the maximal number of active bits needed to represent every value in this range.
LLVM_ABI APInt getUnsignedMin() const
Return the smallest unsigned value contained in the ConstantRange.
static LLVM_ABI 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...
LLVM_ABI unsigned getMinSignedBits() const
Compute the maximal number of bits needed to represent every value in this signed range.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
bool hasSameSign() const
An icmp instruction, which can be marked as "samesign", indicating that the two operands have the sam...
void setSameSign(bool B=true)
CmpPredicate getCmpPredicate() const
CmpPredicate getSwappedCmpPredicate() const
CmpPredicate getInverseCmpPredicate() const
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
Predicate getUnsignedPredicate() const
For example, EQ->EQ, SLE->ULE, UGT->UGT, etc.
Interface for visiting interesting IV users that are recognized but not simplified by this utility.
LLVM_ABI void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
LLVM_ABI bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
LLVM_ABI void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
iterator_range< user_iterator > users()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void dropPoisonGeneratingFlags()
Drops flags that may cause this instruction to evaluate to poison despite having non-poison inputs.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
bool replacementPreservesLCSSAForm(Instruction *From, Value *To)
Returns true if replacing From with To everywhere is guaranteed to preserve LCSSA form.
Represents a single loop in the control flow graph.
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This node represents a polynomial recurrence on the trip count of the specified loop.
const Loop * getLoop() const
SCEVUse getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
This class uses information about analyze scalars to rewrite expressions in canonical form.
static LLVM_ABI bool canReuseFlagsFromOriginalIVInc(PHINode *OrigPhi, PHINode *WidePhi, Instruction *OrigInc, Instruction *WideInc)
Return true if both increments directly increment the corresponding IV PHI nodes and have the same op...
This class represents an analyzed expression in the program.
static constexpr auto FlagNUW
static constexpr auto FlagNSW
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getUDivExpr(SCEVUse LHS, SCEVUse RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI const SCEV * getZeroExtendExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
LLVM_ABI bool isKnownNegative(const SCEV *S)
Test if the given expression is known to be negative.
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI bool willNotOverflow(Instruction::BinaryOps BinOp, bool Signed, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI=nullptr)
Is operation BinOp between LHS and RHS provably does not have a signed/unsigned overflow (Signed)?
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI SCEVUse getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
ConstantRange getSignedRange(const SCEV *S)
Determine the signed range for a particular SCEV.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI std::optional< bool > evaluatePredicateAt(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI)
Check whether the condition described by Pred, LHS, and RHS is true or false in the given Context.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
static SCEVFlags maskFlags(SCEVFlags Flags, SCEVFlags Mask)
Convenient SCEVFlags manipulation.
LLVM_ABI SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI Type * getEffectiveSCEVType(Type *Ty) const
Return a type with the same bitwidth as the given type and which represents how SCEV will treat the g...
LLVM_ABI bool haveSameSign(const SCEV *S1, const SCEV *S2)
Return true if we know that S1 and S2 must have the same sign.
LLVM_ABI std::optional< SCEVFlags > getStrengthenedNoWrapFlagsFromBinOp(const OverflowingBinaryOperator *OBO)
Parse NSW/NUW flags from add/sub/mul IR binary operation Op into SCEV no-wrap flags,...
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
LLVM_ABI void forgetValue(Value *V)
This method should be called by the client when it has changed a value in a way that may effect its v...
LLVM_ABI const SCEV * getSignExtendExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
LLVM_ABI std::optional< LoopInvariantPredicate > getLoopInvariantPredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L, const Instruction *CtxI=nullptr)
If the result of the predicate LHS Pred RHS is loop invariant with respect to L, return a LoopInvaria...
LLVM_ABI SCEVUse getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI unsigned getSmallConstantTripCount(const Loop *L)
Returns the exact trip count of the loop if we can compute it, and the result is a small constant.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, SCEVUse LHS, SCEVUse RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
LLVM_ABI bool properlyDominates(const SCEV *S, const BasicBlock *BB)
Return true if elements that makes up the given SCEV properly dominate the specified basic block.
LLVM_ABI const SCEV * getNegativeSCEV(const SCEV *V, SCEVFlags Flags=SCEV::FlagNone)
Return the SCEV object corresponding to -V.
LLVM_ABI bool canReuseInstruction(const SCEV *S, Instruction *I, SmallVectorImpl< Instruction * > &DropPoisonGeneratingInsts)
Check whether it is poison-safe to represent the expression S using the instruction I.
LLVM_ABI bool isKnownPredicateAt(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM_ABI int getFPMantissaWidth() const
Return the width of the mantissa of this type.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_Value()
Match an arbitrary value and ignore it.
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
OverflowingBinaryOp_match< LHS, RHS, Instruction::Add, OverflowingBinaryOperator::NoSignedWrap > m_NSWAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
@ User
could "use" a pointer
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
LLVM_ABI std::optional< unsigned > getLoopEstimatedTripCount(Loop *L, unsigned *EstimatedLoopInvocationWeight=nullptr)
Return either:
@ Unknown
Not known to have no common set bits.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ BinaryOp
One of the operands is a binary op.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI PHINode * createWideIV(const WideIVInfo &WI, LoopInfo *LI, ScalarEvolution *SE, SCEVExpander &Rewriter, DominatorTree *DT, SmallVectorImpl< WeakTrackingVH > &DeadInsts, unsigned &NumElimExt, unsigned &NumWidened, bool HasGuards, bool UsePostIncrementRanges)
Widen Induction Variables - Extend the width of an IV to cover its widest uses.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool impliesPoison(const Value *ValAssumedPoison, const Value *V)
Return true if V is poison given that ValAssumedPoison is already poison.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI cl::opt< unsigned > SCEVCheapExpansionBudget
LLVM_ABI bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT, LoopInfo *LI, const TargetTransformInfo *TTI, SmallVectorImpl< WeakTrackingVH > &Dead)
SimplifyLoopIVs - Simplify users of induction variables within this loop.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool replaceAllDbgUsesWith(Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT)
Point debug users of From to To or salvage them.
LLVM_ABI std::pair< bool, bool > simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT, LoopInfo *LI, const TargetTransformInfo *TTI, SmallVectorImpl< WeakTrackingVH > &Dead, SCEVExpander &Rewriter, IVVisitor *V=nullptr)
simplifyUsersOfIV - Simplify instructions that use this induction variable by using ScalarEvolution t...
DWARFExpression::Operation Op
constexpr unsigned BitWidth
LLVM_ABI bool formLCSSAForInstructions(SmallVectorImpl< Instruction * > &Worklist, const DominatorTree &DT, const LoopInfo &LI, ScalarEvolution *SE, SmallVectorImpl< PHINode * > *PHIsToRemove=nullptr, SmallVectorImpl< PHINode * > *InsertedPHIs=nullptr)
Ensures LCSSA form for every instruction from the Worklist in the scope of innermost containing loop.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Collect information about induction variables that are used by sign/zero extend operations.