34#define DEBUG_TYPE "indvars"
36STATISTIC(NumElimIdentity,
"Number of IV identities eliminated");
37STATISTIC(NumElimOperand,
"Number of IV operands folded into a use");
38STATISTIC(NumFoldedUser,
"Number of IV users folded into a constant");
39STATISTIC(NumElimRem ,
"Number of IV remainder operations eliminated");
42 "Number of IV signed division operations converted to unsigned division");
45 "Number of IV signed remainder operations converted to unsigned remainder");
46STATISTIC(NumElimCmp,
"Number of IV comparisons eliminated");
47STATISTIC(NumInvariantCmp,
"Number of IV comparisons made loop invariant");
48STATISTIC(NumSameSign,
"Number of IV comparisons with new samesign flags");
55 class SimplifyIndvar {
65 bool RunUnswitching =
false;
72 : L(
Loop), LI(LI), SE(SE), DT(DT),
TTI(
TTI), Rewriter(Rewriter),
74 assert(LI &&
"IV simplification requires LoopInfo");
77 bool hasChanged()
const {
return Changed; }
78 bool runUnswitching()
const {
return RunUnswitching; }
83 void simplifyUsers(PHINode *CurrIV, IVVisitor *V =
nullptr);
85 void pushIVUsers(Instruction *Def,
86 SmallPtrSet<Instruction *, 16> &Simplified,
87 SmallVectorImpl<std::pair<Instruction *, Instruction *>>
90 Value *foldIVUser(Instruction *UseInst, Instruction *IVOperand);
92 bool eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand);
93 bool replaceIVUserWithLoopInvariant(Instruction *UseInst);
94 bool replaceFloatIVWithIntegerIV(Instruction *UseInst);
96 bool eliminateOverflowIntrinsic(WithOverflowInst *WO);
97 bool eliminateSaturatingIntrinsic(SaturatingInst *SI);
98 bool eliminateTrunc(TruncInst *TI);
99 bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand);
100 bool makeIVComparisonInvariant(ICmpInst *ICmp, Instruction *IVOperand);
101 void eliminateIVComparison(ICmpInst *ICmp, Instruction *IVOperand);
102 void simplifyIVRemainder(BinaryOperator *Rem, Instruction *IVOperand,
104 void replaceRemWithNumerator(BinaryOperator *Rem);
105 void replaceRemWithNumeratorOrZero(BinaryOperator *Rem);
106 void replaceSRemWithURem(BinaryOperator *Rem);
107 bool eliminateSDiv(BinaryOperator *SDiv);
108 bool strengthenBinaryOp(BinaryOperator *BO, Instruction *IVOperand);
109 bool strengthenOverflowingOperation(BinaryOperator *OBO,
110 Instruction *IVOperand);
111 bool strengthenRightShift(BinaryOperator *BO, Instruction *IVOperand);
121 for (
auto *Insn : Instructions)
124 assert(CommonDom &&
"Common dominator not found?");
137 Value *IVSrc =
nullptr;
138 const unsigned OperIdx = 0;
139 const SCEV *FoldedExpr =
nullptr;
140 bool MustDropExactFlag =
false;
144 case Instruction::UDiv:
145 case Instruction::LShr:
148 if (IVOperand != UseInst->
getOperand(OperIdx) ||
163 if (UseInst->
getOpcode() == Instruction::LShr) {
178 MustDropExactFlag =
true;
185 if (SE->
getSCEV(UseInst) != FoldedExpr)
188 LLVM_DEBUG(
dbgs() <<
"INDVARS: Eliminated IV operand: " << *IVOperand
189 <<
" -> " << *UseInst <<
'\n');
192 assert(SE->
getSCEV(UseInst) == FoldedExpr &&
"bad SCEV with folded oper");
194 if (MustDropExactFlag)
200 DeadInsts.emplace_back(IVOperand);
204bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp,
205 Instruction *IVOperand) {
209 unsigned IVOperIdx = 0;
226 ICmpInst::Predicate InvariantPredicate = LIP->Pred;
227 const SCEV *InvariantLHS = LIP->LHS;
228 const SCEV *InvariantRHS = LIP->RHS;
231 auto *PHTerm = Preheader->getTerminator();
232 if (
Rewriter.isHighCostExpansion({InvariantLHS, InvariantRHS}, L,
234 !
Rewriter.isSafeToExpandAt(InvariantLHS, PHTerm) ||
235 !
Rewriter.isSafeToExpandAt(InvariantRHS, PHTerm))
241 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified comparison: " << *ICmp <<
'\n');
245 RunUnswitching =
true;
251void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp,
252 Instruction *IVOperand) {
253 unsigned IVOperIdx = 0;
255 ICmpInst::Predicate OriginalPred = Pred;
271 SmallVector<Instruction *, 4>
Users;
272 for (
auto *U : ICmp->
users())
278 DeadInsts.emplace_back(ICmp);
279 LLVM_DEBUG(
dbgs() <<
"INDVARS: Eliminated comparison: " << *ICmp <<
'\n');
285 if (makeIVComparisonInvariant(ICmp, IVOperand)) {
291 if ((ICmpInst::isSigned(OriginalPred) ||
292 (ICmpInst::isUnsigned(OriginalPred) && !ICmp->
hasSameSign())) &&
299 LLVM_DEBUG(
dbgs() <<
"INDVARS: Marking comparison samesign: " << *ICmp
309bool SimplifyIndvar::eliminateSDiv(BinaryOperator *SDiv) {
324 UDiv->setIsExact(SDiv->
isExact());
327 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified sdiv: " << *SDiv <<
'\n');
330 DeadInsts.push_back(SDiv);
338void SimplifyIndvar::replaceSRemWithURem(BinaryOperator *Rem) {
344 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified srem: " << *Rem <<
'\n');
347 DeadInsts.emplace_back(Rem);
351void SimplifyIndvar::replaceRemWithNumerator(BinaryOperator *Rem) {
353 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified rem: " << *Rem <<
'\n');
356 DeadInsts.emplace_back(Rem);
360void SimplifyIndvar::replaceRemWithNumeratorOrZero(BinaryOperator *Rem) {
363 ICmpInst *ICmp =
new ICmpInst(Rem->
getIterator(), ICmpInst::ICMP_EQ,
N,
D);
369 LLVM_DEBUG(
dbgs() <<
"INDVARS: Simplified rem: " << *Rem <<
'\n');
372 DeadInsts.emplace_back(Rem);
377void SimplifyIndvar::simplifyIVRemainder(BinaryOperator *Rem,
378 Instruction *IVOperand,
385 bool UsedAsNumerator = IVOperand == NValue;
386 if (!UsedAsNumerator && !IsSigned)
389 const SCEV *
N = SE->
getSCEV(NValue);
398 if (!IsNumeratorNonNegative)
401 const SCEV *
D = SE->
getSCEV(DValue);
404 if (UsedAsNumerator) {
405 auto LT = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
407 replaceRemWithNumerator(Rem);
414 replaceRemWithNumeratorOrZero(Rem);
424 replaceSRemWithURem(Rem);
427bool SimplifyIndvar::eliminateOverflowIntrinsic(WithOverflowInst *WO) {
446 for (
auto *U : WO->
users()) {
448 if (EVI->getIndices()[0] == 1)
451 assert(EVI->getIndices()[0] == 0 &&
"Only two possibilities!");
452 EVI->replaceAllUsesWith(NewResult);
459 for (
auto *EVI : ToDelete)
460 EVI->eraseFromParent();
469bool SimplifyIndvar::eliminateSaturatingIntrinsic(SaturatingInst *SI) {
476 SI->getBinaryOp(),
SI->getLHS(),
SI->getRHS(),
SI->getName(),
SI->getIterator());
482 SI->replaceAllUsesWith(BO);
484 DeadInsts.emplace_back(SI);
489bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) {
507 Type *IVTy =
IV->getType();
509 const SCEV *TISCEV = SE->
getSCEV(TI);
513 bool DoesSExtCollapse =
false;
514 bool DoesZExtCollapse =
false;
516 DoesSExtCollapse =
true;
518 DoesZExtCollapse =
true;
522 if (!DoesSExtCollapse && !DoesZExtCollapse)
528 for (
auto *U : TI->
users()) {
534 if (!ICI)
return false;
540 if (ICI->
isSigned() && !DoesSExtCollapse)
548 auto CanUseZExt = [&](ICmpInst *ICI) {
553 if (!DoesZExtCollapse)
567 for (
auto *ICI : ICmpUsers) {
568 bool IsSwapped =
L->isLoopInvariant(ICI->
getOperand(0));
571 Value *Ext =
nullptr;
579 if (IsSwapped) Pred = ICmpInst::getSwappedPredicate(Pred);
580 if (CanUseZExt(ICI)) {
581 assert(DoesZExtCollapse &&
"Unprofitable zext?");
582 Ext = Builder.CreateZExt(Op1, IVTy,
"zext");
585 assert(DoesSExtCollapse &&
"Unprofitable sext?");
586 Ext = Builder.CreateSExt(Op1, IVTy,
"sext");
592 auto *NewCmp = Builder.CreateICmp(Pred,
IV, Ext);
594 DeadInsts.emplace_back(ICI);
599 DeadInsts.emplace_back(TI);
606bool SimplifyIndvar::eliminateIVUser(Instruction *UseInst,
607 Instruction *IVOperand) {
609 eliminateIVComparison(ICmp, IVOperand);
613 bool IsSRem =
Bin->getOpcode() == Instruction::SRem;
614 if (IsSRem ||
Bin->getOpcode() == Instruction::URem) {
615 simplifyIVRemainder(
Bin, IVOperand, IsSRem);
619 if (
Bin->getOpcode() == Instruction::SDiv)
620 return eliminateSDiv(
Bin);
624 if (eliminateOverflowIntrinsic(WO))
628 if (eliminateSaturatingIntrinsic(SI))
632 if (eliminateTrunc(TI))
635 if (eliminateIdentitySCEV(UseInst, IVOperand))
642 if (
auto *BB = L->getLoopPreheader())
643 return BB->getTerminator();
649bool SimplifyIndvar::replaceIVUserWithLoopInvariant(Instruction *
I) {
665 if (!
Rewriter.isSafeToExpandAt(S, IP)) {
667 <<
" with non-speculable loop invariant: " << *S <<
'\n');
671 auto *Invariant =
Rewriter.expandCodeFor(S,
I->getType(), IP);
672 bool NeedToEmitLCSSAPhis =
false;
674 NeedToEmitLCSSAPhis =
true;
676 I->replaceAllUsesWith(Invariant);
678 <<
" with loop invariant: " << *S <<
'\n');
680 if (NeedToEmitLCSSAPhis) {
685 <<
" inserting LCSSA Phis" <<
'\n');
689 DeadInsts.emplace_back(
I);
694bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) {
695 if (UseInst->
getOpcode() != CastInst::SIToFP &&
696 UseInst->
getOpcode() != CastInst::UIToFP)
703 if (UseInst->
getOpcode() == CastInst::SIToFP)
708 if (MaskBits <= DestNumSigBits) {
709 for (User *U : UseInst->
users()) {
715 CastInst::CastOps Opcode = CI->getOpcode();
716 if (Opcode != CastInst::FPToSI && Opcode != CastInst::FPToUI)
719 Value *Conv =
nullptr;
720 if (IVOperand->
getType() != CI->getType()) {
727 Conv = Builder.CreateTrunc(IVOperand, CI->getType(), Name +
".trunc");
728 }
else if (Opcode == CastInst::FPToUI ||
729 UseInst->
getOpcode() == CastInst::UIToFP) {
730 Conv = Builder.CreateZExt(IVOperand, CI->getType(), Name +
".zext");
732 Conv = Builder.CreateSExt(IVOperand, CI->getType(), Name +
".sext");
738 DeadInsts.push_back(CI);
740 <<
" with: " << *Conv <<
'\n');
751bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
752 Instruction *IVOperand) {
757 const SCEV *UseSCEV = SE->
getSCEV(UseInst);
758 if (UseSCEV != SE->
getSCEV(IVOperand))
780 if (!DT || !DT->
dominates(IVOperand, UseInst))
792 for (Instruction *
I : DropPoisonGeneratingInsts)
793 I->dropPoisonGeneratingAnnotations();
796 LLVM_DEBUG(
dbgs() <<
"INDVARS: Eliminated identity: " << *UseInst <<
'\n');
802 DeadInsts.emplace_back(UseInst);
806bool SimplifyIndvar::strengthenBinaryOp(BinaryOperator *BO,
807 Instruction *IVOperand) {
809 strengthenOverflowingOperation(BO, IVOperand)) ||
815bool SimplifyIndvar::strengthenOverflowingOperation(BinaryOperator *BO,
816 Instruction *IVOperand) {
839bool SimplifyIndvar::strengthenRightShift(BinaryOperator *BO,
840 Instruction *IVOperand) {
841 if (BO->
getOpcode() == Instruction::Shl) {
844 for (
auto *U : BO->
users()) {
864void SimplifyIndvar::pushIVUsers(
865 Instruction *Def, SmallPtrSet<Instruction *, 16> &Simplified,
866 SmallVectorImpl<std::pair<Instruction *, Instruction *>> &SimpleIVUsers) {
867 for (User *U :
Def->users()) {
879 if (!
L->contains(UI))
886 SimpleIVUsers.push_back(std::make_pair(UI, Def));
923void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
936 pushIVUsers(CurrIV, Simplified, SimpleIVUsers);
938 while (!SimpleIVUsers.
empty()) {
939 std::pair<Instruction*, Instruction*> UseOper =
948 DeadInsts.emplace_back(UseInst);
953 if (UseInst == CurrIV)
continue;
957 if (replaceIVUserWithLoopInvariant(UseInst))
963 for (Use &U : UseInst->
uses()) {
965 if (replaceIVUserWithLoopInvariant(User))
970 for (
unsigned N = 0; IVOperand; ++
N) {
974 Value *NewOper = foldIVUser(UseInst, IVOperand);
982 if (eliminateIVUser(UseInst, IVOperand)) {
983 pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
988 if (strengthenBinaryOp(BO, IVOperand)) {
991 pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
996 if (replaceFloatIVWithIntegerIV(UseInst)) {
998 pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
1008 pushIVUsers(UseInst, Simplified, SimpleIVUsers);
1029 SIV.simplifyUsers(CurrIV, V);
1030 return {SIV.hasChanged(), SIV.runUnswitching()};
1039#if LLVM_ENABLE_ABI_BREAKING_CHECKS
1044 const auto &[
C,
_] =
1067 ScalarEvolution *SE;
1077 unsigned NumElimExt = 0;
1078 unsigned NumWidened = 0;
1081 PHINode *WidePhi =
nullptr;
1083 const SCEV *WideIncExpr =
nullptr;
1084 SmallVectorImpl<WeakTrackingVH> &DeadInsts;
1086 SmallPtrSet<Instruction *,16> Widened;
1094 DenseMap<AssertingVH<Instruction>, ExtendKind> ExtendKindMap;
1096 using DefUserPair = std::pair<AssertingVH<Value>, AssertingVH<Instruction>>;
1102 DenseMap<DefUserPair, ConstantRange> PostIncRangeInfos;
1104 std::optional<ConstantRange> getPostIncRangeInfo(
Value *Def,
1105 Instruction *UseI) {
1106 DefUserPair
Key(Def, UseI);
1107 auto It = PostIncRangeInfos.
find(
Key);
1108 return It == PostIncRangeInfos.
end()
1109 ? std::optional<ConstantRange>(std::nullopt)
1110 : std::optional<ConstantRange>(It->second);
1113 void calculatePostIncRanges(PHINode *OrigPhi);
1114 void calculatePostIncRange(Instruction *NarrowDef, Instruction *NarrowUser);
1116 void updatePostIncRangeInfo(
Value *Def, Instruction *UseI, ConstantRange R) {
1117 DefUserPair
Key(Def, UseI);
1120 It->second =
R.intersectWith(It->second);
1127 struct NarrowIVDefUse {
1135 bool NeverNegative =
false;
1137 NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD,
1139 : NarrowDef(ND), NarrowUse(NU), WideDef(WD),
1140 NeverNegative(NeverNegative) {}
1143 WidenIV(
const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
1144 DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
1149 unsigned getNumElimExt() {
return NumElimExt; };
1150 unsigned getNumWidened() {
return NumWidened; };
1153 Value *createExtendInst(
Value *NarrowOper,
Type *WideType,
bool IsSigned,
1156 Instruction *cloneIVUser(NarrowIVDefUse DU,
const SCEVAddRecExpr *WideAR);
1157 Instruction *cloneArithmeticIVUser(NarrowIVDefUse DU,
1158 const SCEVAddRecExpr *WideAR);
1159 Instruction *cloneBitwiseIVUser(NarrowIVDefUse DU);
1161 ExtendKind getExtendKind(Instruction *
I);
1163 using WidenedRecTy = std::pair<const SCEVAddRecExpr *, ExtendKind>;
1165 WidenedRecTy getWideRecurrence(NarrowIVDefUse DU);
1167 WidenedRecTy getExtendedOperandRecurrence(NarrowIVDefUse DU);
1169 const SCEV *getSCEVByOpCode(
const SCEV *
LHS,
const SCEV *
RHS,
1170 unsigned OpCode)
const;
1173 PHINode *OrigPhi, PHINode *WidePhi);
1174 void truncateIVUse(NarrowIVDefUse DU);
1176 bool widenLoopCompare(NarrowIVDefUse DU);
1177 bool widenWithVariantUse(NarrowIVDefUse DU);
1179 void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
1199 for (
unsigned i = 0, e =
PHI->getNumIncomingValues(); i != e; ++i) {
1200 if (
PHI->getIncomingValue(i) != Def)
1225 assert(DT->
dominates(DefI, InsertPt) &&
"def does not dominate all uses");
1230 for (
auto *DTN = (*DT)[InsertPt->
getParent()]; DTN; DTN = DTN->getIDom())
1232 return DTN->getBlock()->getTerminator();
1240 : OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), LI(LInfo),
1241 L(LI->getLoopFor(OrigPhi->
getParent())), SE(SEv), DT(DTree),
1244 assert(L->getHeader() == OrigPhi->
getParent() &&
"Phi must be an IV");
1245 ExtendKindMap[OrigPhi] = WI.
IsSigned ? ExtendKind::Sign : ExtendKind::Zero;
1248Value *WidenIV::createExtendInst(
Value *NarrowOper,
Type *WideType,
1254 L &&
L->getLoopPreheader() &&
L->isLoopInvariant(NarrowOper);
1255 L =
L->getParentLoop())
1256 Builder.SetInsertPoint(
L->getLoopPreheader()->getTerminator());
1258 return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) :
1259 Builder.CreateZExt(NarrowOper, WideType);
1265Instruction *WidenIV::cloneIVUser(WidenIV::NarrowIVDefUse DU,
1266 const SCEVAddRecExpr *WideAR) {
1267 unsigned Opcode = DU.NarrowUse->
getOpcode();
1271 case Instruction::Add:
1272 case Instruction::Mul:
1273 case Instruction::UDiv:
1274 case Instruction::Sub:
1275 return cloneArithmeticIVUser(DU, WideAR);
1277 case Instruction::And:
1278 case Instruction::Or:
1279 case Instruction::Xor:
1280 case Instruction::Shl:
1281 case Instruction::LShr:
1282 case Instruction::AShr:
1283 return cloneBitwiseIVUser(DU);
1287Instruction *WidenIV::cloneBitwiseIVUser(WidenIV::NarrowIVDefUse DU) {
1292 LLVM_DEBUG(
dbgs() <<
"Cloning bitwise IVUser: " << *NarrowUse <<
"\n");
1298 bool IsSigned = getExtendKind(NarrowDef) == ExtendKind::Sign;
1301 : createExtendInst(NarrowUse->
getOperand(0), WideType,
1302 IsSigned, NarrowUse);
1305 : createExtendInst(NarrowUse->
getOperand(1), WideType,
1306 IsSigned, NarrowUse);
1312 Builder.Insert(WideBO);
1313 WideBO->copyIRFlags(NarrowBO);
1317Instruction *WidenIV::cloneArithmeticIVUser(WidenIV::NarrowIVDefUse DU,
1318 const SCEVAddRecExpr *WideAR) {
1323 LLVM_DEBUG(
dbgs() <<
"Cloning arithmetic IVUser: " << *NarrowUse <<
"\n");
1325 unsigned IVOpIdx = (NarrowUse->
getOperand(0) == NarrowDef) ? 0 : 1;
1336 auto GuessNonIVOperand = [&](
bool SignExt) {
1337 const SCEV *WideLHS;
1338 const SCEV *WideRHS;
1340 auto GetExtend = [
this, SignExt](
const SCEV *S,
Type *Ty) {
1347 WideLHS = SE->
getSCEV(WideDef);
1349 WideRHS = GetExtend(NarrowRHS, WideType);
1352 WideLHS = GetExtend(NarrowLHS, WideType);
1353 WideRHS = SE->
getSCEV(WideDef);
1357 const SCEV *WideUse =
1358 getSCEVByOpCode(WideLHS, WideRHS, NarrowUse->
getOpcode());
1360 return WideUse == WideAR;
1363 bool SignExtend = getExtendKind(NarrowDef) == ExtendKind::Sign;
1364 if (!GuessNonIVOperand(SignExtend)) {
1365 SignExtend = !SignExtend;
1366 if (!GuessNonIVOperand(SignExtend))
1372 : createExtendInst(NarrowUse->
getOperand(0), WideType,
1373 SignExtend, NarrowUse);
1376 : createExtendInst(NarrowUse->
getOperand(1), WideType,
1377 SignExtend, NarrowUse);
1384 Builder.Insert(WideBO);
1385 WideBO->copyIRFlags(NarrowBO);
1389WidenIV::ExtendKind WidenIV::getExtendKind(Instruction *
I) {
1390 auto It = ExtendKindMap.
find(
I);
1391 assert(It != ExtendKindMap.
end() &&
"Instruction not yet extended!");
1395const SCEV *WidenIV::getSCEVByOpCode(
const SCEV *
LHS,
const SCEV *
RHS,
1396 unsigned OpCode)
const {
1398 case Instruction::Add:
1400 case Instruction::Sub:
1402 case Instruction::Mul:
1404 case Instruction::UDiv:
1418 std::array<Value *, 2> Operands;
1422 explicit BinaryOp(Instruction *
Op)
1424 Operands({
Op->getOperand(0),
Op->getOperand(1)}) {
1426 IsNSW = OBO->hasNoSignedWrap();
1427 IsNUW = OBO->hasNoUnsignedWrap();
1432 bool IsNSW =
false,
bool IsNUW =
false)
1433 : Opcode(Opcode), Operands({
LHS,
RHS}), IsNSW(IsNSW), IsNUW(IsNUW) {}
1439 switch (
Op->getOpcode()) {
1440 case Instruction::Add:
1441 case Instruction::Sub:
1442 case Instruction::Mul:
1443 return BinaryOp(
Op);
1444 case Instruction::Or: {
1447 return BinaryOp(Instruction::Add,
Op->getOperand(0),
Op->getOperand(1),
1451 case Instruction::Shl: {
1459 if (SA->getValue().ult(
BitWidth)) {
1464 bool IsNUW =
Op->hasNoUnsignedWrap();
1465 bool IsNSW =
Op->hasNoSignedWrap() &&
1466 (IsNUW || SA->getValue().ult(
BitWidth - 1));
1469 ConstantInt::get(
Op->getContext(),
1471 return BinaryOp(Instruction::Mul,
Op->getOperand(0),
X, IsNSW, IsNUW);
1479 return std::nullopt;
1487WidenIV::WidenedRecTy
1488WidenIV::getExtendedOperandRecurrence(WidenIV::NarrowIVDefUse DU) {
1491 return {
nullptr, ExtendKind::Unknown};
1493 assert((
Op->Opcode == Instruction::Add ||
Op->Opcode == Instruction::Sub ||
1494 Op->Opcode == Instruction::Mul) &&
1495 "Unexpected opcode");
1499 const unsigned ExtendOperIdx =
Op->Operands[0] == DU.NarrowDef ? 1 : 0;
1500 assert(
Op->Operands[1 - ExtendOperIdx] == DU.NarrowDef &&
"bad DU");
1502 ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
1503 if (!(ExtKind == ExtendKind::Sign &&
Op->IsNSW) &&
1504 !(ExtKind == ExtendKind::Zero &&
Op->IsNUW)) {
1505 ExtKind = ExtendKind::Unknown;
1511 if (DU.NeverNegative) {
1513 ExtKind = ExtendKind::Sign;
1514 }
else if (
Op->IsNUW) {
1515 ExtKind = ExtendKind::Zero;
1520 const SCEV *ExtendOperExpr = SE->
getSCEV(
Op->Operands[ExtendOperIdx]);
1521 if (ExtKind == ExtendKind::Sign)
1523 else if (ExtKind == ExtendKind::Zero)
1526 return {
nullptr, ExtendKind::Unknown};
1533 const SCEV *lhs = SE->
getSCEV(DU.WideDef);
1534 const SCEV *rhs = ExtendOperExpr;
1538 if (ExtendOperIdx == 0)
1540 const SCEVAddRecExpr *AddRec =
1543 if (!AddRec || AddRec->
getLoop() != L)
1544 return {
nullptr, ExtendKind::Unknown};
1546 return {AddRec, ExtKind};
1554WidenIV::WidenedRecTy WidenIV::getWideRecurrence(WidenIV::NarrowIVDefUse DU) {
1556 return {
nullptr, ExtendKind::Unknown};
1558 const SCEV *NarrowExpr = SE->
getSCEV(DU.NarrowUse);
1563 return {
nullptr, ExtendKind::Unknown};
1566 const SCEV *WideExpr;
1568 if (DU.NeverNegative) {
1571 ExtKind = ExtendKind::Sign;
1574 ExtKind = ExtendKind::Zero;
1576 }
else if (getExtendKind(DU.NarrowDef) == ExtendKind::Sign) {
1578 ExtKind = ExtendKind::Sign;
1581 ExtKind = ExtendKind::Zero;
1584 if (!AddRec || AddRec->
getLoop() != L)
1585 return {
nullptr, ExtendKind::Unknown};
1586 return {AddRec, ExtKind};
1591void WidenIV::truncateIVUse(NarrowIVDefUse DU) {
1595 LLVM_DEBUG(
dbgs() <<
"INDVARS: Truncate IV " << *DU.WideDef <<
" for user "
1596 << *DU.NarrowUse <<
"\n");
1597 ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
1600 Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType(),
"",
1601 DU.NeverNegative || ExtKind == ExtendKind::Zero,
1602 DU.NeverNegative || ExtKind == ExtendKind::Sign);
1603 DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
1609bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
1628 bool IsSigned = getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
1629 bool CmpPreferredSign =
Cmp->hasSameSign() ? IsSigned :
Cmp->isSigned();
1630 if (!DU.NeverNegative && IsSigned != CmpPreferredSign)
1633 Value *
Op =
Cmp->getOperand(
Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
1636 assert(CastWidth <= IVWidth &&
"Unexpected width while widening compare.");
1642 if (CastWidth < IVWidth) {
1647 CmpPreferredSign =
true;
1649 Value *ExtOp = createExtendInst(
Op, WideType, CmpPreferredSign, Cmp);
1675bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
1683 if (OpCode != Instruction::Add && OpCode != Instruction::Sub &&
1684 OpCode != Instruction::Mul)
1693 const OverflowingBinaryOperator *OBO =
1695 ExtendKind ExtKind = getExtendKind(NarrowDef);
1696 bool CanSignExtend = ExtKind == ExtendKind::Sign && OBO->
hasNoSignedWrap();
1698 auto AnotherOpExtKind = ExtKind;
1705 SmallVector<Instruction *, 4> ExtUsers;
1708 for (Use &U : NarrowUse->
uses()) {
1710 if (User == NarrowDef)
1712 if (!
L->contains(User)) {
1716 if (LCSSAPhi->getNumOperands() != 1)
1727 if (ExtKind == ExtendKind::Zero && ICmpInst::isSigned(Pred))
1729 if (ExtKind == ExtendKind::Sign && ICmpInst::isUnsigned(Pred))
1734 if (ExtKind == ExtendKind::Sign)
1738 if (!User ||
User->getType() != WideType)
1742 if (ExtUsers.
empty()) {
1752 if (!CanSignExtend && !CanZeroExtend) {
1755 if (OpCode != Instruction::Add)
1757 if (ExtKind != ExtendKind::Zero)
1775 AnotherOpExtKind = ExtendKind::Sign;
1779 const SCEV *Op1 = SE->
getSCEV(WideDef);
1781 if (!AddRecOp1 || AddRecOp1->
getLoop() != L)
1784 LLVM_DEBUG(
dbgs() <<
"Cloning arithmetic IVUser: " << *NarrowUse <<
"\n");
1790 : createExtendInst(NarrowUse->
getOperand(0), WideType,
1791 AnotherOpExtKind == ExtendKind::Sign, NarrowUse);
1795 : createExtendInst(NarrowUse->
getOperand(1), WideType,
1796 AnotherOpExtKind == ExtendKind::Sign, NarrowUse);
1802 Builder.Insert(WideBO);
1803 WideBO->copyIRFlags(NarrowBO);
1804 ExtendKindMap[NarrowUse] = ExtKind;
1806 for (Instruction *User : ExtUsers) {
1807 assert(
User->getType() == WideType &&
"Checked before!");
1808 LLVM_DEBUG(
dbgs() <<
"INDVARS: eliminating " << *User <<
" replaced by "
1809 << *WideBO <<
"\n");
1811 User->replaceAllUsesWith(WideBO);
1815 for (PHINode *User : LCSSAPhiUsers) {
1816 assert(
User->getNumOperands() == 1 &&
"Checked before!");
1817 Builder.SetInsertPoint(User);
1819 Builder.CreatePHI(WideBO->getType(), 1,
User->getName() +
".wide");
1820 BasicBlock *LoopExitingBlock =
User->getParent()->getSinglePredecessor();
1821 assert(LoopExitingBlock &&
L->contains(LoopExitingBlock) &&
1822 "Not a LCSSA Phi?");
1823 WidePN->addIncoming(WideBO, LoopExitingBlock);
1824 Builder.SetInsertPoint(
User->getParent(),
1825 User->getParent()->getFirstInsertionPt());
1826 auto *TruncPN = Builder.CreateTrunc(WidePN,
User->getType());
1827 User->replaceAllUsesWith(TruncPN);
1831 for (ICmpInst *User : ICmpUsers) {
1832 Builder.SetInsertPoint(User);
1836 if (ExtKind == ExtendKind::Zero)
1837 return Builder.CreateZExt(V, WideBO->getType());
1839 return Builder.CreateSExt(V, WideBO->getType());
1841 auto Pred =
User->getPredicate();
1842 auto *
LHS = ExtendedOp(
User->getOperand(0));
1843 auto *
RHS = ExtendedOp(
User->getOperand(1));
1845 Builder.CreateICmp(Pred,
LHS,
RHS,
User->getName() +
".wide");
1846 User->replaceAllUsesWith(WideCmp);
1855Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
1856 SCEVExpander &
Rewriter, PHINode *OrigPhi,
1859 "Should already know the kind of extension used to widen NarrowDef");
1863 bool CanWidenBySExt =
1864 DU.NeverNegative || getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
1865 bool CanWidenByZExt =
1866 DU.NeverNegative || getExtendKind(DU.NarrowDef) == ExtendKind::Zero;
1870 if (LI->
getLoopFor(UsePhi->getParent()) != L) {
1874 if (UsePhi->getNumOperands() != 1)
1885 UsePhi->getIterator());
1886 WidePhi->
addIncoming(DU.WideDef, UsePhi->getIncomingBlock(0));
1889 Value *Trunc = Builder.CreateTrunc(WidePhi, DU.NarrowDef->
getType(),
"",
1890 CanWidenByZExt, CanWidenBySExt);
1893 LLVM_DEBUG(
dbgs() <<
"INDVARS: Widen lcssa phi " << *UsePhi <<
" to "
1894 << *WidePhi <<
"\n");
1903 Value *NewDef = DU.WideDef;
1904 if (DU.NarrowUse->
getType() != WideType) {
1907 if (CastWidth < IVWidth) {
1910 NewDef = Builder.CreateTrunc(DU.WideDef, DU.NarrowUse->
getType(),
"",
1911 CanWidenByZExt, CanWidenBySExt);
1918 <<
" not wide enough to subsume " << *DU.NarrowUse
1921 NewDef = DU.NarrowUse;
1924 if (NewDef != DU.NarrowUse) {
1926 <<
" replaced by " << *DU.WideDef <<
"\n");
1941 auto tryAddRecExpansion = [&]() -> Instruction* {
1943 WidenedRecTy WideAddRec = getExtendedOperandRecurrence(DU);
1944 if (!WideAddRec.first)
1945 WideAddRec = getWideRecurrence(DU);
1946 assert((WideAddRec.first ==
nullptr) ==
1947 (WideAddRec.second == ExtendKind::Unknown));
1948 if (!WideAddRec.first)
1951 auto CanUseWideInc = [&]() {
1958 bool NeedToRecomputeFlags =
1960 OrigPhi, WidePhi, DU.NarrowUse, WideInc) ||
1963 return WideAddRec.first == WideIncExpr &&
1964 Rewriter.hoistIVInc(WideInc, DU.NarrowUse, NeedToRecomputeFlags);
1968 if (CanUseWideInc())
1971 WideUse = cloneIVUser(DU, WideAddRec.first);
1980 if (WideAddRec.first != SE->
getSCEV(WideUse)) {
1981 LLVM_DEBUG(
dbgs() <<
"Wide use expression mismatch: " << *WideUse <<
": "
1982 << *SE->
getSCEV(WideUse) <<
" != " << *WideAddRec.first
1992 ExtendKindMap[DU.NarrowUse] = WideAddRec.second;
1997 if (
auto *
I = tryAddRecExpansion())
2002 if (widenLoopCompare(DU))
2010 if (widenWithVariantUse(DU))
2021void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
2022 const SCEV *NarrowSCEV = SE->
getSCEV(NarrowDef);
2023 bool NonNegativeDef =
2026 for (User *U : NarrowDef->
users()) {
2030 if (!Widened.
insert(NarrowUser).second)
2033 bool NonNegativeUse =
false;
2034 if (!NonNegativeDef) {
2036 if (
auto RangeInfo = getPostIncRangeInfo(NarrowDef, NarrowUser))
2037 NonNegativeUse = RangeInfo->getSignedMin().isNonNegative();
2040 NarrowIVUsers.emplace_back(NarrowDef, NarrowUser, WideDef,
2041 NonNegativeDef || NonNegativeUse);
2053PHINode *WidenIV::createWideIV(SCEVExpander &
Rewriter) {
2060 const SCEV *WideIVExpr = getExtendKind(OrigPhi) == ExtendKind::Sign
2065 "Expect the new IV expression to preserve its type");
2069 if (!AddRec || AddRec->
getLoop() != L)
2078 "Loop header phi recurrence inputs do not dominate the loop");
2091 calculatePostIncRanges(OrigPhi);
2097 Instruction *InsertPt = &*
L->getHeader()->getFirstInsertionPt();
2098 Value *ExpandInst =
Rewriter.expandCodeFor(AddRec, WideType, InsertPt);
2115 if (BasicBlock *LatchBlock =
L->getLoopLatch()) {
2119 WideIncExpr = SE->
getSCEV(WideInc);
2136 OrigInc, WideInc) &&
2140 OrigInc->hasNoUnsignedWrap());
2142 OrigInc->hasNoSignedWrap());
2151 assert(Widened.
empty() && NarrowIVUsers.empty() &&
"expect initial state" );
2154 pushNarrowIVUsers(OrigPhi, WidePhi);
2156 while (!NarrowIVUsers.empty()) {
2157 WidenIV::NarrowIVDefUse DU = NarrowIVUsers.pop_back_val();
2165 pushNarrowIVUsers(DU.NarrowUse, WideUse);
2180void WidenIV::calculatePostIncRange(Instruction *NarrowDef,
2181 Instruction *NarrowUser) {
2182 Value *NarrowDefLHS;
2183 const APInt *NarrowDefRHS;
2189 auto UpdateRangeFromCondition = [&](
Value *Condition,
bool TrueDest) {
2199 auto CmpConstrainedLHSRange =
2201 auto NarrowDefRange = CmpConstrainedLHSRange.addWithNoWrap(
2204 updatePostIncRangeInfo(NarrowDef, NarrowUser, NarrowDefRange);
2207 auto UpdateRangeFromGuards = [&](
Instruction *Ctx) {
2211 for (Instruction &
I :
make_range(Ctx->getIterator().getReverse(),
2212 Ctx->getParent()->rend())) {
2215 UpdateRangeFromCondition(
C,
true);
2219 UpdateRangeFromGuards(NarrowUser);
2227 for (
auto *DTB = (*DT)[NarrowUserBB]->getIDom();
2228 L->contains(DTB->getBlock());
2229 DTB = DTB->getIDom()) {
2230 auto *BB = DTB->getBlock();
2231 auto *TI = BB->getTerminator();
2232 UpdateRangeFromGuards(TI);
2235 if (!BI || !BI->isConditional())
2238 auto *TrueSuccessor = BI->getSuccessor(0);
2239 auto *FalseSuccessor = BI->getSuccessor(1);
2241 auto DominatesNarrowUser = [
this, NarrowUser] (BasicBlockEdge BBE) {
2242 return BBE.isSingleEdge() &&
2246 if (DominatesNarrowUser(BasicBlockEdge(BB, TrueSuccessor)))
2247 UpdateRangeFromCondition(BI->getCondition(),
true);
2249 if (DominatesNarrowUser(BasicBlockEdge(BB, FalseSuccessor)))
2250 UpdateRangeFromCondition(BI->getCondition(),
false);
2255void WidenIV::calculatePostIncRanges(PHINode *OrigPhi) {
2256 SmallPtrSet<Instruction *, 16> Visited;
2261 while (!Worklist.
empty()) {
2264 for (Use &U : NarrowDef->
uses()) {
2268 auto *NarrowUserLoop = (*LI)[NarrowUser->
getParent()];
2269 if (!NarrowUserLoop || !
L->contains(NarrowUserLoop))
2272 if (!Visited.
insert(NarrowUser).second)
2277 calculatePostIncRange(NarrowDef, NarrowUser);
2285 unsigned &NumElimExt,
unsigned &NumWidened,
2288 PHINode *WidePHI = Widener.createWideIV(Rewriter);
2289 NumElimExt = Widener.getNumElimExt();
2290 NumWidened = Widener.getNumWidened();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
iv Induction Variable Users
static cl::opt< bool > UsePostIncrementRanges("indvars-post-increment-ranges", cl::Hidden, cl::desc("Use post increment control-dependent ranges in IndVarSimplify"), cl::init(true))
static cl::opt< bool > WidenIV("loop-flatten-widen-iv", cl::Hidden, cl::init(true), cl::desc("Widen the loop induction variables, if possible, so " "overflow checks won't reject flattening"))
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)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
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.
ArrayRef - 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 if the block is well formed or null if the block is not well forme...
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.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
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 SCEV * getStart() const
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
const Loop * getLoop() const
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.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const DataLayout & getDataLayout() const
Return the DataLayout associated with the module this SCEV instance is operating on.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
LLVM_ABI bool isKnownNegative(const SCEV *S)
Test if the given expression is known to be negative.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
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 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.
LLVM_ABI const SCEV * getUDivExpr(const SCEV *LHS, const SCEV *RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI const SCEV * getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
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.
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 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 const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI std::optional< SCEV::NoWrapFlags > getStrengthenedNoWrapFlagsFromBinOp(const OverflowingBinaryOperator *OBO)
Parse NSW/NUW flags from add/sub/mul IR binary operation Op into SCEV no-wrap flags,...
LLVM_ABI const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, int Mask)
Convenient NoWrapFlags manipulation that hides enum casts and is visible in the ScalarEvolution name ...
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 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,...
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS)
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.
iterator_range< user_iterator > users()
LLVM_ABI 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.
@ C
The default llvm calling convention, compatible with C.
@ 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.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
match_combine_or< CastInst_match< OpTy, SExtInst >, NNegZExt_match< OpTy > > m_SExtLike(const OpTy &Op)
Match either "sext" or "zext nneg".
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
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.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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.
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.
LLVM_ABI cl::opt< unsigned > SCEVCheapExpansionBudget
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.
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...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
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.