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");
 
   53  class SimplifyIndvar {
 
   63    bool RunUnswitching = 
false;
 
   70        : L(
Loop), LI(LI), SE(SE), DT(DT), 
TTI(
TTI), Rewriter(Rewriter),
 
   72      assert(LI && 
"IV simplification requires LoopInfo");
 
   75    bool hasChanged()
 const { 
return Changed; }
 
   76    bool runUnswitching()
 const { 
return RunUnswitching; }
 
   81    void simplifyUsers(PHINode *CurrIV, IVVisitor *V = 
nullptr);
 
   83    void pushIVUsers(Instruction *Def,
 
   84                     SmallPtrSet<Instruction *, 16> &Simplified,
 
   85                     SmallVectorImpl<std::pair<Instruction *, Instruction *>>
 
   88    Value *foldIVUser(Instruction *UseInst, Instruction *IVOperand);
 
   90    bool eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand);
 
   91    bool replaceIVUserWithLoopInvariant(Instruction *UseInst);
 
   92    bool replaceFloatIVWithIntegerIV(Instruction *UseInst);
 
   94    bool eliminateOverflowIntrinsic(WithOverflowInst *WO);
 
   95    bool eliminateSaturatingIntrinsic(SaturatingInst *SI);
 
   96    bool eliminateTrunc(TruncInst *TI);
 
   97    bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand);
 
   98    bool makeIVComparisonInvariant(ICmpInst *ICmp, Instruction *IVOperand);
 
   99    void eliminateIVComparison(ICmpInst *ICmp, Instruction *IVOperand);
 
  100    void simplifyIVRemainder(BinaryOperator *Rem, Instruction *IVOperand,
 
  102    void replaceRemWithNumerator(BinaryOperator *Rem);
 
  103    void replaceRemWithNumeratorOrZero(BinaryOperator *Rem);
 
  104    void replaceSRemWithURem(BinaryOperator *Rem);
 
  105    bool eliminateSDiv(BinaryOperator *SDiv);
 
  106    bool strengthenBinaryOp(BinaryOperator *BO, Instruction *IVOperand);
 
  107    bool strengthenOverflowingOperation(BinaryOperator *OBO,
 
  108                                        Instruction *IVOperand);
 
  109    bool strengthenRightShift(BinaryOperator *BO, Instruction *IVOperand);
 
  119  for (
auto *Insn : Instructions)
 
  122  assert(CommonDom && 
"Common dominator not found?");
 
 
  135  Value *IVSrc = 
nullptr;
 
  136  const unsigned OperIdx = 0;
 
  137  const SCEV *FoldedExpr = 
nullptr;
 
  138  bool MustDropExactFlag = 
false;
 
  142  case Instruction::UDiv:
 
  143  case Instruction::LShr:
 
  146    if (IVOperand != UseInst->
getOperand(OperIdx) ||
 
  161    if (UseInst->
getOpcode() == Instruction::LShr) {
 
  176      MustDropExactFlag = 
true;
 
  183  if (SE->
getSCEV(UseInst) != FoldedExpr)
 
  186  LLVM_DEBUG(
dbgs() << 
"INDVARS: Eliminated IV operand: " << *IVOperand
 
  187                    << 
" -> " << *UseInst << 
'\n');
 
  190  assert(SE->
getSCEV(UseInst) == FoldedExpr && 
"bad SCEV with folded oper");
 
  192  if (MustDropExactFlag)
 
  198    DeadInsts.emplace_back(IVOperand);
 
  202bool SimplifyIndvar::makeIVComparisonInvariant(ICmpInst *ICmp,
 
  203                                               Instruction *IVOperand) {
 
  207  unsigned IVOperIdx = 0;
 
  224  ICmpInst::Predicate InvariantPredicate = LIP->Pred;
 
  225  const SCEV *InvariantLHS = LIP->LHS;
 
  226  const SCEV *InvariantRHS = LIP->RHS;
 
  229  auto *PHTerm = Preheader->getTerminator();
 
  230  if (
Rewriter.isHighCostExpansion({InvariantLHS, InvariantRHS}, L,
 
  232      !
Rewriter.isSafeToExpandAt(InvariantLHS, PHTerm) ||
 
  233      !
Rewriter.isSafeToExpandAt(InvariantRHS, PHTerm))
 
  239  LLVM_DEBUG(
dbgs() << 
"INDVARS: Simplified comparison: " << *ICmp << 
'\n');
 
  243  RunUnswitching = 
true;
 
  249void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp,
 
  250                                           Instruction *IVOperand) {
 
  251  unsigned IVOperIdx = 0;
 
  253  ICmpInst::Predicate OriginalPred = Pred;
 
  269  SmallVector<Instruction *, 4> 
Users;
 
  270  for (
auto *U : ICmp->
users())
 
  276    DeadInsts.emplace_back(ICmp);
 
  277    LLVM_DEBUG(
dbgs() << 
"INDVARS: Eliminated comparison: " << *ICmp << 
'\n');
 
  278  } 
else if (makeIVComparisonInvariant(ICmp, IVOperand)) {
 
  280  } 
else if (ICmpInst::isSigned(OriginalPred) &&
 
  288    LLVM_DEBUG(
dbgs() << 
"INDVARS: Turn to unsigned comparison: " << *ICmp
 
  299bool SimplifyIndvar::eliminateSDiv(BinaryOperator *SDiv) {
 
  314    UDiv->setIsExact(SDiv->
isExact());
 
  317    LLVM_DEBUG(
dbgs() << 
"INDVARS: Simplified sdiv: " << *SDiv << 
'\n');
 
  320    DeadInsts.push_back(SDiv);
 
  328void SimplifyIndvar::replaceSRemWithURem(BinaryOperator *Rem) {
 
  334  LLVM_DEBUG(
dbgs() << 
"INDVARS: Simplified srem: " << *Rem << 
'\n');
 
  337  DeadInsts.emplace_back(Rem);
 
  341void SimplifyIndvar::replaceRemWithNumerator(BinaryOperator *Rem) {
 
  343  LLVM_DEBUG(
dbgs() << 
"INDVARS: Simplified rem: " << *Rem << 
'\n');
 
  346  DeadInsts.emplace_back(Rem);
 
  350void SimplifyIndvar::replaceRemWithNumeratorOrZero(BinaryOperator *Rem) {
 
  353  ICmpInst *ICmp = 
new ICmpInst(Rem->
getIterator(), ICmpInst::ICMP_EQ, 
N, 
D);
 
  359  LLVM_DEBUG(
dbgs() << 
"INDVARS: Simplified rem: " << *Rem << 
'\n');
 
  362  DeadInsts.emplace_back(Rem);
 
  367void SimplifyIndvar::simplifyIVRemainder(BinaryOperator *Rem,
 
  368                                         Instruction *IVOperand,
 
  375  bool UsedAsNumerator = IVOperand == NValue;
 
  376  if (!UsedAsNumerator && !IsSigned)
 
  379  const SCEV *
N = SE->
getSCEV(NValue);
 
  388  if (!IsNumeratorNonNegative)
 
  391  const SCEV *
D = SE->
getSCEV(DValue);
 
  394  if (UsedAsNumerator) {
 
  395    auto LT = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
 
  397      replaceRemWithNumerator(Rem);
 
  404      replaceRemWithNumeratorOrZero(Rem);
 
  414  replaceSRemWithURem(Rem);
 
  417bool SimplifyIndvar::eliminateOverflowIntrinsic(WithOverflowInst *WO) {
 
  436  for (
auto *U : WO->
users()) {
 
  438      if (EVI->getIndices()[0] == 1)
 
  441        assert(EVI->getIndices()[0] == 0 && 
"Only two possibilities!");
 
  442        EVI->replaceAllUsesWith(NewResult);
 
  449  for (
auto *EVI : ToDelete)
 
  450    EVI->eraseFromParent();
 
  459bool SimplifyIndvar::eliminateSaturatingIntrinsic(SaturatingInst *SI) {
 
  466      SI->getBinaryOp(), 
SI->getLHS(), 
SI->getRHS(), 
SI->getName(), 
SI->getIterator());
 
  472  SI->replaceAllUsesWith(BO);
 
  474  DeadInsts.emplace_back(SI);
 
  479bool SimplifyIndvar::eliminateTrunc(TruncInst *TI) {
 
  497  Type *IVTy = 
IV->getType();
 
  499  const SCEV *TISCEV = SE->
getSCEV(TI);
 
  503  bool DoesSExtCollapse = 
false;
 
  504  bool DoesZExtCollapse = 
false;
 
  506    DoesSExtCollapse = 
true;
 
  508    DoesZExtCollapse = 
true;
 
  512  if (!DoesSExtCollapse && !DoesZExtCollapse)
 
  518  for (
auto *U : TI->
users()) {
 
  524    if (!ICI) 
return false;
 
  530    if (ICI->
isSigned() && !DoesSExtCollapse)
 
  538  auto CanUseZExt = [&](ICmpInst *ICI) {
 
  543    if (!DoesZExtCollapse)
 
  557  for (
auto *ICI : ICmpUsers) {
 
  558    bool IsSwapped = 
L->isLoopInvariant(ICI->
getOperand(0));
 
  569    if (IsSwapped) Pred = ICmpInst::getSwappedPredicate(Pred);
 
  570    if (CanUseZExt(ICI)) {
 
  571      assert(DoesZExtCollapse && 
"Unprofitable zext?");
 
  572      Ext = Builder.CreateZExt(Op1, IVTy, 
"zext");
 
  575      assert(DoesSExtCollapse && 
"Unprofitable sext?");
 
  576      Ext = Builder.CreateSExt(Op1, IVTy, 
"sext");
 
  582    auto *NewCmp = Builder.CreateICmp(Pred, 
IV, Ext);
 
  584    DeadInsts.emplace_back(ICI);
 
  589  DeadInsts.emplace_back(TI);
 
  596bool SimplifyIndvar::eliminateIVUser(Instruction *UseInst,
 
  597                                     Instruction *IVOperand) {
 
  599    eliminateIVComparison(ICmp, IVOperand);
 
  603    bool IsSRem = 
Bin->getOpcode() == Instruction::SRem;
 
  604    if (IsSRem || 
Bin->getOpcode() == Instruction::URem) {
 
  605      simplifyIVRemainder(
Bin, IVOperand, IsSRem);
 
  609    if (
Bin->getOpcode() == Instruction::SDiv)
 
  610      return eliminateSDiv(
Bin);
 
  614    if (eliminateOverflowIntrinsic(WO))
 
  618    if (eliminateSaturatingIntrinsic(SI))
 
  622    if (eliminateTrunc(TI))
 
  625  if (eliminateIdentitySCEV(UseInst, IVOperand))
 
  632  if (
auto *BB = L->getLoopPreheader())
 
  633    return BB->getTerminator();
 
 
  639bool SimplifyIndvar::replaceIVUserWithLoopInvariant(Instruction *
I) {
 
  655  if (!
Rewriter.isSafeToExpandAt(S, IP)) {
 
  657                      << 
" with non-speculable loop invariant: " << *S << 
'\n');
 
  661  auto *Invariant = 
Rewriter.expandCodeFor(S, 
I->getType(), IP);
 
  662  bool NeedToEmitLCSSAPhis = 
false;
 
  664    NeedToEmitLCSSAPhis = 
true;
 
  666  I->replaceAllUsesWith(Invariant);
 
  668                    << 
" with loop invariant: " << *S << 
'\n');
 
  670  if (NeedToEmitLCSSAPhis) {
 
  675                      << 
" inserting LCSSA Phis" << 
'\n');
 
  679  DeadInsts.emplace_back(
I);
 
  684bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) {
 
  685  if (UseInst->
getOpcode() != CastInst::SIToFP &&
 
  686      UseInst->
getOpcode() != CastInst::UIToFP)
 
  693  if (UseInst->
getOpcode() == CastInst::SIToFP)
 
  698  if (MaskBits <= DestNumSigBits) {
 
  699    for (User *U : UseInst->
users()) {
 
  705      CastInst::CastOps Opcode = CI->getOpcode();
 
  706      if (Opcode != CastInst::FPToSI && Opcode != CastInst::FPToUI)
 
  709      Value *Conv = 
nullptr;
 
  710      if (IVOperand->
getType() != CI->getType()) {
 
  717          Conv = Builder.CreateTrunc(IVOperand, CI->getType(), Name + 
".trunc");
 
  718        } 
else if (Opcode == CastInst::FPToUI ||
 
  719                   UseInst->
getOpcode() == CastInst::UIToFP) {
 
  720          Conv = Builder.CreateZExt(IVOperand, CI->getType(), Name + 
".zext");
 
  722          Conv = Builder.CreateSExt(IVOperand, CI->getType(), Name + 
".sext");
 
  728      DeadInsts.push_back(CI);
 
  730                        << 
" with: " << *Conv << 
'\n');
 
  741bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
 
  742                                           Instruction *IVOperand) {
 
  747  const SCEV *UseSCEV = SE->
getSCEV(UseInst);
 
  748  if (UseSCEV != SE->
getSCEV(IVOperand))
 
  770    if (!DT || !DT->
dominates(IVOperand, UseInst))
 
  782    for (Instruction *
I : DropPoisonGeneratingInsts)
 
  783      I->dropPoisonGeneratingAnnotations();
 
  786  LLVM_DEBUG(
dbgs() << 
"INDVARS: Eliminated identity: " << *UseInst << 
'\n');
 
  792  DeadInsts.emplace_back(UseInst);
 
  796bool SimplifyIndvar::strengthenBinaryOp(BinaryOperator *BO,
 
  797                                        Instruction *IVOperand) {
 
  799          strengthenOverflowingOperation(BO, IVOperand)) ||
 
  805bool SimplifyIndvar::strengthenOverflowingOperation(BinaryOperator *BO,
 
  806                                                    Instruction *IVOperand) {
 
  829bool SimplifyIndvar::strengthenRightShift(BinaryOperator *BO,
 
  830                                          Instruction *IVOperand) {
 
  831  if (BO->
getOpcode() == Instruction::Shl) {
 
  834    for (
auto *U : BO->
users()) {
 
  854void SimplifyIndvar::pushIVUsers(
 
  855    Instruction *Def, SmallPtrSet<Instruction *, 16> &Simplified,
 
  856    SmallVectorImpl<std::pair<Instruction *, Instruction *>> &SimpleIVUsers) {
 
  857  for (User *U : 
Def->users()) {
 
  869    if (!
L->contains(UI))
 
  876    SimpleIVUsers.push_back(std::make_pair(UI, Def));
 
  913void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) {
 
  926  pushIVUsers(CurrIV, Simplified, SimpleIVUsers);
 
  928  while (!SimpleIVUsers.
empty()) {
 
  929    std::pair<Instruction*, Instruction*> UseOper =
 
  938      DeadInsts.emplace_back(UseInst);
 
  943    if (UseInst == CurrIV) 
continue;
 
  947    if (replaceIVUserWithLoopInvariant(UseInst))
 
  953      for (Use &U : UseInst->
uses()) {
 
  955        if (replaceIVUserWithLoopInvariant(User))
 
  960    for (
unsigned N = 0; IVOperand; ++
N) {
 
  964      Value *NewOper = foldIVUser(UseInst, IVOperand);
 
  972    if (eliminateIVUser(UseInst, IVOperand)) {
 
  973      pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
 
  978      if (strengthenBinaryOp(BO, IVOperand)) {
 
  981        pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
 
  986    if (replaceFloatIVWithIntegerIV(UseInst)) {
 
  988      pushIVUsers(IVOperand, Simplified, SimpleIVUsers);
 
  998      pushIVUsers(UseInst, Simplified, SimpleIVUsers);
 
 1019  SIV.simplifyUsers(CurrIV, V);
 
 1020  return {SIV.hasChanged(), SIV.runUnswitching()};
 
 
 1029#if LLVM_ENABLE_ABI_BREAKING_CHECKS 
 1034    const auto &[
C, 
_] =
 
 
 1057  ScalarEvolution *SE;
 
 1067  unsigned NumElimExt = 0;
 
 1068  unsigned NumWidened = 0;
 
 1071  PHINode *WidePhi = 
nullptr;
 
 1073  const SCEV *WideIncExpr = 
nullptr;
 
 1074  SmallVectorImpl<WeakTrackingVH> &DeadInsts;
 
 1076  SmallPtrSet<Instruction *,16> Widened;
 
 1084  DenseMap<AssertingVH<Instruction>, ExtendKind> ExtendKindMap;
 
 1086  using DefUserPair = std::pair<AssertingVH<Value>, AssertingVH<Instruction>>;
 
 1092  DenseMap<DefUserPair, ConstantRange> PostIncRangeInfos;
 
 1094  std::optional<ConstantRange> getPostIncRangeInfo(
Value *Def,
 
 1095                                                   Instruction *UseI) {
 
 1096    DefUserPair 
Key(Def, UseI);
 
 1097    auto It = PostIncRangeInfos.
find(
Key);
 
 1098    return It == PostIncRangeInfos.
end()
 
 1099               ? std::optional<ConstantRange>(std::nullopt)
 
 1100               : std::optional<ConstantRange>(It->second);
 
 1103  void calculatePostIncRanges(PHINode *OrigPhi);
 
 1104  void calculatePostIncRange(Instruction *NarrowDef, Instruction *NarrowUser);
 
 1106  void updatePostIncRangeInfo(
Value *Def, Instruction *UseI, ConstantRange R) {
 
 1107    DefUserPair 
Key(Def, UseI);
 
 1110      It->second = 
R.intersectWith(It->second);
 
 1117  struct NarrowIVDefUse {
 
 1125    bool NeverNegative = 
false;
 
 1127    NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD,
 
 1129        : NarrowDef(ND), NarrowUse(NU), WideDef(WD),
 
 1130          NeverNegative(NeverNegative) {}
 
 1133  WidenIV(
const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
 
 1134          DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI,
 
 1139  unsigned getNumElimExt() { 
return NumElimExt; };
 
 1140  unsigned getNumWidened() { 
return NumWidened; };
 
 1143  Value *createExtendInst(
Value *NarrowOper, 
Type *WideType, 
bool IsSigned,
 
 1146  Instruction *cloneIVUser(NarrowIVDefUse DU, 
const SCEVAddRecExpr *WideAR);
 
 1147  Instruction *cloneArithmeticIVUser(NarrowIVDefUse DU,
 
 1148                                     const SCEVAddRecExpr *WideAR);
 
 1149  Instruction *cloneBitwiseIVUser(NarrowIVDefUse DU);
 
 1151  ExtendKind getExtendKind(Instruction *
I);
 
 1153  using WidenedRecTy = std::pair<const SCEVAddRecExpr *, ExtendKind>;
 
 1155  WidenedRecTy getWideRecurrence(NarrowIVDefUse DU);
 
 1157  WidenedRecTy getExtendedOperandRecurrence(NarrowIVDefUse DU);
 
 1159  const SCEV *getSCEVByOpCode(
const SCEV *
LHS, 
const SCEV *
RHS,
 
 1160                              unsigned OpCode) 
const;
 
 1163                          PHINode *OrigPhi, PHINode *WidePhi);
 
 1164  void truncateIVUse(NarrowIVDefUse DU);
 
 1166  bool widenLoopCompare(NarrowIVDefUse DU);
 
 1167  bool widenWithVariantUse(NarrowIVDefUse DU);
 
 1169  void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
 
 1189  for (
unsigned i = 0, e = 
PHI->getNumIncomingValues(); i != e; ++i) {
 
 1190    if (
PHI->getIncomingValue(i) != Def)
 
 1215  assert(DT->
dominates(DefI, InsertPt) && 
"def does not dominate all uses");
 
 1220  for (
auto *DTN = (*DT)[InsertPt->
getParent()]; DTN; DTN = DTN->getIDom())
 
 1222      return DTN->getBlock()->getTerminator();
 
 
 1230      : OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), LI(LInfo),
 
 1231        L(LI->getLoopFor(OrigPhi->
getParent())), SE(SEv), DT(DTree),
 
 1234    assert(L->getHeader() == OrigPhi->
getParent() && 
"Phi must be an IV");
 
 1235    ExtendKindMap[OrigPhi] = WI.
IsSigned ? ExtendKind::Sign : ExtendKind::Zero;
 
 
 1238Value *WidenIV::createExtendInst(
Value *NarrowOper, 
Type *WideType,
 
 1244       L && 
L->getLoopPreheader() && 
L->isLoopInvariant(NarrowOper);
 
 1245       L = 
L->getParentLoop())
 
 1246    Builder.SetInsertPoint(
L->getLoopPreheader()->getTerminator());
 
 1248  return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) :
 
 1249                    Builder.CreateZExt(NarrowOper, WideType);
 
 1255Instruction *WidenIV::cloneIVUser(WidenIV::NarrowIVDefUse DU,
 
 1256                                  const SCEVAddRecExpr *WideAR) {
 
 1257  unsigned Opcode = DU.NarrowUse->
getOpcode();
 
 1261  case Instruction::Add:
 
 1262  case Instruction::Mul:
 
 1263  case Instruction::UDiv:
 
 1264  case Instruction::Sub:
 
 1265    return cloneArithmeticIVUser(DU, WideAR);
 
 1267  case Instruction::And:
 
 1268  case Instruction::Or:
 
 1269  case Instruction::Xor:
 
 1270  case Instruction::Shl:
 
 1271  case Instruction::LShr:
 
 1272  case Instruction::AShr:
 
 1273    return cloneBitwiseIVUser(DU);
 
 1277Instruction *WidenIV::cloneBitwiseIVUser(WidenIV::NarrowIVDefUse DU) {
 
 1282  LLVM_DEBUG(
dbgs() << 
"Cloning bitwise IVUser: " << *NarrowUse << 
"\n");
 
 1288  bool IsSigned = getExtendKind(NarrowDef) == ExtendKind::Sign;
 
 1291                   : createExtendInst(NarrowUse->
getOperand(0), WideType,
 
 1292                                      IsSigned, NarrowUse);
 
 1295                   : createExtendInst(NarrowUse->
getOperand(1), WideType,
 
 1296                                      IsSigned, NarrowUse);
 
 1302  Builder.Insert(WideBO);
 
 1303  WideBO->copyIRFlags(NarrowBO);
 
 1307Instruction *WidenIV::cloneArithmeticIVUser(WidenIV::NarrowIVDefUse DU,
 
 1308                                            const SCEVAddRecExpr *WideAR) {
 
 1313  LLVM_DEBUG(
dbgs() << 
"Cloning arithmetic IVUser: " << *NarrowUse << 
"\n");
 
 1315  unsigned IVOpIdx = (NarrowUse->
getOperand(0) == NarrowDef) ? 0 : 1;
 
 1326  auto GuessNonIVOperand = [&](
bool SignExt) {
 
 1327    const SCEV *WideLHS;
 
 1328    const SCEV *WideRHS;
 
 1330    auto GetExtend = [
this, SignExt](
const SCEV *S, 
Type *Ty) {
 
 1337      WideLHS = SE->
getSCEV(WideDef);
 
 1339      WideRHS = GetExtend(NarrowRHS, WideType);
 
 1342      WideLHS = GetExtend(NarrowLHS, WideType);
 
 1343      WideRHS = SE->
getSCEV(WideDef);
 
 1347    const SCEV *WideUse =
 
 1348      getSCEVByOpCode(WideLHS, WideRHS, NarrowUse->
getOpcode());
 
 1350    return WideUse == WideAR;
 
 1353  bool SignExtend = getExtendKind(NarrowDef) == ExtendKind::Sign;
 
 1354  if (!GuessNonIVOperand(SignExtend)) {
 
 1355    SignExtend = !SignExtend;
 
 1356    if (!GuessNonIVOperand(SignExtend))
 
 1362                   : createExtendInst(NarrowUse->
getOperand(0), WideType,
 
 1363                                      SignExtend, NarrowUse);
 
 1366                   : createExtendInst(NarrowUse->
getOperand(1), WideType,
 
 1367                                      SignExtend, NarrowUse);
 
 1374  Builder.Insert(WideBO);
 
 1375  WideBO->copyIRFlags(NarrowBO);
 
 1379WidenIV::ExtendKind WidenIV::getExtendKind(Instruction *
I) {
 
 1380  auto It = ExtendKindMap.
find(
I);
 
 1381  assert(It != ExtendKindMap.
end() && 
"Instruction not yet extended!");
 
 1385const SCEV *WidenIV::getSCEVByOpCode(
const SCEV *
LHS, 
const SCEV *
RHS,
 
 1386                                     unsigned OpCode)
 const {
 
 1388  case Instruction::Add:
 
 1390  case Instruction::Sub:
 
 1392  case Instruction::Mul:
 
 1394  case Instruction::UDiv:
 
 1408  std::array<Value *, 2> Operands;
 
 1412  explicit BinaryOp(Instruction *
Op)
 
 1414        Operands({
Op->getOperand(0), 
Op->getOperand(1)}) {
 
 1416      IsNSW = OBO->hasNoSignedWrap();
 
 1417      IsNUW = OBO->hasNoUnsignedWrap();
 
 1422                    bool IsNSW = 
false, 
bool IsNUW = 
false)
 
 1423      : Opcode(Opcode), Operands({
LHS, 
RHS}), IsNSW(IsNSW), IsNUW(IsNUW) {}
 
 1429  switch (
Op->getOpcode()) {
 
 1430  case Instruction::Add:
 
 1431  case Instruction::Sub:
 
 1432  case Instruction::Mul:
 
 1433    return BinaryOp(
Op);
 
 1434  case Instruction::Or: {
 
 1437      return BinaryOp(Instruction::Add, 
Op->getOperand(0), 
Op->getOperand(1),
 
 1441  case Instruction::Shl: {
 
 1449      if (SA->getValue().ult(
BitWidth)) {
 
 1454        bool IsNUW = 
Op->hasNoUnsignedWrap();
 
 1455        bool IsNSW = 
Op->hasNoSignedWrap() &&
 
 1456                     (IsNUW || SA->getValue().ult(
BitWidth - 1));
 
 1459            ConstantInt::get(
Op->getContext(),
 
 1461        return BinaryOp(Instruction::Mul, 
Op->getOperand(0), 
X, IsNSW, IsNUW);
 
 1469  return std::nullopt;
 
 
 1477WidenIV::WidenedRecTy
 
 1478WidenIV::getExtendedOperandRecurrence(WidenIV::NarrowIVDefUse DU) {
 
 1481    return {
nullptr, ExtendKind::Unknown};
 
 1483  assert((
Op->Opcode == Instruction::Add || 
Op->Opcode == Instruction::Sub ||
 
 1484          Op->Opcode == Instruction::Mul) &&
 
 1485         "Unexpected opcode");
 
 1489  const unsigned ExtendOperIdx = 
Op->Operands[0] == DU.NarrowDef ? 1 : 0;
 
 1490  assert(
Op->Operands[1 - ExtendOperIdx] == DU.NarrowDef && 
"bad DU");
 
 1492  ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
 
 1493  if (!(ExtKind == ExtendKind::Sign && 
Op->IsNSW) &&
 
 1494      !(ExtKind == ExtendKind::Zero && 
Op->IsNUW)) {
 
 1495    ExtKind = ExtendKind::Unknown;
 
 1501    if (DU.NeverNegative) {
 
 1503        ExtKind = ExtendKind::Sign;
 
 1504      } 
else if (
Op->IsNUW) {
 
 1505        ExtKind = ExtendKind::Zero;
 
 1510  const SCEV *ExtendOperExpr = SE->
getSCEV(
Op->Operands[ExtendOperIdx]);
 
 1511  if (ExtKind == ExtendKind::Sign)
 
 1513  else if (ExtKind == ExtendKind::Zero)
 
 1516    return {
nullptr, ExtendKind::Unknown};
 
 1523  const SCEV *lhs = SE->
getSCEV(DU.WideDef);
 
 1524  const SCEV *rhs = ExtendOperExpr;
 
 1528  if (ExtendOperIdx == 0)
 
 1530  const SCEVAddRecExpr *AddRec =
 
 1533  if (!AddRec || AddRec->
getLoop() != L)
 
 1534    return {
nullptr, ExtendKind::Unknown};
 
 1536  return {AddRec, ExtKind};
 
 1544WidenIV::WidenedRecTy WidenIV::getWideRecurrence(WidenIV::NarrowIVDefUse DU) {
 
 1546    return {
nullptr, ExtendKind::Unknown};
 
 1548  const SCEV *NarrowExpr = SE->
getSCEV(DU.NarrowUse);
 
 1553    return {
nullptr, ExtendKind::Unknown};
 
 1556  const SCEV *WideExpr;
 
 1558  if (DU.NeverNegative) {
 
 1561      ExtKind = ExtendKind::Sign;
 
 1564      ExtKind = ExtendKind::Zero;
 
 1566  } 
else if (getExtendKind(DU.NarrowDef) == ExtendKind::Sign) {
 
 1568    ExtKind = ExtendKind::Sign;
 
 1571    ExtKind = ExtendKind::Zero;
 
 1574  if (!AddRec || AddRec->
getLoop() != L)
 
 1575    return {
nullptr, ExtendKind::Unknown};
 
 1576  return {AddRec, ExtKind};
 
 1581void WidenIV::truncateIVUse(NarrowIVDefUse DU) {
 
 1585  LLVM_DEBUG(
dbgs() << 
"INDVARS: Truncate IV " << *DU.WideDef << 
" for user " 
 1586                    << *DU.NarrowUse << 
"\n");
 
 1587  ExtendKind ExtKind = getExtendKind(DU.NarrowDef);
 
 1590      Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType(), 
"",
 
 1591                          DU.NeverNegative || ExtKind == ExtendKind::Zero,
 
 1592                          DU.NeverNegative || ExtKind == ExtendKind::Sign);
 
 1593  DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
 
 1599bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
 
 1618  bool IsSigned = getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
 
 1619  bool CmpPreferredSign = 
Cmp->hasSameSign() ? IsSigned : 
Cmp->isSigned();
 
 1620  if (!DU.NeverNegative && IsSigned != CmpPreferredSign)
 
 1623  Value *
Op = 
Cmp->getOperand(
Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
 
 1626  assert(CastWidth <= IVWidth && 
"Unexpected width while widening compare.");
 
 1632  if (CastWidth < IVWidth) {
 
 1637      CmpPreferredSign = 
true;
 
 1639    Value *ExtOp = createExtendInst(
Op, WideType, CmpPreferredSign, Cmp);
 
 1665bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
 
 1673  if (OpCode != Instruction::Add && OpCode != Instruction::Sub &&
 
 1674      OpCode != Instruction::Mul)
 
 1683  const OverflowingBinaryOperator *OBO =
 
 1685  ExtendKind ExtKind = getExtendKind(NarrowDef);
 
 1686  bool CanSignExtend = ExtKind == ExtendKind::Sign && OBO->
hasNoSignedWrap();
 
 1688  auto AnotherOpExtKind = ExtKind;
 
 1695  SmallVector<Instruction *, 4> ExtUsers;
 
 1698  for (Use &U : NarrowUse->
uses()) {
 
 1700    if (User == NarrowDef)
 
 1702    if (!
L->contains(User)) {
 
 1706      if (LCSSAPhi->getNumOperands() != 1)
 
 1717      if (ExtKind == ExtendKind::Zero && ICmpInst::isSigned(Pred))
 
 1719      if (ExtKind == ExtendKind::Sign && ICmpInst::isUnsigned(Pred))
 
 1724    if (ExtKind == ExtendKind::Sign)
 
 1728    if (!User || 
User->getType() != WideType)
 
 1732  if (ExtUsers.
empty()) {
 
 1742  if (!CanSignExtend && !CanZeroExtend) {
 
 1745    if (OpCode != Instruction::Add)
 
 1747    if (ExtKind != ExtendKind::Zero)
 
 1765    AnotherOpExtKind = ExtendKind::Sign;
 
 1769  const SCEV *Op1 = SE->
getSCEV(WideDef);
 
 1771  if (!AddRecOp1 || AddRecOp1->
getLoop() != L)
 
 1774  LLVM_DEBUG(
dbgs() << 
"Cloning arithmetic IVUser: " << *NarrowUse << 
"\n");
 
 1780          : createExtendInst(NarrowUse->
getOperand(0), WideType,
 
 1781                             AnotherOpExtKind == ExtendKind::Sign, NarrowUse);
 
 1785          : createExtendInst(NarrowUse->
getOperand(1), WideType,
 
 1786                             AnotherOpExtKind == ExtendKind::Sign, NarrowUse);
 
 1792  Builder.Insert(WideBO);
 
 1793  WideBO->copyIRFlags(NarrowBO);
 
 1794  ExtendKindMap[NarrowUse] = ExtKind;
 
 1796  for (Instruction *User : ExtUsers) {
 
 1797    assert(
User->getType() == WideType && 
"Checked before!");
 
 1798    LLVM_DEBUG(
dbgs() << 
"INDVARS: eliminating " << *User << 
" replaced by " 
 1799                      << *WideBO << 
"\n");
 
 1801    User->replaceAllUsesWith(WideBO);
 
 1805  for (PHINode *User : LCSSAPhiUsers) {
 
 1806    assert(
User->getNumOperands() == 1 && 
"Checked before!");
 
 1807    Builder.SetInsertPoint(User);
 
 1809        Builder.CreatePHI(WideBO->getType(), 1, 
User->getName() + 
".wide");
 
 1810    BasicBlock *LoopExitingBlock = 
User->getParent()->getSinglePredecessor();
 
 1811    assert(LoopExitingBlock && 
L->contains(LoopExitingBlock) &&
 
 1812           "Not a LCSSA Phi?");
 
 1813    WidePN->addIncoming(WideBO, LoopExitingBlock);
 
 1814    Builder.SetInsertPoint(
User->getParent(),
 
 1815                           User->getParent()->getFirstInsertionPt());
 
 1816    auto *TruncPN = Builder.CreateTrunc(WidePN, 
User->getType());
 
 1817    User->replaceAllUsesWith(TruncPN);
 
 1821  for (ICmpInst *User : ICmpUsers) {
 
 1822    Builder.SetInsertPoint(User);
 
 1826      if (ExtKind == ExtendKind::Zero)
 
 1827        return Builder.CreateZExt(V, WideBO->getType());
 
 1829        return Builder.CreateSExt(V, WideBO->getType());
 
 1831    auto Pred = 
User->getPredicate();
 
 1832    auto *
LHS = ExtendedOp(
User->getOperand(0));
 
 1833    auto *
RHS = ExtendedOp(
User->getOperand(1));
 
 1835        Builder.CreateICmp(Pred, 
LHS, 
RHS, 
User->getName() + 
".wide");
 
 1836    User->replaceAllUsesWith(WideCmp);
 
 1845Instruction *WidenIV::widenIVUse(WidenIV::NarrowIVDefUse DU,
 
 1846                                 SCEVExpander &
Rewriter, PHINode *OrigPhi,
 
 1849         "Should already know the kind of extension used to widen NarrowDef");
 
 1853  bool CanWidenBySExt =
 
 1854      DU.NeverNegative || getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
 
 1855  bool CanWidenByZExt =
 
 1856      DU.NeverNegative || getExtendKind(DU.NarrowDef) == ExtendKind::Zero;
 
 1860    if (LI->
getLoopFor(UsePhi->getParent()) != L) {
 
 1864      if (UsePhi->getNumOperands() != 1)
 
 1875                          UsePhi->getIterator());
 
 1876        WidePhi->
addIncoming(DU.WideDef, UsePhi->getIncomingBlock(0));
 
 1879        Value *Trunc = Builder.CreateTrunc(WidePhi, DU.NarrowDef->
getType(), 
"",
 
 1880                                           CanWidenByZExt, CanWidenBySExt);
 
 1883        LLVM_DEBUG(
dbgs() << 
"INDVARS: Widen lcssa phi " << *UsePhi << 
" to " 
 1884                          << *WidePhi << 
"\n");
 
 1893    Value *NewDef = DU.WideDef;
 
 1894    if (DU.NarrowUse->
getType() != WideType) {
 
 1897      if (CastWidth < IVWidth) {
 
 1900        NewDef = Builder.CreateTrunc(DU.WideDef, DU.NarrowUse->
getType(), 
"",
 
 1901                                     CanWidenByZExt, CanWidenBySExt);
 
 1908                          << 
" not wide enough to subsume " << *DU.NarrowUse
 
 1911        NewDef = DU.NarrowUse;
 
 1914    if (NewDef != DU.NarrowUse) {
 
 1916                        << 
" replaced by " << *DU.WideDef << 
"\n");
 
 1931  auto tryAddRecExpansion = [&]() -> Instruction* {
 
 1933    WidenedRecTy WideAddRec = getExtendedOperandRecurrence(DU);
 
 1934    if (!WideAddRec.first)
 
 1935      WideAddRec = getWideRecurrence(DU);
 
 1936    assert((WideAddRec.first == 
nullptr) ==
 
 1937           (WideAddRec.second == ExtendKind::Unknown));
 
 1938    if (!WideAddRec.first)
 
 1941    auto CanUseWideInc = [&]() {
 
 1948      bool NeedToRecomputeFlags =
 
 1950              OrigPhi, WidePhi, DU.NarrowUse, WideInc) ||
 
 1953      return WideAddRec.first == WideIncExpr &&
 
 1954             Rewriter.hoistIVInc(WideInc, DU.NarrowUse, NeedToRecomputeFlags);
 
 1958    if (CanUseWideInc())
 
 1961      WideUse = cloneIVUser(DU, WideAddRec.first);
 
 1970    if (WideAddRec.first != SE->
getSCEV(WideUse)) {
 
 1971      LLVM_DEBUG(
dbgs() << 
"Wide use expression mismatch: " << *WideUse << 
": " 
 1972                 << *SE->
getSCEV(WideUse) << 
" != " << *WideAddRec.first
 
 1982    ExtendKindMap[DU.NarrowUse] = WideAddRec.second;
 
 1987  if (
auto *
I = tryAddRecExpansion())
 
 1992  if (widenLoopCompare(DU))
 
 2000  if (widenWithVariantUse(DU))
 
 2011void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
 
 2012  const SCEV *NarrowSCEV = SE->
getSCEV(NarrowDef);
 
 2013  bool NonNegativeDef =
 
 2016  for (User *U : NarrowDef->
users()) {
 
 2020    if (!Widened.
insert(NarrowUser).second)
 
 2023    bool NonNegativeUse = 
false;
 
 2024    if (!NonNegativeDef) {
 
 2026      if (
auto RangeInfo = getPostIncRangeInfo(NarrowDef, NarrowUser))
 
 2027        NonNegativeUse = RangeInfo->getSignedMin().isNonNegative();
 
 2030    NarrowIVUsers.emplace_back(NarrowDef, NarrowUser, WideDef,
 
 2031                               NonNegativeDef || NonNegativeUse);
 
 2043PHINode *WidenIV::createWideIV(SCEVExpander &
Rewriter) {
 
 2050  const SCEV *WideIVExpr = getExtendKind(OrigPhi) == ExtendKind::Sign
 
 2055         "Expect the new IV expression to preserve its type");
 
 2059  if (!AddRec || AddRec->
getLoop() != L)
 
 2068      "Loop header phi recurrence inputs do not dominate the loop");
 
 2081    calculatePostIncRanges(OrigPhi);
 
 2087  Instruction *InsertPt = &*
L->getHeader()->getFirstInsertionPt();
 
 2088  Value *ExpandInst = 
Rewriter.expandCodeFor(AddRec, WideType, InsertPt);
 
 2105  if (BasicBlock *LatchBlock = 
L->getLoopLatch()) {
 
 2109      WideIncExpr = SE->
getSCEV(WideInc);
 
 2126                                                       OrigInc, WideInc) &&
 
 2130                                      OrigInc->hasNoUnsignedWrap());
 
 2132                                    OrigInc->hasNoSignedWrap());
 
 2141  assert(Widened.
empty() && NarrowIVUsers.empty() && 
"expect initial state" );
 
 2144  pushNarrowIVUsers(OrigPhi, WidePhi);
 
 2146  while (!NarrowIVUsers.empty()) {
 
 2147    WidenIV::NarrowIVDefUse DU = NarrowIVUsers.pop_back_val();
 
 2155      pushNarrowIVUsers(DU.NarrowUse, WideUse);
 
 2170void WidenIV::calculatePostIncRange(Instruction *NarrowDef,
 
 2171                                    Instruction *NarrowUser) {
 
 2172  Value *NarrowDefLHS;
 
 2173  const APInt *NarrowDefRHS;
 
 2179  auto UpdateRangeFromCondition = [&](
Value *Condition, 
bool TrueDest) {
 
 2189    auto CmpConstrainedLHSRange =
 
 2191    auto NarrowDefRange = CmpConstrainedLHSRange.addWithNoWrap(
 
 2194    updatePostIncRangeInfo(NarrowDef, NarrowUser, NarrowDefRange);
 
 2197  auto UpdateRangeFromGuards = [&](
Instruction *Ctx) {
 
 2201    for (Instruction &
I : 
make_range(Ctx->getIterator().getReverse(),
 
 2202                                     Ctx->getParent()->rend())) {
 
 2205        UpdateRangeFromCondition(
C, 
true);
 
 2209  UpdateRangeFromGuards(NarrowUser);
 
 2217  for (
auto *DTB = (*DT)[NarrowUserBB]->getIDom();
 
 2218       L->contains(DTB->getBlock());
 
 2219       DTB = DTB->getIDom()) {
 
 2220    auto *BB = DTB->getBlock();
 
 2221    auto *TI = BB->getTerminator();
 
 2222    UpdateRangeFromGuards(TI);
 
 2225    if (!BI || !BI->isConditional())
 
 2228    auto *TrueSuccessor = BI->getSuccessor(0);
 
 2229    auto *FalseSuccessor = BI->getSuccessor(1);
 
 2231    auto DominatesNarrowUser = [
this, NarrowUser] (BasicBlockEdge BBE) {
 
 2232      return BBE.isSingleEdge() &&
 
 2236    if (DominatesNarrowUser(BasicBlockEdge(BB, TrueSuccessor)))
 
 2237      UpdateRangeFromCondition(BI->getCondition(), 
true);
 
 2239    if (DominatesNarrowUser(BasicBlockEdge(BB, FalseSuccessor)))
 
 2240      UpdateRangeFromCondition(BI->getCondition(), 
false);
 
 2245void WidenIV::calculatePostIncRanges(PHINode *OrigPhi) {
 
 2246  SmallPtrSet<Instruction *, 16> Visited;
 
 2251  while (!Worklist.
empty()) {
 
 2254    for (Use &U : NarrowDef->
uses()) {
 
 2258      auto *NarrowUserLoop = (*LI)[NarrowUser->
getParent()];
 
 2259      if (!NarrowUserLoop || !
L->contains(NarrowUserLoop))
 
 2262      if (!Visited.
insert(NarrowUser).second)
 
 2267      calculatePostIncRange(NarrowDef, NarrowUser);
 
 2275    unsigned &NumElimExt, 
unsigned &NumWidened,
 
 2278  PHINode *WidePHI = Widener.createWideIV(Rewriter);
 
 2279  NumElimExt = Widener.getNumElimExt();
 
 2280  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.
 
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...
 
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.
 
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
 
void setOperand(unsigned i, Value *Val)
 
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.