llvm.org GIT mirror llvm / 76aac8f
[SCEV] Use depth limit instead of local cache for SExt and ZExt In rL300494 there was an attempt to deal with excessive compile time on invocations of getSign/ZeroExtExpr using local caching. This approach only helps if we request the same SCEV multiple times throughout recursion. But in the bug PR33431 we see a case where we request different values all the time, so caching does not help and the size of the cache grows enormously. In this patch we remove the local cache for this methods and add the recursion depth limit instead, as we do for arithmetics. This gives us a guarantee that the invocation sequence is limited and reasonably short. Differential Revision: https://reviews.llvm.org/D34273 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306785 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 2 years ago
4 changed file(s) with 184 addition(s) and 145 deletion(s). Raw diff Collapse all Expand all
11961196 const SCEV *getConstant(const APInt &Val);
11971197 const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
11981198 const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty);
1199
1200 typedef SmallDenseMap, const SCEV *, 8>
1201 ExtendCacheTy;
1202 const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty);
1203 const SCEV *getZeroExtendExprCached(const SCEV *Op, Type *Ty,
1204 ExtendCacheTy &Cache);
1205 const SCEV *getZeroExtendExprImpl(const SCEV *Op, Type *Ty,
1206 ExtendCacheTy &Cache);
1207
1208 const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty);
1209 const SCEV *getSignExtendExprCached(const SCEV *Op, Type *Ty,
1210 ExtendCacheTy &Cache);
1211 const SCEV *getSignExtendExprImpl(const SCEV *Op, Type *Ty,
1212 ExtendCacheTy &Cache);
1199 const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
1200 const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0);
12131201 const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty);
12141202 const SCEV *getAddExpr(SmallVectorImpl &Ops,
12151203 SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
156156 "scalar-evolution-max-constant-evolving-depth", cl::Hidden,
157157 cl::desc("Maximum depth of recursive constant evolving"), cl::init(32));
158158
159 static cl::opt
160 MaxExtDepth("scalar-evolution-max-ext-depth", cl::Hidden,
161 cl::desc("Maximum depth of recursive SExt/ZExt"),
162 cl::init(8));
163
159164 //===----------------------------------------------------------------------===//
160165 // SCEV class definitions
161166 //===----------------------------------------------------------------------===//
12841289 namespace {
12851290
12861291 struct ExtendOpTraitsBase {
1287 typedef const SCEV *(ScalarEvolution::*GetExtendExprTy)(
1288 const SCEV *, Type *, ScalarEvolution::ExtendCacheTy &Cache);
1292 typedef const SCEV *(ScalarEvolution::*GetExtendExprTy)(const SCEV *, Type *,
1293 unsigned);
12891294 };
12901295
12911296 // Used to make code generic over signed and unsigned overflow.
13141319 }
13151320 };
13161321
1317 const ExtendOpTraitsBase::GetExtendExprTy
1318 ExtendOpTraits::GetExtendExpr =
1319 &ScalarEvolution::getSignExtendExprCached;
1322 const ExtendOpTraitsBase::GetExtendExprTy ExtendOpTraits<
1323 SCEVSignExtendExpr>::GetExtendExpr = &ScalarEvolution::getSignExtendExpr;
13201324
13211325 template <>
13221326 struct ExtendOpTraits : public ExtendOpTraitsBase {
13311335 }
13321336 };
13331337
1334 const ExtendOpTraitsBase::GetExtendExprTy
1335 ExtendOpTraits::GetExtendExpr =
1336 &ScalarEvolution::getZeroExtendExprCached;
1338 const ExtendOpTraitsBase::GetExtendExprTy ExtendOpTraits<
1339 SCEVZeroExtendExpr>::GetExtendExpr = &ScalarEvolution::getZeroExtendExpr;
13371340 }
13381341
13391342 // The recurrence AR has been shown to have no signed/unsigned wrap or something
13451348 // "sext/zext(PostIncAR)"
13461349 template
13471350 static const SCEV *getPreStartForExtend(const SCEVAddRecExpr *AR, Type *Ty,
1348 ScalarEvolution *SE,
1349 ScalarEvolution::ExtendCacheTy &Cache) {
1351 ScalarEvolution *SE, unsigned Depth) {
13501352 auto WrapType = ExtendOpTraits::WrapType;
13511353 auto GetExtendExpr = ExtendOpTraits::GetExtendExpr;
13521354
13931395 unsigned BitWidth = SE->getTypeSizeInBits(AR->getType());
13941396 Type *WideTy = IntegerType::get(SE->getContext(), BitWidth * 2);
13951397 const SCEV *OperandExtendedStart =
1396 SE->getAddExpr((SE->*GetExtendExpr)(PreStart, WideTy, Cache),
1397 (SE->*GetExtendExpr)(Step, WideTy, Cache));
1398 if ((SE->*GetExtendExpr)(Start, WideTy, Cache) == OperandExtendedStart) {
1398 SE->getAddExpr((SE->*GetExtendExpr)(PreStart, WideTy, Depth),
1399 (SE->*GetExtendExpr)(Step, WideTy, Depth));
1400 if ((SE->*GetExtendExpr)(Start, WideTy, Depth) == OperandExtendedStart) {
13991401 if (PreAR && AR->getNoWrapFlags(WrapType)) {
14001402 // If we know `AR` == {`PreStart`+`Step`,+,`Step`} is `WrapType` (FlagNSW
14011403 // or FlagNUW) and that `PreStart` + `Step` is `WrapType` too, then
14211423 template
14221424 static const SCEV *getExtendAddRecStart(const SCEVAddRecExpr *AR, Type *Ty,
14231425 ScalarEvolution *SE,
1424 ScalarEvolution::ExtendCacheTy &Cache) {
1426 unsigned Depth) {
14251427 auto GetExtendExpr = ExtendOpTraits::GetExtendExpr;
14261428
1427 const SCEV *PreStart = getPreStartForExtend(AR, Ty, SE, Cache);
1429 const SCEV *PreStart = getPreStartForExtend(AR, Ty, SE, Depth);
14281430 if (!PreStart)
1429 return (SE->*GetExtendExpr)(AR->getStart(), Ty, Cache);
1430
1431 return SE->getAddExpr(
1432 (SE->*GetExtendExpr)(AR->getStepRecurrence(*SE), Ty, Cache),
1433 (SE->*GetExtendExpr)(PreStart, Ty, Cache));
1431 return (SE->*GetExtendExpr)(AR->getStart(), Ty, Depth);
1432
1433 return SE->getAddExpr((SE->*GetExtendExpr)(AR->getStepRecurrence(*SE), Ty,
1434 Depth),
1435 (SE->*GetExtendExpr)(PreStart, Ty, Depth));
14341436 }
14351437
14361438 // Try to prove away overflow by looking at "nearby" add recurrences. A
15101512 return false;
15111513 }
15121514
1513 const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty) {
1514 // Use the local cache to prevent exponential behavior of
1515 // getZeroExtendExprImpl.
1516 ExtendCacheTy Cache;
1517 return getZeroExtendExprCached(Op, Ty, Cache);
1518 }
1519
1520 /// Query \p Cache before calling getZeroExtendExprImpl. If there is no
1521 /// related entry in the \p Cache, call getZeroExtendExprImpl and save
1522 /// the result in the \p Cache.
1523 const SCEV *ScalarEvolution::getZeroExtendExprCached(const SCEV *Op, Type *Ty,
1524 ExtendCacheTy &Cache) {
1525 auto It = Cache.find({Op, Ty});
1526 if (It != Cache.end())
1527 return It->second;
1528 const SCEV *ZExt = getZeroExtendExprImpl(Op, Ty, Cache);
1529 auto InsertResult = Cache.insert({{Op, Ty}, ZExt});
1530 assert(InsertResult.second && "Expect the key was not in the cache");
1531 (void)InsertResult;
1532 return ZExt;
1533 }
1534
1535 /// The real implementation of getZeroExtendExpr.
1536 const SCEV *ScalarEvolution::getZeroExtendExprImpl(const SCEV *Op, Type *Ty,
1537 ExtendCacheTy &Cache) {
1515 const SCEV *
1516 ScalarEvolution::getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
15381517 assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) &&
15391518 "This is not an extending conversion!");
15401519 assert(isSCEVable(Ty) &&
15441523 // Fold if the operand is constant.
15451524 if (const SCEVConstant *SC = dyn_cast(Op))
15461525 return getConstant(
1547 cast(ConstantExpr::getZExt(SC->getValue(), Ty)));
1526 cast(ConstantExpr::getZExt(SC->getValue(), Ty)));
15481527
15491528 // zext(zext(x)) --> zext(x)
15501529 if (const SCEVZeroExtendExpr *SZ = dyn_cast(Op))
1551 return getZeroExtendExprCached(SZ->getOperand(), Ty, Cache);
1530 return getZeroExtendExpr(SZ->getOperand(), Ty, Depth + 1);
15521531
15531532 // Before doing any expensive analysis, check to see if we've already
15541533 // computed a SCEV for this Op and Ty.
15581537 ID.AddPointer(Ty);
15591538 void *IP = nullptr;
15601539 if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
1540 if (Depth > MaxExtDepth) {
1541 SCEV *S = new (SCEVAllocator) SCEVZeroExtendExpr(ID.Intern(SCEVAllocator),
1542 Op, Ty);
1543 UniqueSCEVs.InsertNode(S, IP);
1544 return S;
1545 }
15611546
15621547 // zext(trunc(x)) --> zext(x) or x or trunc(x)
15631548 if (const SCEVTruncateExpr *ST = dyn_cast(Op)) {
15921577 // we don't need to do any further analysis.
15931578 if (AR->hasNoUnsignedWrap())
15941579 return getAddRecExpr(
1595 getExtendAddRecStart(AR, Ty, this, Cache),
1596 getZeroExtendExprCached(Step, Ty, Cache), L, AR->getNoWrapFlags());
1580 getExtendAddRecStart(AR, Ty, this, Depth + 1),
1581 getZeroExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
15971582
15981583 // Check whether the backedge-taken count is SCEVCouldNotCompute.
15991584 // Note that this serves two purposes: It filters out loops that are
16171602 if (MaxBECount == RecastedMaxBECount) {
16181603 Type *WideTy = IntegerType::get(getContext(), BitWidth * 2);
16191604 // Check whether Start+Step*MaxBECount has no unsigned overflow.
1620 const SCEV *ZMul = getMulExpr(CastedMaxBECount, Step);
1621 const SCEV *ZAdd =
1622 getZeroExtendExprCached(getAddExpr(Start, ZMul), WideTy, Cache);
1623 const SCEV *WideStart = getZeroExtendExprCached(Start, WideTy, Cache);
1605 const SCEV *ZMul = getMulExpr(CastedMaxBECount, Step,
1606 SCEV::FlagAnyWrap, Depth + 1);
1607 const SCEV *ZAdd = getZeroExtendExpr(getAddExpr(Start, ZMul,
1608 SCEV::FlagAnyWrap,
1609 Depth + 1),
1610 WideTy, Depth + 1);
1611 const SCEV *WideStart = getZeroExtendExpr(Start, WideTy, Depth + 1);
16241612 const SCEV *WideMaxBECount =
1625 getZeroExtendExprCached(CastedMaxBECount, WideTy, Cache);
1626 const SCEV *OperandExtendedAdd = getAddExpr(
1627 WideStart, getMulExpr(WideMaxBECount, getZeroExtendExprCached(
1628 Step, WideTy, Cache)));
1613 getZeroExtendExpr(CastedMaxBECount, WideTy, Depth + 1);
1614 const SCEV *OperandExtendedAdd =
1615 getAddExpr(WideStart,
1616 getMulExpr(WideMaxBECount,
1617 getZeroExtendExpr(Step, WideTy, Depth + 1),
1618 SCEV::FlagAnyWrap, Depth + 1),
1619 SCEV::FlagAnyWrap, Depth + 1);
16291620 if (ZAdd == OperandExtendedAdd) {
16301621 // Cache knowledge of AR NUW, which is propagated to this AddRec.
16311622 const_cast(AR)->setNoWrapFlags(SCEV::FlagNUW);
16321623 // Return the expression with the addrec on the outside.
16331624 return getAddRecExpr(
1634 getExtendAddRecStart(AR, Ty, this, Cache),
1635 getZeroExtendExprCached(Step, Ty, Cache), L,
1625 getExtendAddRecStart(AR, Ty, this,
1626 Depth + 1),
1627 getZeroExtendExpr(Step, Ty, Depth + 1), L,
16361628 AR->getNoWrapFlags());
16371629 }
16381630 // Similar to above, only this time treat the step value as signed.
16401632 OperandExtendedAdd =
16411633 getAddExpr(WideStart,
16421634 getMulExpr(WideMaxBECount,
1643 getSignExtendExpr(Step, WideTy)));
1635 getSignExtendExpr(Step, WideTy, Depth + 1),
1636 SCEV::FlagAnyWrap, Depth + 1),
1637 SCEV::FlagAnyWrap, Depth + 1);
16441638 if (ZAdd == OperandExtendedAdd) {
16451639 // Cache knowledge of AR NW, which is propagated to this AddRec.
16461640 // Negative step causes unsigned wrap, but it still can't self-wrap.
16471641 const_cast(AR)->setNoWrapFlags(SCEV::FlagNW);
16481642 // Return the expression with the addrec on the outside.
16491643 return getAddRecExpr(
1650 getExtendAddRecStart(AR, Ty, this, Cache),
1651 getSignExtendExpr(Step, Ty), L, AR->getNoWrapFlags());
1644 getExtendAddRecStart(AR, Ty, this,
1645 Depth + 1),
1646 getSignExtendExpr(Step, Ty, Depth + 1), L,
1647 AR->getNoWrapFlags());
16521648 }
16531649 }
16541650 }
16791675 const_cast(AR)->setNoWrapFlags(SCEV::FlagNUW);
16801676 // Return the expression with the addrec on the outside.
16811677 return getAddRecExpr(
1682 getExtendAddRecStart(AR, Ty, this, Cache),
1683 getZeroExtendExprCached(Step, Ty, Cache), L,
1678 getExtendAddRecStart(AR, Ty, this,
1679 Depth + 1),
1680 getZeroExtendExpr(Step, Ty, Depth + 1), L,
16841681 AR->getNoWrapFlags());
16851682 }
16861683 } else if (isKnownNegative(Step)) {
16961693 const_cast(AR)->setNoWrapFlags(SCEV::FlagNW);
16971694 // Return the expression with the addrec on the outside.
16981695 return getAddRecExpr(
1699 getExtendAddRecStart(AR, Ty, this, Cache),
1700 getSignExtendExpr(Step, Ty), L, AR->getNoWrapFlags());
1696 getExtendAddRecStart(AR, Ty, this,
1697 Depth + 1),
1698 getSignExtendExpr(Step, Ty, Depth + 1), L,
1699 AR->getNoWrapFlags());
17011700 }
17021701 }
17031702 }
17051704 if (proveNoWrapByVaryingStart(Start, Step, L)) {
17061705 const_cast(AR)->setNoWrapFlags(SCEV::FlagNUW);
17071706 return getAddRecExpr(
1708 getExtendAddRecStart(AR, Ty, this, Cache),
1709 getZeroExtendExprCached(Step, Ty, Cache), L, AR->getNoWrapFlags());
1707 getExtendAddRecStart(AR, Ty, this, Depth + 1),
1708 getZeroExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
17101709 }
17111710 }
17121711
17171716 // commute the zero extension with the addition operation.
17181717 SmallVector Ops;
17191718 for (const auto *Op : SA->operands())
1720 Ops.push_back(getZeroExtendExprCached(Op, Ty, Cache));
1721 return getAddExpr(Ops, SCEV::FlagNUW);
1719 Ops.push_back(getZeroExtendExpr(Op, Ty, Depth + 1));
1720 return getAddExpr(Ops, SCEV::FlagNUW, Depth + 1);
17221721 }
17231722 }
17241723
17311730 return S;
17321731 }
17331732
1734 const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty) {
1735 // Use the local cache to prevent exponential behavior of
1736 // getSignExtendExprImpl.
1737 ExtendCacheTy Cache;
1738 return getSignExtendExprCached(Op, Ty, Cache);
1739 }
1740
1741 /// Query \p Cache before calling getSignExtendExprImpl. If there is no
1742 /// related entry in the \p Cache, call getSignExtendExprImpl and save
1743 /// the result in the \p Cache.
1744 const SCEV *ScalarEvolution::getSignExtendExprCached(const SCEV *Op, Type *Ty,
1745 ExtendCacheTy &Cache) {
1746 auto It = Cache.find({Op, Ty});
1747 if (It != Cache.end())
1748 return It->second;
1749 const SCEV *SExt = getSignExtendExprImpl(Op, Ty, Cache);
1750 auto InsertResult = Cache.insert({{Op, Ty}, SExt});
1751 assert(InsertResult.second && "Expect the key was not in the cache");
1752 (void)InsertResult;
1753 return SExt;
1754 }
1755
1756 /// The real implementation of getSignExtendExpr.
1757 const SCEV *ScalarEvolution::getSignExtendExprImpl(const SCEV *Op, Type *Ty,
1758 ExtendCacheTy &Cache) {
1733 const SCEV *
1734 ScalarEvolution::getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth) {
17591735 assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) &&
17601736 "This is not an extending conversion!");
17611737 assert(isSCEVable(Ty) &&
17651741 // Fold if the operand is constant.
17661742 if (const SCEVConstant *SC = dyn_cast(Op))
17671743 return getConstant(
1768 cast(ConstantExpr::getSExt(SC->getValue(), Ty)));
1744 cast(ConstantExpr::getSExt(SC->getValue(), Ty)));
17691745
17701746 // sext(sext(x)) --> sext(x)
17711747 if (const SCEVSignExtendExpr *SS = dyn_cast(Op))
1772 return getSignExtendExprCached(SS->getOperand(), Ty, Cache);
1748 return getSignExtendExpr(SS->getOperand(), Ty, Depth + 1);
17731749
17741750 // sext(zext(x)) --> zext(x)
17751751 if (const SCEVZeroExtendExpr *SZ = dyn_cast(Op))
1776 return getZeroExtendExpr(SZ->getOperand(), Ty);
1752 return getZeroExtendExpr(SZ->getOperand(), Ty, Depth + 1);
17771753
17781754 // Before doing any expensive analysis, check to see if we've already
17791755 // computed a SCEV for this Op and Ty.
17831759 ID.AddPointer(Ty);
17841760 void *IP = nullptr;
17851761 if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
1762 // Limit recursion depth.
1763 if (Depth > MaxExtDepth) {
1764 SCEV *S = new (SCEVAllocator) SCEVSignExtendExpr(ID.Intern(SCEVAllocator),
1765 Op, Ty);
1766 UniqueSCEVs.InsertNode(S, IP);
1767 return S;
1768 }
17861769
17871770 // sext(trunc(x)) --> sext(x) or x or trunc(x)
17881771 if (const SCEVTruncateExpr *ST = dyn_cast(Op)) {
18081791 const APInt &C2 = SC2->getAPInt();
18091792 if (C1.isStrictlyPositive() && C2.isStrictlyPositive() &&
18101793 C2.ugt(C1) && C2.isPowerOf2())
1811 return getAddExpr(getSignExtendExprCached(SC1, Ty, Cache),
1812 getSignExtendExprCached(SMul, Ty, Cache));
1794 return getAddExpr(getSignExtendExpr(SC1, Ty, Depth + 1),
1795 getSignExtendExpr(SMul, Ty, Depth + 1),
1796 SCEV::FlagAnyWrap, Depth + 1);
18131797 }
18141798 }
18151799 }
18201804 // commute the sign extension with the addition operation.
18211805 SmallVector Ops;
18221806 for (const auto *Op : SA->operands())
1823 Ops.push_back(getSignExtendExprCached(Op, Ty, Cache));
1824 return getAddExpr(Ops, SCEV::FlagNSW);
1807 Ops.push_back(getSignExtendExpr(Op, Ty, Depth + 1));
1808 return getAddExpr(Ops, SCEV::FlagNSW, Depth + 1);
18251809 }
18261810 }
18271811 // If the input value is a chrec scev, and we can prove that the value
18441828 // we don't need to do any further analysis.
18451829 if (AR->hasNoSignedWrap())
18461830 return getAddRecExpr(
1847 getExtendAddRecStart(AR, Ty, this, Cache),
1848 getSignExtendExprCached(Step, Ty, Cache), L, SCEV::FlagNSW);
1831 getExtendAddRecStart(AR, Ty, this, Depth + 1),
1832 getSignExtendExpr(Step, Ty, Depth + 1), L, SCEV::FlagNSW);
18491833
18501834 // Check whether the backedge-taken count is SCEVCouldNotCompute.
18511835 // Note that this serves two purposes: It filters out loops that are
18691853 if (MaxBECount == RecastedMaxBECount) {
18701854 Type *WideTy = IntegerType::get(getContext(), BitWidth * 2);
18711855 // Check whether Start+Step*MaxBECount has no signed overflow.
1872 const SCEV *SMul = getMulExpr(CastedMaxBECount, Step);
1873 const SCEV *SAdd =
1874 getSignExtendExprCached(getAddExpr(Start, SMul), WideTy, Cache);
1875 const SCEV *WideStart = getSignExtendExprCached(Start, WideTy, Cache);
1856 const SCEV *SMul = getMulExpr(CastedMaxBECount, Step,
1857 SCEV::FlagAnyWrap, Depth + 1);
1858 const SCEV *SAdd = getSignExtendExpr(getAddExpr(Start, SMul,
1859 SCEV::FlagAnyWrap,
1860 Depth + 1),
1861 WideTy, Depth + 1);
1862 const SCEV *WideStart = getSignExtendExpr(Start, WideTy, Depth + 1);
18761863 const SCEV *WideMaxBECount =
1877 getZeroExtendExpr(CastedMaxBECount, WideTy);
1878 const SCEV *OperandExtendedAdd = getAddExpr(
1879 WideStart, getMulExpr(WideMaxBECount, getSignExtendExprCached(
1880 Step, WideTy, Cache)));
1864 getZeroExtendExpr(CastedMaxBECount, WideTy, Depth + 1);
1865 const SCEV *OperandExtendedAdd =
1866 getAddExpr(WideStart,
1867 getMulExpr(WideMaxBECount,
1868 getSignExtendExpr(Step, WideTy, Depth + 1),
1869 SCEV::FlagAnyWrap, Depth + 1),
1870 SCEV::FlagAnyWrap, Depth + 1);
18811871 if (SAdd == OperandExtendedAdd) {
18821872 // Cache knowledge of AR NSW, which is propagated to this AddRec.
18831873 const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW);
18841874 // Return the expression with the addrec on the outside.
18851875 return getAddRecExpr(
1886 getExtendAddRecStart(AR, Ty, this, Cache),
1887 getSignExtendExprCached(Step, Ty, Cache), L,
1876 getExtendAddRecStart(AR, Ty, this,
1877 Depth + 1),
1878 getSignExtendExpr(Step, Ty, Depth + 1), L,
18881879 AR->getNoWrapFlags());
18891880 }
18901881 // Similar to above, only this time treat the step value as unsigned.
18921883 OperandExtendedAdd =
18931884 getAddExpr(WideStart,
18941885 getMulExpr(WideMaxBECount,
1895 getZeroExtendExpr(Step, WideTy)));
1886 getZeroExtendExpr(Step, WideTy, Depth + 1),
1887 SCEV::FlagAnyWrap, Depth + 1),
1888 SCEV::FlagAnyWrap, Depth + 1);
18961889 if (SAdd == OperandExtendedAdd) {
18971890 // If AR wraps around then
18981891 //
19061899
19071900 // Return the expression with the addrec on the outside.
19081901 return getAddRecExpr(
1909 getExtendAddRecStart(AR, Ty, this, Cache),
1910 getZeroExtendExpr(Step, Ty), L, AR->getNoWrapFlags());
1902 getExtendAddRecStart(AR, Ty, this,
1903 Depth + 1),
1904 getZeroExtendExpr(Step, Ty, Depth + 1), L,
1905 AR->getNoWrapFlags());
19111906 }
19121907 }
19131908 }
19381933 // Cache knowledge of AR NSW, then propagate NSW to the wide AddRec.
19391934 const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW);
19401935 return getAddRecExpr(
1941 getExtendAddRecStart(AR, Ty, this, Cache),
1942 getSignExtendExprCached(Step, Ty, Cache), L,
1943 AR->getNoWrapFlags());
1936 getExtendAddRecStart(AR, Ty, this, Depth + 1),
1937 getSignExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
19441938 }
19451939 }
19461940
19541948 const APInt &C2 = SC2->getAPInt();
19551949 if (C1.isStrictlyPositive() && C2.isStrictlyPositive() && C2.ugt(C1) &&
19561950 C2.isPowerOf2()) {
1957 Start = getSignExtendExprCached(Start, Ty, Cache);
1951 Start = getSignExtendExpr(Start, Ty, Depth + 1);
19581952 const SCEV *NewAR = getAddRecExpr(getZero(AR->getType()), Step, L,
19591953 AR->getNoWrapFlags());
1960 return getAddExpr(Start, getSignExtendExprCached(NewAR, Ty, Cache));
1954 return getAddExpr(Start, getSignExtendExpr(NewAR, Ty, Depth + 1),
1955 SCEV::FlagAnyWrap, Depth + 1);
19611956 }
19621957 }
19631958
19641959 if (proveNoWrapByVaryingStart(Start, Step, L)) {
19651960 const_cast(AR)->setNoWrapFlags(SCEV::FlagNSW);
19661961 return getAddRecExpr(
1967 getExtendAddRecStart(AR, Ty, this, Cache),
1968 getSignExtendExprCached(Step, Ty, Cache), L, AR->getNoWrapFlags());
1962 getExtendAddRecStart(AR, Ty, this, Depth + 1),
1963 getSignExtendExpr(Step, Ty, Depth + 1), L, AR->getNoWrapFlags());
19691964 }
19701965 }
19711966
19721967 // If the input value is provably positive and we could not simplify
19731968 // away the sext build a zext instead.
19741969 if (isKnownNonNegative(Op))
1975 return getZeroExtendExpr(Op, Ty);
1970 return getZeroExtendExpr(Op, Ty, Depth + 1);
19761971
19771972 // The cast wasn't folded; create an explicit cast node.
19781973 // Recompute the insert position, as it may have been invalidated.
353353 typedef const SCEV *(ScalarEvolution::*OperationFunctionTy)(
354354 const SCEV *, const SCEV *, SCEV::NoWrapFlags, unsigned);
355355 typedef const SCEV *(ScalarEvolution::*ExtensionFunctionTy)(
356 const SCEV *, Type *);
356 const SCEV *, Type *, unsigned);
357357
358358 OperationFunctionTy Operation;
359359 ExtensionFunctionTy Extension;
405405 IntegerType::get(NarrowTy->getContext(), NarrowTy->getBitWidth() * 2);
406406
407407 const SCEV *A =
408 (SE->*Extension)((SE->*Operation)(LHS, RHS, SCEV::FlagAnyWrap, 0u),
409 WideTy);
408 (SE->*Extension)((SE->*Operation)(LHS, RHS, SCEV::FlagAnyWrap, 0),
409 WideTy, 0);
410410 const SCEV *B =
411 (SE->*Operation)((SE->*Extension)(LHS, WideTy),
412 (SE->*Extension)(RHS, WideTy), SCEV::FlagAnyWrap, 0u);
411 (SE->*Operation)((SE->*Extension)(LHS, WideTy, 0),
412 (SE->*Extension)(RHS, WideTy, 0), SCEV::FlagAnyWrap, 0);
413413
414414 if (A != B)
415415 return false;
None ; RUN: opt -scalar-evolution-max-arith-depth=0 -analyze -scalar-evolution < %s | FileCheck %s
0 ; RUN: opt -scalar-evolution-max-arith-depth=0 -scalar-evolution-max-ext-depth=0 -analyze -scalar-evolution < %s | FileCheck %s
11
22 ; Check that depth set to 0 prevents getAddExpr and getMulExpr from making
33 ; transformations in SCEV. We expect the result to be very straightforward.
4141 %s2 = mul i32 %s1, %p3
4242 ret void
4343 }
44
45 define void @test_sext(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) {
46 ; CHECK-LABEL: @test_sext
47 ; CHECK: %se2 = sext i64 %iv2.inc to i128
48 ; CHECK-NEXT: --> {(1 + (sext i64 {(sext i32 (1 + %a) to i64),+,1}<%loop> to i128)),+,1}<%loop2>
49 entry:
50 br label %loop
51
52 loop:
53 %iv = phi i32 [ %a, %entry ], [ %iv.inc, %loop ]
54 %iv.inc = add nsw i32 %iv, 1
55 %cond = icmp sle i32 %iv.inc, 50
56 br i1 %cond, label %loop, label %between
57
58 between:
59 %se = sext i32 %iv.inc to i64
60 br label %loop2
61
62 loop2:
63 %iv2 = phi i64 [ %se, %between ], [ %iv2.inc, %loop2 ]
64 %iv2.inc = add nsw i64 %iv2, 1
65 %cond2 = icmp sle i64 %iv2.inc, 50
66 br i1 %cond2, label %loop2, label %exit
67
68 exit:
69 %se2 = sext i64 %iv2.inc to i128
70 ret void
71 }
72
73 define void @test_zext(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) {
74 ; CHECK-LABEL: @test_zext
75 ; CHECK: %ze2 = zext i64 %iv2.inc to i128
76 ; CHECK-NEXT: --> {(1 + (zext i64 {7,+,1}<%loop> to i128)),+,1}<%loop2>
77 entry:
78 br label %loop
79
80 loop:
81 %iv = phi i32 [ 6, %entry ], [ %iv.inc, %loop ]
82 %iv.inc = add nsw i32 %iv, 1
83 %cond = icmp sle i32 %iv.inc, 50
84 br i1 %cond, label %loop, label %between
85
86 between:
87 %ze = zext i32 %iv.inc to i64
88 br label %loop2
89
90 loop2:
91 %iv2 = phi i64 [ %ze, %between ], [ %iv2.inc, %loop2 ]
92 %iv2.inc = add nuw i64 %iv2, 1
93 %cond2 = icmp sle i64 %iv2.inc, 50
94 br i1 %cond2, label %loop2, label %exit
95
96 exit:
97 %ze2 = zext i64 %iv2.inc to i128
98 ret void
99 }