xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Utils/LoopConstrainer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f757f3fSDimitry Andric #include "llvm/Transforms/Utils/LoopConstrainer.h"
25f757f3fSDimitry Andric #include "llvm/Analysis/LoopInfo.h"
35f757f3fSDimitry Andric #include "llvm/Analysis/ScalarEvolution.h"
45f757f3fSDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpressions.h"
55f757f3fSDimitry Andric #include "llvm/IR/Dominators.h"
65f757f3fSDimitry Andric #include "llvm/Transforms/Utils/Cloning.h"
75f757f3fSDimitry Andric #include "llvm/Transforms/Utils/LoopSimplify.h"
85f757f3fSDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h"
95f757f3fSDimitry Andric #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
105f757f3fSDimitry Andric 
115f757f3fSDimitry Andric using namespace llvm;
125f757f3fSDimitry Andric 
135f757f3fSDimitry Andric static const char *ClonedLoopTag = "loop_constrainer.loop.clone";
145f757f3fSDimitry Andric 
155f757f3fSDimitry Andric #define DEBUG_TYPE "loop-constrainer"
165f757f3fSDimitry Andric 
175f757f3fSDimitry Andric /// Given a loop with an deccreasing induction variable, is it possible to
185f757f3fSDimitry Andric /// safely calculate the bounds of a new loop using the given Predicate.
195f757f3fSDimitry Andric static bool isSafeDecreasingBound(const SCEV *Start, const SCEV *BoundSCEV,
205f757f3fSDimitry Andric                                   const SCEV *Step, ICmpInst::Predicate Pred,
215f757f3fSDimitry Andric                                   unsigned LatchBrExitIdx, Loop *L,
225f757f3fSDimitry Andric                                   ScalarEvolution &SE) {
235f757f3fSDimitry Andric   if (Pred != ICmpInst::ICMP_SLT && Pred != ICmpInst::ICMP_SGT &&
245f757f3fSDimitry Andric       Pred != ICmpInst::ICMP_ULT && Pred != ICmpInst::ICMP_UGT)
255f757f3fSDimitry Andric     return false;
265f757f3fSDimitry Andric 
275f757f3fSDimitry Andric   if (!SE.isAvailableAtLoopEntry(BoundSCEV, L))
285f757f3fSDimitry Andric     return false;
295f757f3fSDimitry Andric 
305f757f3fSDimitry Andric   assert(SE.isKnownNegative(Step) && "expecting negative step");
315f757f3fSDimitry Andric 
325f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "isSafeDecreasingBound with:\n");
335f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "Start: " << *Start << "\n");
345f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "Step: " << *Step << "\n");
355f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "BoundSCEV: " << *BoundSCEV << "\n");
365f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "Pred: " << Pred << "\n");
375f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "LatchExitBrIdx: " << LatchBrExitIdx << "\n");
385f757f3fSDimitry Andric 
395f757f3fSDimitry Andric   bool IsSigned = ICmpInst::isSigned(Pred);
405f757f3fSDimitry Andric   // The predicate that we need to check that the induction variable lies
415f757f3fSDimitry Andric   // within bounds.
425f757f3fSDimitry Andric   ICmpInst::Predicate BoundPred =
435f757f3fSDimitry Andric       IsSigned ? CmpInst::ICMP_SGT : CmpInst::ICMP_UGT;
445f757f3fSDimitry Andric 
45*0fca6ea1SDimitry Andric   auto StartLG = SE.applyLoopGuards(Start, L);
46*0fca6ea1SDimitry Andric   auto BoundLG = SE.applyLoopGuards(BoundSCEV, L);
47*0fca6ea1SDimitry Andric 
485f757f3fSDimitry Andric   if (LatchBrExitIdx == 1)
49*0fca6ea1SDimitry Andric     return SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG, BoundLG);
505f757f3fSDimitry Andric 
515f757f3fSDimitry Andric   assert(LatchBrExitIdx == 0 && "LatchBrExitIdx should be either 0 or 1");
525f757f3fSDimitry Andric 
535f757f3fSDimitry Andric   const SCEV *StepPlusOne = SE.getAddExpr(Step, SE.getOne(Step->getType()));
545f757f3fSDimitry Andric   unsigned BitWidth = cast<IntegerType>(BoundSCEV->getType())->getBitWidth();
555f757f3fSDimitry Andric   APInt Min = IsSigned ? APInt::getSignedMinValue(BitWidth)
565f757f3fSDimitry Andric                        : APInt::getMinValue(BitWidth);
575f757f3fSDimitry Andric   const SCEV *Limit = SE.getMinusSCEV(SE.getConstant(Min), StepPlusOne);
585f757f3fSDimitry Andric 
595f757f3fSDimitry Andric   const SCEV *MinusOne =
60*0fca6ea1SDimitry Andric       SE.getMinusSCEV(BoundLG, SE.getOne(BoundLG->getType()));
615f757f3fSDimitry Andric 
62*0fca6ea1SDimitry Andric   return SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG, MinusOne) &&
63*0fca6ea1SDimitry Andric          SE.isLoopEntryGuardedByCond(L, BoundPred, BoundLG, Limit);
645f757f3fSDimitry Andric }
655f757f3fSDimitry Andric 
665f757f3fSDimitry Andric /// Given a loop with an increasing induction variable, is it possible to
675f757f3fSDimitry Andric /// safely calculate the bounds of a new loop using the given Predicate.
685f757f3fSDimitry Andric static bool isSafeIncreasingBound(const SCEV *Start, const SCEV *BoundSCEV,
695f757f3fSDimitry Andric                                   const SCEV *Step, ICmpInst::Predicate Pred,
705f757f3fSDimitry Andric                                   unsigned LatchBrExitIdx, Loop *L,
715f757f3fSDimitry Andric                                   ScalarEvolution &SE) {
725f757f3fSDimitry Andric   if (Pred != ICmpInst::ICMP_SLT && Pred != ICmpInst::ICMP_SGT &&
735f757f3fSDimitry Andric       Pred != ICmpInst::ICMP_ULT && Pred != ICmpInst::ICMP_UGT)
745f757f3fSDimitry Andric     return false;
755f757f3fSDimitry Andric 
765f757f3fSDimitry Andric   if (!SE.isAvailableAtLoopEntry(BoundSCEV, L))
775f757f3fSDimitry Andric     return false;
785f757f3fSDimitry Andric 
795f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "isSafeIncreasingBound with:\n");
805f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "Start: " << *Start << "\n");
815f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "Step: " << *Step << "\n");
825f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "BoundSCEV: " << *BoundSCEV << "\n");
835f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "Pred: " << Pred << "\n");
845f757f3fSDimitry Andric   LLVM_DEBUG(dbgs() << "LatchExitBrIdx: " << LatchBrExitIdx << "\n");
855f757f3fSDimitry Andric 
865f757f3fSDimitry Andric   bool IsSigned = ICmpInst::isSigned(Pred);
875f757f3fSDimitry Andric   // The predicate that we need to check that the induction variable lies
885f757f3fSDimitry Andric   // within bounds.
895f757f3fSDimitry Andric   ICmpInst::Predicate BoundPred =
905f757f3fSDimitry Andric       IsSigned ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT;
915f757f3fSDimitry Andric 
92*0fca6ea1SDimitry Andric   auto StartLG = SE.applyLoopGuards(Start, L);
93*0fca6ea1SDimitry Andric   auto BoundLG = SE.applyLoopGuards(BoundSCEV, L);
94*0fca6ea1SDimitry Andric 
955f757f3fSDimitry Andric   if (LatchBrExitIdx == 1)
96*0fca6ea1SDimitry Andric     return SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG, BoundLG);
975f757f3fSDimitry Andric 
985f757f3fSDimitry Andric   assert(LatchBrExitIdx == 0 && "LatchBrExitIdx should be 0 or 1");
995f757f3fSDimitry Andric 
1005f757f3fSDimitry Andric   const SCEV *StepMinusOne = SE.getMinusSCEV(Step, SE.getOne(Step->getType()));
1015f757f3fSDimitry Andric   unsigned BitWidth = cast<IntegerType>(BoundSCEV->getType())->getBitWidth();
1025f757f3fSDimitry Andric   APInt Max = IsSigned ? APInt::getSignedMaxValue(BitWidth)
1035f757f3fSDimitry Andric                        : APInt::getMaxValue(BitWidth);
1045f757f3fSDimitry Andric   const SCEV *Limit = SE.getMinusSCEV(SE.getConstant(Max), StepMinusOne);
1055f757f3fSDimitry Andric 
106*0fca6ea1SDimitry Andric   return (SE.isLoopEntryGuardedByCond(L, BoundPred, StartLG,
107*0fca6ea1SDimitry Andric                                       SE.getAddExpr(BoundLG, Step)) &&
108*0fca6ea1SDimitry Andric           SE.isLoopEntryGuardedByCond(L, BoundPred, BoundLG, Limit));
1095f757f3fSDimitry Andric }
1105f757f3fSDimitry Andric 
1115f757f3fSDimitry Andric /// Returns estimate for max latch taken count of the loop of the narrowest
1125f757f3fSDimitry Andric /// available type. If the latch block has such estimate, it is returned.
1135f757f3fSDimitry Andric /// Otherwise, we use max exit count of whole loop (that is potentially of wider
1145f757f3fSDimitry Andric /// type than latch check itself), which is still better than no estimate.
1155f757f3fSDimitry Andric static const SCEV *getNarrowestLatchMaxTakenCountEstimate(ScalarEvolution &SE,
1165f757f3fSDimitry Andric                                                           const Loop &L) {
1175f757f3fSDimitry Andric   const SCEV *FromBlock =
1185f757f3fSDimitry Andric       SE.getExitCount(&L, L.getLoopLatch(), ScalarEvolution::SymbolicMaximum);
1195f757f3fSDimitry Andric   if (isa<SCEVCouldNotCompute>(FromBlock))
1205f757f3fSDimitry Andric     return SE.getSymbolicMaxBackedgeTakenCount(&L);
1215f757f3fSDimitry Andric   return FromBlock;
1225f757f3fSDimitry Andric }
1235f757f3fSDimitry Andric 
1245f757f3fSDimitry Andric std::optional<LoopStructure>
1255f757f3fSDimitry Andric LoopStructure::parseLoopStructure(ScalarEvolution &SE, Loop &L,
1265f757f3fSDimitry Andric                                   bool AllowUnsignedLatchCond,
1275f757f3fSDimitry Andric                                   const char *&FailureReason) {
1285f757f3fSDimitry Andric   if (!L.isLoopSimplifyForm()) {
1295f757f3fSDimitry Andric     FailureReason = "loop not in LoopSimplify form";
1305f757f3fSDimitry Andric     return std::nullopt;
1315f757f3fSDimitry Andric   }
1325f757f3fSDimitry Andric 
1335f757f3fSDimitry Andric   BasicBlock *Latch = L.getLoopLatch();
1345f757f3fSDimitry Andric   assert(Latch && "Simplified loops only have one latch!");
1355f757f3fSDimitry Andric 
1365f757f3fSDimitry Andric   if (Latch->getTerminator()->getMetadata(ClonedLoopTag)) {
1375f757f3fSDimitry Andric     FailureReason = "loop has already been cloned";
1385f757f3fSDimitry Andric     return std::nullopt;
1395f757f3fSDimitry Andric   }
1405f757f3fSDimitry Andric 
1415f757f3fSDimitry Andric   if (!L.isLoopExiting(Latch)) {
1425f757f3fSDimitry Andric     FailureReason = "no loop latch";
1435f757f3fSDimitry Andric     return std::nullopt;
1445f757f3fSDimitry Andric   }
1455f757f3fSDimitry Andric 
1465f757f3fSDimitry Andric   BasicBlock *Header = L.getHeader();
1475f757f3fSDimitry Andric   BasicBlock *Preheader = L.getLoopPreheader();
1485f757f3fSDimitry Andric   if (!Preheader) {
1495f757f3fSDimitry Andric     FailureReason = "no preheader";
1505f757f3fSDimitry Andric     return std::nullopt;
1515f757f3fSDimitry Andric   }
1525f757f3fSDimitry Andric 
1535f757f3fSDimitry Andric   BranchInst *LatchBr = dyn_cast<BranchInst>(Latch->getTerminator());
1545f757f3fSDimitry Andric   if (!LatchBr || LatchBr->isUnconditional()) {
1555f757f3fSDimitry Andric     FailureReason = "latch terminator not conditional branch";
1565f757f3fSDimitry Andric     return std::nullopt;
1575f757f3fSDimitry Andric   }
1585f757f3fSDimitry Andric 
1595f757f3fSDimitry Andric   unsigned LatchBrExitIdx = LatchBr->getSuccessor(0) == Header ? 1 : 0;
1605f757f3fSDimitry Andric 
1615f757f3fSDimitry Andric   ICmpInst *ICI = dyn_cast<ICmpInst>(LatchBr->getCondition());
1625f757f3fSDimitry Andric   if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType())) {
1635f757f3fSDimitry Andric     FailureReason = "latch terminator branch not conditional on integral icmp";
1645f757f3fSDimitry Andric     return std::nullopt;
1655f757f3fSDimitry Andric   }
1665f757f3fSDimitry Andric 
1675f757f3fSDimitry Andric   const SCEV *MaxBETakenCount = getNarrowestLatchMaxTakenCountEstimate(SE, L);
1685f757f3fSDimitry Andric   if (isa<SCEVCouldNotCompute>(MaxBETakenCount)) {
1695f757f3fSDimitry Andric     FailureReason = "could not compute latch count";
1705f757f3fSDimitry Andric     return std::nullopt;
1715f757f3fSDimitry Andric   }
1725f757f3fSDimitry Andric   assert(SE.getLoopDisposition(MaxBETakenCount, &L) ==
1735f757f3fSDimitry Andric              ScalarEvolution::LoopInvariant &&
1745f757f3fSDimitry Andric          "loop variant exit count doesn't make sense!");
1755f757f3fSDimitry Andric 
1765f757f3fSDimitry Andric   ICmpInst::Predicate Pred = ICI->getPredicate();
1775f757f3fSDimitry Andric   Value *LeftValue = ICI->getOperand(0);
1785f757f3fSDimitry Andric   const SCEV *LeftSCEV = SE.getSCEV(LeftValue);
1795f757f3fSDimitry Andric   IntegerType *IndVarTy = cast<IntegerType>(LeftValue->getType());
1805f757f3fSDimitry Andric 
1815f757f3fSDimitry Andric   Value *RightValue = ICI->getOperand(1);
1825f757f3fSDimitry Andric   const SCEV *RightSCEV = SE.getSCEV(RightValue);
1835f757f3fSDimitry Andric 
1845f757f3fSDimitry Andric   // We canonicalize `ICI` such that `LeftSCEV` is an add recurrence.
1855f757f3fSDimitry Andric   if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
1865f757f3fSDimitry Andric     if (isa<SCEVAddRecExpr>(RightSCEV)) {
1875f757f3fSDimitry Andric       std::swap(LeftSCEV, RightSCEV);
1885f757f3fSDimitry Andric       std::swap(LeftValue, RightValue);
1895f757f3fSDimitry Andric       Pred = ICmpInst::getSwappedPredicate(Pred);
1905f757f3fSDimitry Andric     } else {
1915f757f3fSDimitry Andric       FailureReason = "no add recurrences in the icmp";
1925f757f3fSDimitry Andric       return std::nullopt;
1935f757f3fSDimitry Andric     }
1945f757f3fSDimitry Andric   }
1955f757f3fSDimitry Andric 
1965f757f3fSDimitry Andric   auto HasNoSignedWrap = [&](const SCEVAddRecExpr *AR) {
1975f757f3fSDimitry Andric     if (AR->getNoWrapFlags(SCEV::FlagNSW))
1985f757f3fSDimitry Andric       return true;
1995f757f3fSDimitry Andric 
2005f757f3fSDimitry Andric     IntegerType *Ty = cast<IntegerType>(AR->getType());
2015f757f3fSDimitry Andric     IntegerType *WideTy =
2025f757f3fSDimitry Andric         IntegerType::get(Ty->getContext(), Ty->getBitWidth() * 2);
2035f757f3fSDimitry Andric 
2045f757f3fSDimitry Andric     const SCEVAddRecExpr *ExtendAfterOp =
2055f757f3fSDimitry Andric         dyn_cast<SCEVAddRecExpr>(SE.getSignExtendExpr(AR, WideTy));
2065f757f3fSDimitry Andric     if (ExtendAfterOp) {
2075f757f3fSDimitry Andric       const SCEV *ExtendedStart = SE.getSignExtendExpr(AR->getStart(), WideTy);
2085f757f3fSDimitry Andric       const SCEV *ExtendedStep =
2095f757f3fSDimitry Andric           SE.getSignExtendExpr(AR->getStepRecurrence(SE), WideTy);
2105f757f3fSDimitry Andric 
2115f757f3fSDimitry Andric       bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart &&
2125f757f3fSDimitry Andric                           ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep;
2135f757f3fSDimitry Andric 
2145f757f3fSDimitry Andric       if (NoSignedWrap)
2155f757f3fSDimitry Andric         return true;
2165f757f3fSDimitry Andric     }
2175f757f3fSDimitry Andric 
2185f757f3fSDimitry Andric     // We may have proved this when computing the sign extension above.
2195f757f3fSDimitry Andric     return AR->getNoWrapFlags(SCEV::FlagNSW) != SCEV::FlagAnyWrap;
2205f757f3fSDimitry Andric   };
2215f757f3fSDimitry Andric 
2225f757f3fSDimitry Andric   // `ICI` is interpreted as taking the backedge if the *next* value of the
2235f757f3fSDimitry Andric   // induction variable satisfies some constraint.
2245f757f3fSDimitry Andric 
2255f757f3fSDimitry Andric   const SCEVAddRecExpr *IndVarBase = cast<SCEVAddRecExpr>(LeftSCEV);
2265f757f3fSDimitry Andric   if (IndVarBase->getLoop() != &L) {
2275f757f3fSDimitry Andric     FailureReason = "LHS in cmp is not an AddRec for this loop";
2285f757f3fSDimitry Andric     return std::nullopt;
2295f757f3fSDimitry Andric   }
2305f757f3fSDimitry Andric   if (!IndVarBase->isAffine()) {
2315f757f3fSDimitry Andric     FailureReason = "LHS in icmp not induction variable";
2325f757f3fSDimitry Andric     return std::nullopt;
2335f757f3fSDimitry Andric   }
2345f757f3fSDimitry Andric   const SCEV *StepRec = IndVarBase->getStepRecurrence(SE);
2355f757f3fSDimitry Andric   if (!isa<SCEVConstant>(StepRec)) {
2365f757f3fSDimitry Andric     FailureReason = "LHS in icmp not induction variable";
2375f757f3fSDimitry Andric     return std::nullopt;
2385f757f3fSDimitry Andric   }
2395f757f3fSDimitry Andric   ConstantInt *StepCI = cast<SCEVConstant>(StepRec)->getValue();
2405f757f3fSDimitry Andric 
2415f757f3fSDimitry Andric   if (ICI->isEquality() && !HasNoSignedWrap(IndVarBase)) {
2425f757f3fSDimitry Andric     FailureReason = "LHS in icmp needs nsw for equality predicates";
2435f757f3fSDimitry Andric     return std::nullopt;
2445f757f3fSDimitry Andric   }
2455f757f3fSDimitry Andric 
2465f757f3fSDimitry Andric   assert(!StepCI->isZero() && "Zero step?");
2475f757f3fSDimitry Andric   bool IsIncreasing = !StepCI->isNegative();
2485f757f3fSDimitry Andric   bool IsSignedPredicate;
2495f757f3fSDimitry Andric   const SCEV *StartNext = IndVarBase->getStart();
2505f757f3fSDimitry Andric   const SCEV *Addend = SE.getNegativeSCEV(IndVarBase->getStepRecurrence(SE));
2515f757f3fSDimitry Andric   const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend);
2525f757f3fSDimitry Andric   const SCEV *Step = SE.getSCEV(StepCI);
2535f757f3fSDimitry Andric 
2545f757f3fSDimitry Andric   const SCEV *FixedRightSCEV = nullptr;
2555f757f3fSDimitry Andric 
2565f757f3fSDimitry Andric   // If RightValue resides within loop (but still being loop invariant),
2575f757f3fSDimitry Andric   // regenerate it as preheader.
2585f757f3fSDimitry Andric   if (auto *I = dyn_cast<Instruction>(RightValue))
2595f757f3fSDimitry Andric     if (L.contains(I->getParent()))
2605f757f3fSDimitry Andric       FixedRightSCEV = RightSCEV;
2615f757f3fSDimitry Andric 
2625f757f3fSDimitry Andric   if (IsIncreasing) {
2635f757f3fSDimitry Andric     bool DecreasedRightValueByOne = false;
2645f757f3fSDimitry Andric     if (StepCI->isOne()) {
2655f757f3fSDimitry Andric       // Try to turn eq/ne predicates to those we can work with.
2665f757f3fSDimitry Andric       if (Pred == ICmpInst::ICMP_NE && LatchBrExitIdx == 1)
2675f757f3fSDimitry Andric         // while (++i != len) {         while (++i < len) {
2685f757f3fSDimitry Andric         //   ...                 --->     ...
2695f757f3fSDimitry Andric         // }                            }
2705f757f3fSDimitry Andric         // If both parts are known non-negative, it is profitable to use
2715f757f3fSDimitry Andric         // unsigned comparison in increasing loop. This allows us to make the
2725f757f3fSDimitry Andric         // comparison check against "RightSCEV + 1" more optimistic.
2735f757f3fSDimitry Andric         if (isKnownNonNegativeInLoop(IndVarStart, &L, SE) &&
2745f757f3fSDimitry Andric             isKnownNonNegativeInLoop(RightSCEV, &L, SE))
2755f757f3fSDimitry Andric           Pred = ICmpInst::ICMP_ULT;
2765f757f3fSDimitry Andric         else
2775f757f3fSDimitry Andric           Pred = ICmpInst::ICMP_SLT;
2785f757f3fSDimitry Andric       else if (Pred == ICmpInst::ICMP_EQ && LatchBrExitIdx == 0) {
2795f757f3fSDimitry Andric         // while (true) {               while (true) {
2805f757f3fSDimitry Andric         //   if (++i == len)     --->     if (++i > len - 1)
2815f757f3fSDimitry Andric         //     break;                       break;
2825f757f3fSDimitry Andric         //   ...                          ...
2835f757f3fSDimitry Andric         // }                            }
2845f757f3fSDimitry Andric         if (IndVarBase->getNoWrapFlags(SCEV::FlagNUW) &&
2855f757f3fSDimitry Andric             cannotBeMinInLoop(RightSCEV, &L, SE, /*Signed*/ false)) {
2865f757f3fSDimitry Andric           Pred = ICmpInst::ICMP_UGT;
2875f757f3fSDimitry Andric           RightSCEV =
2885f757f3fSDimitry Andric               SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType()));
2895f757f3fSDimitry Andric           DecreasedRightValueByOne = true;
2905f757f3fSDimitry Andric         } else if (cannotBeMinInLoop(RightSCEV, &L, SE, /*Signed*/ true)) {
2915f757f3fSDimitry Andric           Pred = ICmpInst::ICMP_SGT;
2925f757f3fSDimitry Andric           RightSCEV =
2935f757f3fSDimitry Andric               SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType()));
2945f757f3fSDimitry Andric           DecreasedRightValueByOne = true;
2955f757f3fSDimitry Andric         }
2965f757f3fSDimitry Andric       }
2975f757f3fSDimitry Andric     }
2985f757f3fSDimitry Andric 
2995f757f3fSDimitry Andric     bool LTPred = (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT);
3005f757f3fSDimitry Andric     bool GTPred = (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT);
3015f757f3fSDimitry Andric     bool FoundExpectedPred =
3025f757f3fSDimitry Andric         (LTPred && LatchBrExitIdx == 1) || (GTPred && LatchBrExitIdx == 0);
3035f757f3fSDimitry Andric 
3045f757f3fSDimitry Andric     if (!FoundExpectedPred) {
3055f757f3fSDimitry Andric       FailureReason = "expected icmp slt semantically, found something else";
3065f757f3fSDimitry Andric       return std::nullopt;
3075f757f3fSDimitry Andric     }
3085f757f3fSDimitry Andric 
3095f757f3fSDimitry Andric     IsSignedPredicate = ICmpInst::isSigned(Pred);
3105f757f3fSDimitry Andric     if (!IsSignedPredicate && !AllowUnsignedLatchCond) {
3115f757f3fSDimitry Andric       FailureReason = "unsigned latch conditions are explicitly prohibited";
3125f757f3fSDimitry Andric       return std::nullopt;
3135f757f3fSDimitry Andric     }
3145f757f3fSDimitry Andric 
3155f757f3fSDimitry Andric     if (!isSafeIncreasingBound(IndVarStart, RightSCEV, Step, Pred,
3165f757f3fSDimitry Andric                                LatchBrExitIdx, &L, SE)) {
3175f757f3fSDimitry Andric       FailureReason = "Unsafe loop bounds";
3185f757f3fSDimitry Andric       return std::nullopt;
3195f757f3fSDimitry Andric     }
3205f757f3fSDimitry Andric     if (LatchBrExitIdx == 0) {
3215f757f3fSDimitry Andric       // We need to increase the right value unless we have already decreased
3225f757f3fSDimitry Andric       // it virtually when we replaced EQ with SGT.
3235f757f3fSDimitry Andric       if (!DecreasedRightValueByOne)
3245f757f3fSDimitry Andric         FixedRightSCEV =
3255f757f3fSDimitry Andric             SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType()));
3265f757f3fSDimitry Andric     } else {
3275f757f3fSDimitry Andric       assert(!DecreasedRightValueByOne &&
3285f757f3fSDimitry Andric              "Right value can be decreased only for LatchBrExitIdx == 0!");
3295f757f3fSDimitry Andric     }
3305f757f3fSDimitry Andric   } else {
3315f757f3fSDimitry Andric     bool IncreasedRightValueByOne = false;
3325f757f3fSDimitry Andric     if (StepCI->isMinusOne()) {
3335f757f3fSDimitry Andric       // Try to turn eq/ne predicates to those we can work with.
3345f757f3fSDimitry Andric       if (Pred == ICmpInst::ICMP_NE && LatchBrExitIdx == 1)
3355f757f3fSDimitry Andric         // while (--i != len) {         while (--i > len) {
3365f757f3fSDimitry Andric         //   ...                 --->     ...
3375f757f3fSDimitry Andric         // }                            }
3385f757f3fSDimitry Andric         // We intentionally don't turn the predicate into UGT even if we know
3395f757f3fSDimitry Andric         // that both operands are non-negative, because it will only pessimize
3405f757f3fSDimitry Andric         // our check against "RightSCEV - 1".
3415f757f3fSDimitry Andric         Pred = ICmpInst::ICMP_SGT;
3425f757f3fSDimitry Andric       else if (Pred == ICmpInst::ICMP_EQ && LatchBrExitIdx == 0) {
3435f757f3fSDimitry Andric         // while (true) {               while (true) {
3445f757f3fSDimitry Andric         //   if (--i == len)     --->     if (--i < len + 1)
3455f757f3fSDimitry Andric         //     break;                       break;
3465f757f3fSDimitry Andric         //   ...                          ...
3475f757f3fSDimitry Andric         // }                            }
3485f757f3fSDimitry Andric         if (IndVarBase->getNoWrapFlags(SCEV::FlagNUW) &&
3495f757f3fSDimitry Andric             cannotBeMaxInLoop(RightSCEV, &L, SE, /* Signed */ false)) {
3505f757f3fSDimitry Andric           Pred = ICmpInst::ICMP_ULT;
3515f757f3fSDimitry Andric           RightSCEV = SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType()));
3525f757f3fSDimitry Andric           IncreasedRightValueByOne = true;
3535f757f3fSDimitry Andric         } else if (cannotBeMaxInLoop(RightSCEV, &L, SE, /* Signed */ true)) {
3545f757f3fSDimitry Andric           Pred = ICmpInst::ICMP_SLT;
3555f757f3fSDimitry Andric           RightSCEV = SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType()));
3565f757f3fSDimitry Andric           IncreasedRightValueByOne = true;
3575f757f3fSDimitry Andric         }
3585f757f3fSDimitry Andric       }
3595f757f3fSDimitry Andric     }
3605f757f3fSDimitry Andric 
3615f757f3fSDimitry Andric     bool LTPred = (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT);
3625f757f3fSDimitry Andric     bool GTPred = (Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT);
3635f757f3fSDimitry Andric 
3645f757f3fSDimitry Andric     bool FoundExpectedPred =
3655f757f3fSDimitry Andric         (GTPred && LatchBrExitIdx == 1) || (LTPred && LatchBrExitIdx == 0);
3665f757f3fSDimitry Andric 
3675f757f3fSDimitry Andric     if (!FoundExpectedPred) {
3685f757f3fSDimitry Andric       FailureReason = "expected icmp sgt semantically, found something else";
3695f757f3fSDimitry Andric       return std::nullopt;
3705f757f3fSDimitry Andric     }
3715f757f3fSDimitry Andric 
3725f757f3fSDimitry Andric     IsSignedPredicate =
3735f757f3fSDimitry Andric         Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGT;
3745f757f3fSDimitry Andric 
3755f757f3fSDimitry Andric     if (!IsSignedPredicate && !AllowUnsignedLatchCond) {
3765f757f3fSDimitry Andric       FailureReason = "unsigned latch conditions are explicitly prohibited";
3775f757f3fSDimitry Andric       return std::nullopt;
3785f757f3fSDimitry Andric     }
3795f757f3fSDimitry Andric 
3805f757f3fSDimitry Andric     if (!isSafeDecreasingBound(IndVarStart, RightSCEV, Step, Pred,
3815f757f3fSDimitry Andric                                LatchBrExitIdx, &L, SE)) {
3825f757f3fSDimitry Andric       FailureReason = "Unsafe bounds";
3835f757f3fSDimitry Andric       return std::nullopt;
3845f757f3fSDimitry Andric     }
3855f757f3fSDimitry Andric 
3865f757f3fSDimitry Andric     if (LatchBrExitIdx == 0) {
3875f757f3fSDimitry Andric       // We need to decrease the right value unless we have already increased
3885f757f3fSDimitry Andric       // it virtually when we replaced EQ with SLT.
3895f757f3fSDimitry Andric       if (!IncreasedRightValueByOne)
3905f757f3fSDimitry Andric         FixedRightSCEV =
3915f757f3fSDimitry Andric             SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType()));
3925f757f3fSDimitry Andric     } else {
3935f757f3fSDimitry Andric       assert(!IncreasedRightValueByOne &&
3945f757f3fSDimitry Andric              "Right value can be increased only for LatchBrExitIdx == 0!");
3955f757f3fSDimitry Andric     }
3965f757f3fSDimitry Andric   }
3975f757f3fSDimitry Andric   BasicBlock *LatchExit = LatchBr->getSuccessor(LatchBrExitIdx);
3985f757f3fSDimitry Andric 
3995f757f3fSDimitry Andric   assert(!L.contains(LatchExit) && "expected an exit block!");
400*0fca6ea1SDimitry Andric   const DataLayout &DL = Preheader->getDataLayout();
4015f757f3fSDimitry Andric   SCEVExpander Expander(SE, DL, "loop-constrainer");
4025f757f3fSDimitry Andric   Instruction *Ins = Preheader->getTerminator();
4035f757f3fSDimitry Andric 
4045f757f3fSDimitry Andric   if (FixedRightSCEV)
4055f757f3fSDimitry Andric     RightValue =
4065f757f3fSDimitry Andric         Expander.expandCodeFor(FixedRightSCEV, FixedRightSCEV->getType(), Ins);
4075f757f3fSDimitry Andric 
4085f757f3fSDimitry Andric   Value *IndVarStartV = Expander.expandCodeFor(IndVarStart, IndVarTy, Ins);
4095f757f3fSDimitry Andric   IndVarStartV->setName("indvar.start");
4105f757f3fSDimitry Andric 
4115f757f3fSDimitry Andric   LoopStructure Result;
4125f757f3fSDimitry Andric 
4135f757f3fSDimitry Andric   Result.Tag = "main";
4145f757f3fSDimitry Andric   Result.Header = Header;
4155f757f3fSDimitry Andric   Result.Latch = Latch;
4165f757f3fSDimitry Andric   Result.LatchBr = LatchBr;
4175f757f3fSDimitry Andric   Result.LatchExit = LatchExit;
4185f757f3fSDimitry Andric   Result.LatchBrExitIdx = LatchBrExitIdx;
4195f757f3fSDimitry Andric   Result.IndVarStart = IndVarStartV;
4205f757f3fSDimitry Andric   Result.IndVarStep = StepCI;
4215f757f3fSDimitry Andric   Result.IndVarBase = LeftValue;
4225f757f3fSDimitry Andric   Result.IndVarIncreasing = IsIncreasing;
4235f757f3fSDimitry Andric   Result.LoopExitAt = RightValue;
4245f757f3fSDimitry Andric   Result.IsSignedPredicate = IsSignedPredicate;
4255f757f3fSDimitry Andric   Result.ExitCountTy = cast<IntegerType>(MaxBETakenCount->getType());
4265f757f3fSDimitry Andric 
4275f757f3fSDimitry Andric   FailureReason = nullptr;
4285f757f3fSDimitry Andric 
4295f757f3fSDimitry Andric   return Result;
4305f757f3fSDimitry Andric }
4315f757f3fSDimitry Andric 
4325f757f3fSDimitry Andric // Add metadata to the loop L to disable loop optimizations. Callers need to
4335f757f3fSDimitry Andric // confirm that optimizing loop L is not beneficial.
4345f757f3fSDimitry Andric static void DisableAllLoopOptsOnLoop(Loop &L) {
4355f757f3fSDimitry Andric   // We do not care about any existing loopID related metadata for L, since we
4365f757f3fSDimitry Andric   // are setting all loop metadata to false.
4375f757f3fSDimitry Andric   LLVMContext &Context = L.getHeader()->getContext();
4385f757f3fSDimitry Andric   // Reserve first location for self reference to the LoopID metadata node.
4395f757f3fSDimitry Andric   MDNode *Dummy = MDNode::get(Context, {});
4405f757f3fSDimitry Andric   MDNode *DisableUnroll = MDNode::get(
4415f757f3fSDimitry Andric       Context, {MDString::get(Context, "llvm.loop.unroll.disable")});
4425f757f3fSDimitry Andric   Metadata *FalseVal =
4435f757f3fSDimitry Andric       ConstantAsMetadata::get(ConstantInt::get(Type::getInt1Ty(Context), 0));
4445f757f3fSDimitry Andric   MDNode *DisableVectorize = MDNode::get(
4455f757f3fSDimitry Andric       Context,
4465f757f3fSDimitry Andric       {MDString::get(Context, "llvm.loop.vectorize.enable"), FalseVal});
4475f757f3fSDimitry Andric   MDNode *DisableLICMVersioning = MDNode::get(
4485f757f3fSDimitry Andric       Context, {MDString::get(Context, "llvm.loop.licm_versioning.disable")});
4495f757f3fSDimitry Andric   MDNode *DisableDistribution = MDNode::get(
4505f757f3fSDimitry Andric       Context,
4515f757f3fSDimitry Andric       {MDString::get(Context, "llvm.loop.distribute.enable"), FalseVal});
4525f757f3fSDimitry Andric   MDNode *NewLoopID =
4535f757f3fSDimitry Andric       MDNode::get(Context, {Dummy, DisableUnroll, DisableVectorize,
4545f757f3fSDimitry Andric                             DisableLICMVersioning, DisableDistribution});
4555f757f3fSDimitry Andric   // Set operand 0 to refer to the loop id itself.
4565f757f3fSDimitry Andric   NewLoopID->replaceOperandWith(0, NewLoopID);
4575f757f3fSDimitry Andric   L.setLoopID(NewLoopID);
4585f757f3fSDimitry Andric }
4595f757f3fSDimitry Andric 
4605f757f3fSDimitry Andric LoopConstrainer::LoopConstrainer(Loop &L, LoopInfo &LI,
4615f757f3fSDimitry Andric                                  function_ref<void(Loop *, bool)> LPMAddNewLoop,
4625f757f3fSDimitry Andric                                  const LoopStructure &LS, ScalarEvolution &SE,
4635f757f3fSDimitry Andric                                  DominatorTree &DT, Type *T, SubRanges SR)
4645f757f3fSDimitry Andric     : F(*L.getHeader()->getParent()), Ctx(L.getHeader()->getContext()), SE(SE),
4655f757f3fSDimitry Andric       DT(DT), LI(LI), LPMAddNewLoop(LPMAddNewLoop), OriginalLoop(L), RangeTy(T),
4665f757f3fSDimitry Andric       MainLoopStructure(LS), SR(SR) {}
4675f757f3fSDimitry Andric 
4685f757f3fSDimitry Andric void LoopConstrainer::cloneLoop(LoopConstrainer::ClonedLoop &Result,
4695f757f3fSDimitry Andric                                 const char *Tag) const {
4705f757f3fSDimitry Andric   for (BasicBlock *BB : OriginalLoop.getBlocks()) {
4715f757f3fSDimitry Andric     BasicBlock *Clone = CloneBasicBlock(BB, Result.Map, Twine(".") + Tag, &F);
4725f757f3fSDimitry Andric     Result.Blocks.push_back(Clone);
4735f757f3fSDimitry Andric     Result.Map[BB] = Clone;
4745f757f3fSDimitry Andric   }
4755f757f3fSDimitry Andric 
4765f757f3fSDimitry Andric   auto GetClonedValue = [&Result](Value *V) {
4775f757f3fSDimitry Andric     assert(V && "null values not in domain!");
4785f757f3fSDimitry Andric     auto It = Result.Map.find(V);
4795f757f3fSDimitry Andric     if (It == Result.Map.end())
4805f757f3fSDimitry Andric       return V;
4815f757f3fSDimitry Andric     return static_cast<Value *>(It->second);
4825f757f3fSDimitry Andric   };
4835f757f3fSDimitry Andric 
4845f757f3fSDimitry Andric   auto *ClonedLatch =
4855f757f3fSDimitry Andric       cast<BasicBlock>(GetClonedValue(OriginalLoop.getLoopLatch()));
4865f757f3fSDimitry Andric   ClonedLatch->getTerminator()->setMetadata(ClonedLoopTag,
4875f757f3fSDimitry Andric                                             MDNode::get(Ctx, {}));
4885f757f3fSDimitry Andric 
4895f757f3fSDimitry Andric   Result.Structure = MainLoopStructure.map(GetClonedValue);
4905f757f3fSDimitry Andric   Result.Structure.Tag = Tag;
4915f757f3fSDimitry Andric 
4925f757f3fSDimitry Andric   for (unsigned i = 0, e = Result.Blocks.size(); i != e; ++i) {
4935f757f3fSDimitry Andric     BasicBlock *ClonedBB = Result.Blocks[i];
4945f757f3fSDimitry Andric     BasicBlock *OriginalBB = OriginalLoop.getBlocks()[i];
4955f757f3fSDimitry Andric 
4965f757f3fSDimitry Andric     assert(Result.Map[OriginalBB] == ClonedBB && "invariant!");
4975f757f3fSDimitry Andric 
4985f757f3fSDimitry Andric     for (Instruction &I : *ClonedBB)
4995f757f3fSDimitry Andric       RemapInstruction(&I, Result.Map,
5005f757f3fSDimitry Andric                        RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
5015f757f3fSDimitry Andric 
5025f757f3fSDimitry Andric     // Exit blocks will now have one more predecessor and their PHI nodes need
5035f757f3fSDimitry Andric     // to be edited to reflect that.  No phi nodes need to be introduced because
5045f757f3fSDimitry Andric     // the loop is in LCSSA.
5055f757f3fSDimitry Andric 
5065f757f3fSDimitry Andric     for (auto *SBB : successors(OriginalBB)) {
5075f757f3fSDimitry Andric       if (OriginalLoop.contains(SBB))
5085f757f3fSDimitry Andric         continue; // not an exit block
5095f757f3fSDimitry Andric 
5105f757f3fSDimitry Andric       for (PHINode &PN : SBB->phis()) {
5115f757f3fSDimitry Andric         Value *OldIncoming = PN.getIncomingValueForBlock(OriginalBB);
5125f757f3fSDimitry Andric         PN.addIncoming(GetClonedValue(OldIncoming), ClonedBB);
5135f757f3fSDimitry Andric         SE.forgetValue(&PN);
5145f757f3fSDimitry Andric       }
5155f757f3fSDimitry Andric     }
5165f757f3fSDimitry Andric   }
5175f757f3fSDimitry Andric }
5185f757f3fSDimitry Andric 
5195f757f3fSDimitry Andric LoopConstrainer::RewrittenRangeInfo LoopConstrainer::changeIterationSpaceEnd(
5205f757f3fSDimitry Andric     const LoopStructure &LS, BasicBlock *Preheader, Value *ExitSubloopAt,
5215f757f3fSDimitry Andric     BasicBlock *ContinuationBlock) const {
5225f757f3fSDimitry Andric   // We start with a loop with a single latch:
5235f757f3fSDimitry Andric   //
5245f757f3fSDimitry Andric   //    +--------------------+
5255f757f3fSDimitry Andric   //    |                    |
5265f757f3fSDimitry Andric   //    |     preheader      |
5275f757f3fSDimitry Andric   //    |                    |
5285f757f3fSDimitry Andric   //    +--------+-----------+
5295f757f3fSDimitry Andric   //             |      ----------------\
5305f757f3fSDimitry Andric   //             |     /                |
5315f757f3fSDimitry Andric   //    +--------v----v------+          |
5325f757f3fSDimitry Andric   //    |                    |          |
5335f757f3fSDimitry Andric   //    |      header        |          |
5345f757f3fSDimitry Andric   //    |                    |          |
5355f757f3fSDimitry Andric   //    +--------------------+          |
5365f757f3fSDimitry Andric   //                                    |
5375f757f3fSDimitry Andric   //            .....                   |
5385f757f3fSDimitry Andric   //                                    |
5395f757f3fSDimitry Andric   //    +--------------------+          |
5405f757f3fSDimitry Andric   //    |                    |          |
5415f757f3fSDimitry Andric   //    |       latch        >----------/
5425f757f3fSDimitry Andric   //    |                    |
5435f757f3fSDimitry Andric   //    +-------v------------+
5445f757f3fSDimitry Andric   //            |
5455f757f3fSDimitry Andric   //            |
5465f757f3fSDimitry Andric   //            |   +--------------------+
5475f757f3fSDimitry Andric   //            |   |                    |
5485f757f3fSDimitry Andric   //            +--->   original exit    |
5495f757f3fSDimitry Andric   //                |                    |
5505f757f3fSDimitry Andric   //                +--------------------+
5515f757f3fSDimitry Andric   //
5525f757f3fSDimitry Andric   // We change the control flow to look like
5535f757f3fSDimitry Andric   //
5545f757f3fSDimitry Andric   //
5555f757f3fSDimitry Andric   //    +--------------------+
5565f757f3fSDimitry Andric   //    |                    |
5575f757f3fSDimitry Andric   //    |     preheader      >-------------------------+
5585f757f3fSDimitry Andric   //    |                    |                         |
5595f757f3fSDimitry Andric   //    +--------v-----------+                         |
5605f757f3fSDimitry Andric   //             |    /-------------+                  |
5615f757f3fSDimitry Andric   //             |   /              |                  |
5625f757f3fSDimitry Andric   //    +--------v--v--------+      |                  |
5635f757f3fSDimitry Andric   //    |                    |      |                  |
5645f757f3fSDimitry Andric   //    |      header        |      |   +--------+     |
5655f757f3fSDimitry Andric   //    |                    |      |   |        |     |
5665f757f3fSDimitry Andric   //    +--------------------+      |   |  +-----v-----v-----------+
5675f757f3fSDimitry Andric   //                                |   |  |                       |
5685f757f3fSDimitry Andric   //                                |   |  |     .pseudo.exit      |
5695f757f3fSDimitry Andric   //                                |   |  |                       |
5705f757f3fSDimitry Andric   //                                |   |  +-----------v-----------+
5715f757f3fSDimitry Andric   //                                |   |              |
5725f757f3fSDimitry Andric   //            .....               |   |              |
5735f757f3fSDimitry Andric   //                                |   |     +--------v-------------+
5745f757f3fSDimitry Andric   //    +--------------------+      |   |     |                      |
5755f757f3fSDimitry Andric   //    |                    |      |   |     |   ContinuationBlock  |
5765f757f3fSDimitry Andric   //    |       latch        >------+   |     |                      |
5775f757f3fSDimitry Andric   //    |                    |          |     +----------------------+
5785f757f3fSDimitry Andric   //    +---------v----------+          |
5795f757f3fSDimitry Andric   //              |                     |
5805f757f3fSDimitry Andric   //              |                     |
5815f757f3fSDimitry Andric   //              |     +---------------^-----+
5825f757f3fSDimitry Andric   //              |     |                     |
5835f757f3fSDimitry Andric   //              +----->    .exit.selector   |
5845f757f3fSDimitry Andric   //                    |                     |
5855f757f3fSDimitry Andric   //                    +----------v----------+
5865f757f3fSDimitry Andric   //                               |
5875f757f3fSDimitry Andric   //     +--------------------+    |
5885f757f3fSDimitry Andric   //     |                    |    |
5895f757f3fSDimitry Andric   //     |   original exit    <----+
5905f757f3fSDimitry Andric   //     |                    |
5915f757f3fSDimitry Andric   //     +--------------------+
5925f757f3fSDimitry Andric 
5935f757f3fSDimitry Andric   RewrittenRangeInfo RRI;
5945f757f3fSDimitry Andric 
5955f757f3fSDimitry Andric   BasicBlock *BBInsertLocation = LS.Latch->getNextNode();
5965f757f3fSDimitry Andric   RRI.ExitSelector = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".exit.selector",
5975f757f3fSDimitry Andric                                         &F, BBInsertLocation);
5985f757f3fSDimitry Andric   RRI.PseudoExit = BasicBlock::Create(Ctx, Twine(LS.Tag) + ".pseudo.exit", &F,
5995f757f3fSDimitry Andric                                       BBInsertLocation);
6005f757f3fSDimitry Andric 
6015f757f3fSDimitry Andric   BranchInst *PreheaderJump = cast<BranchInst>(Preheader->getTerminator());
6025f757f3fSDimitry Andric   bool Increasing = LS.IndVarIncreasing;
6035f757f3fSDimitry Andric   bool IsSignedPredicate = LS.IsSignedPredicate;
6045f757f3fSDimitry Andric 
6055f757f3fSDimitry Andric   IRBuilder<> B(PreheaderJump);
6065f757f3fSDimitry Andric   auto NoopOrExt = [&](Value *V) {
6075f757f3fSDimitry Andric     if (V->getType() == RangeTy)
6085f757f3fSDimitry Andric       return V;
6095f757f3fSDimitry Andric     return IsSignedPredicate ? B.CreateSExt(V, RangeTy, "wide." + V->getName())
6105f757f3fSDimitry Andric                              : B.CreateZExt(V, RangeTy, "wide." + V->getName());
6115f757f3fSDimitry Andric   };
6125f757f3fSDimitry Andric 
6135f757f3fSDimitry Andric   // EnterLoopCond - is it okay to start executing this `LS'?
6145f757f3fSDimitry Andric   Value *EnterLoopCond = nullptr;
6155f757f3fSDimitry Andric   auto Pred =
6165f757f3fSDimitry Andric       Increasing
6175f757f3fSDimitry Andric           ? (IsSignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT)
6185f757f3fSDimitry Andric           : (IsSignedPredicate ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT);
6195f757f3fSDimitry Andric   Value *IndVarStart = NoopOrExt(LS.IndVarStart);
6205f757f3fSDimitry Andric   EnterLoopCond = B.CreateICmp(Pred, IndVarStart, ExitSubloopAt);
6215f757f3fSDimitry Andric 
6225f757f3fSDimitry Andric   B.CreateCondBr(EnterLoopCond, LS.Header, RRI.PseudoExit);
6235f757f3fSDimitry Andric   PreheaderJump->eraseFromParent();
6245f757f3fSDimitry Andric 
6255f757f3fSDimitry Andric   LS.LatchBr->setSuccessor(LS.LatchBrExitIdx, RRI.ExitSelector);
6265f757f3fSDimitry Andric   B.SetInsertPoint(LS.LatchBr);
6275f757f3fSDimitry Andric   Value *IndVarBase = NoopOrExt(LS.IndVarBase);
6285f757f3fSDimitry Andric   Value *TakeBackedgeLoopCond = B.CreateICmp(Pred, IndVarBase, ExitSubloopAt);
6295f757f3fSDimitry Andric 
6305f757f3fSDimitry Andric   Value *CondForBranch = LS.LatchBrExitIdx == 1
6315f757f3fSDimitry Andric                              ? TakeBackedgeLoopCond
6325f757f3fSDimitry Andric                              : B.CreateNot(TakeBackedgeLoopCond);
6335f757f3fSDimitry Andric 
6345f757f3fSDimitry Andric   LS.LatchBr->setCondition(CondForBranch);
6355f757f3fSDimitry Andric 
6365f757f3fSDimitry Andric   B.SetInsertPoint(RRI.ExitSelector);
6375f757f3fSDimitry Andric 
6385f757f3fSDimitry Andric   // IterationsLeft - are there any more iterations left, given the original
6395f757f3fSDimitry Andric   // upper bound on the induction variable?  If not, we branch to the "real"
6405f757f3fSDimitry Andric   // exit.
6415f757f3fSDimitry Andric   Value *LoopExitAt = NoopOrExt(LS.LoopExitAt);
6425f757f3fSDimitry Andric   Value *IterationsLeft = B.CreateICmp(Pred, IndVarBase, LoopExitAt);
6435f757f3fSDimitry Andric   B.CreateCondBr(IterationsLeft, RRI.PseudoExit, LS.LatchExit);
6445f757f3fSDimitry Andric 
6455f757f3fSDimitry Andric   BranchInst *BranchToContinuation =
6465f757f3fSDimitry Andric       BranchInst::Create(ContinuationBlock, RRI.PseudoExit);
6475f757f3fSDimitry Andric 
6485f757f3fSDimitry Andric   // We emit PHI nodes into `RRI.PseudoExit' that compute the "latest" value of
6495f757f3fSDimitry Andric   // each of the PHI nodes in the loop header.  This feeds into the initial
6505f757f3fSDimitry Andric   // value of the same PHI nodes if/when we continue execution.
6515f757f3fSDimitry Andric   for (PHINode &PN : LS.Header->phis()) {
6525f757f3fSDimitry Andric     PHINode *NewPHI = PHINode::Create(PN.getType(), 2, PN.getName() + ".copy",
653*0fca6ea1SDimitry Andric                                       BranchToContinuation->getIterator());
6545f757f3fSDimitry Andric 
6555f757f3fSDimitry Andric     NewPHI->addIncoming(PN.getIncomingValueForBlock(Preheader), Preheader);
6565f757f3fSDimitry Andric     NewPHI->addIncoming(PN.getIncomingValueForBlock(LS.Latch),
6575f757f3fSDimitry Andric                         RRI.ExitSelector);
6585f757f3fSDimitry Andric     RRI.PHIValuesAtPseudoExit.push_back(NewPHI);
6595f757f3fSDimitry Andric   }
6605f757f3fSDimitry Andric 
6615f757f3fSDimitry Andric   RRI.IndVarEnd = PHINode::Create(IndVarBase->getType(), 2, "indvar.end",
662*0fca6ea1SDimitry Andric                                   BranchToContinuation->getIterator());
6635f757f3fSDimitry Andric   RRI.IndVarEnd->addIncoming(IndVarStart, Preheader);
6645f757f3fSDimitry Andric   RRI.IndVarEnd->addIncoming(IndVarBase, RRI.ExitSelector);
6655f757f3fSDimitry Andric 
6665f757f3fSDimitry Andric   // The latch exit now has a branch from `RRI.ExitSelector' instead of
6675f757f3fSDimitry Andric   // `LS.Latch'.  The PHI nodes need to be updated to reflect that.
6685f757f3fSDimitry Andric   LS.LatchExit->replacePhiUsesWith(LS.Latch, RRI.ExitSelector);
6695f757f3fSDimitry Andric 
6705f757f3fSDimitry Andric   return RRI;
6715f757f3fSDimitry Andric }
6725f757f3fSDimitry Andric 
6735f757f3fSDimitry Andric void LoopConstrainer::rewriteIncomingValuesForPHIs(
6745f757f3fSDimitry Andric     LoopStructure &LS, BasicBlock *ContinuationBlock,
6755f757f3fSDimitry Andric     const LoopConstrainer::RewrittenRangeInfo &RRI) const {
6765f757f3fSDimitry Andric   unsigned PHIIndex = 0;
6775f757f3fSDimitry Andric   for (PHINode &PN : LS.Header->phis())
6785f757f3fSDimitry Andric     PN.setIncomingValueForBlock(ContinuationBlock,
6795f757f3fSDimitry Andric                                 RRI.PHIValuesAtPseudoExit[PHIIndex++]);
6805f757f3fSDimitry Andric 
6815f757f3fSDimitry Andric   LS.IndVarStart = RRI.IndVarEnd;
6825f757f3fSDimitry Andric }
6835f757f3fSDimitry Andric 
6845f757f3fSDimitry Andric BasicBlock *LoopConstrainer::createPreheader(const LoopStructure &LS,
6855f757f3fSDimitry Andric                                              BasicBlock *OldPreheader,
6865f757f3fSDimitry Andric                                              const char *Tag) const {
6875f757f3fSDimitry Andric   BasicBlock *Preheader = BasicBlock::Create(Ctx, Tag, &F, LS.Header);
6885f757f3fSDimitry Andric   BranchInst::Create(LS.Header, Preheader);
6895f757f3fSDimitry Andric 
6905f757f3fSDimitry Andric   LS.Header->replacePhiUsesWith(OldPreheader, Preheader);
6915f757f3fSDimitry Andric 
6925f757f3fSDimitry Andric   return Preheader;
6935f757f3fSDimitry Andric }
6945f757f3fSDimitry Andric 
6955f757f3fSDimitry Andric void LoopConstrainer::addToParentLoopIfNeeded(ArrayRef<BasicBlock *> BBs) {
6965f757f3fSDimitry Andric   Loop *ParentLoop = OriginalLoop.getParentLoop();
6975f757f3fSDimitry Andric   if (!ParentLoop)
6985f757f3fSDimitry Andric     return;
6995f757f3fSDimitry Andric 
7005f757f3fSDimitry Andric   for (BasicBlock *BB : BBs)
7015f757f3fSDimitry Andric     ParentLoop->addBasicBlockToLoop(BB, LI);
7025f757f3fSDimitry Andric }
7035f757f3fSDimitry Andric 
7045f757f3fSDimitry Andric Loop *LoopConstrainer::createClonedLoopStructure(Loop *Original, Loop *Parent,
7055f757f3fSDimitry Andric                                                  ValueToValueMapTy &VM,
7065f757f3fSDimitry Andric                                                  bool IsSubloop) {
7075f757f3fSDimitry Andric   Loop &New = *LI.AllocateLoop();
7085f757f3fSDimitry Andric   if (Parent)
7095f757f3fSDimitry Andric     Parent->addChildLoop(&New);
7105f757f3fSDimitry Andric   else
7115f757f3fSDimitry Andric     LI.addTopLevelLoop(&New);
7125f757f3fSDimitry Andric   LPMAddNewLoop(&New, IsSubloop);
7135f757f3fSDimitry Andric 
7145f757f3fSDimitry Andric   // Add all of the blocks in Original to the new loop.
7155f757f3fSDimitry Andric   for (auto *BB : Original->blocks())
7165f757f3fSDimitry Andric     if (LI.getLoopFor(BB) == Original)
7175f757f3fSDimitry Andric       New.addBasicBlockToLoop(cast<BasicBlock>(VM[BB]), LI);
7185f757f3fSDimitry Andric 
7195f757f3fSDimitry Andric   // Add all of the subloops to the new loop.
7205f757f3fSDimitry Andric   for (Loop *SubLoop : *Original)
7215f757f3fSDimitry Andric     createClonedLoopStructure(SubLoop, &New, VM, /* IsSubloop */ true);
7225f757f3fSDimitry Andric 
7235f757f3fSDimitry Andric   return &New;
7245f757f3fSDimitry Andric }
7255f757f3fSDimitry Andric 
7265f757f3fSDimitry Andric bool LoopConstrainer::run() {
7275f757f3fSDimitry Andric   BasicBlock *Preheader = OriginalLoop.getLoopPreheader();
7285f757f3fSDimitry Andric   assert(Preheader != nullptr && "precondition!");
7295f757f3fSDimitry Andric 
7305f757f3fSDimitry Andric   OriginalPreheader = Preheader;
7315f757f3fSDimitry Andric   MainLoopPreheader = Preheader;
7325f757f3fSDimitry Andric   bool IsSignedPredicate = MainLoopStructure.IsSignedPredicate;
7335f757f3fSDimitry Andric   bool Increasing = MainLoopStructure.IndVarIncreasing;
7345f757f3fSDimitry Andric   IntegerType *IVTy = cast<IntegerType>(RangeTy);
7355f757f3fSDimitry Andric 
736*0fca6ea1SDimitry Andric   SCEVExpander Expander(SE, F.getDataLayout(), "loop-constrainer");
7375f757f3fSDimitry Andric   Instruction *InsertPt = OriginalPreheader->getTerminator();
7385f757f3fSDimitry Andric 
7395f757f3fSDimitry Andric   // It would have been better to make `PreLoop' and `PostLoop'
7405f757f3fSDimitry Andric   // `std::optional<ClonedLoop>'s, but `ValueToValueMapTy' does not have a copy
7415f757f3fSDimitry Andric   // constructor.
7425f757f3fSDimitry Andric   ClonedLoop PreLoop, PostLoop;
7435f757f3fSDimitry Andric   bool NeedsPreLoop =
7445f757f3fSDimitry Andric       Increasing ? SR.LowLimit.has_value() : SR.HighLimit.has_value();
7455f757f3fSDimitry Andric   bool NeedsPostLoop =
7465f757f3fSDimitry Andric       Increasing ? SR.HighLimit.has_value() : SR.LowLimit.has_value();
7475f757f3fSDimitry Andric 
7485f757f3fSDimitry Andric   Value *ExitPreLoopAt = nullptr;
7495f757f3fSDimitry Andric   Value *ExitMainLoopAt = nullptr;
7505f757f3fSDimitry Andric   const SCEVConstant *MinusOneS =
7515f757f3fSDimitry Andric       cast<SCEVConstant>(SE.getConstant(IVTy, -1, true /* isSigned */));
7525f757f3fSDimitry Andric 
7535f757f3fSDimitry Andric   if (NeedsPreLoop) {
7545f757f3fSDimitry Andric     const SCEV *ExitPreLoopAtSCEV = nullptr;
7555f757f3fSDimitry Andric 
7565f757f3fSDimitry Andric     if (Increasing)
7575f757f3fSDimitry Andric       ExitPreLoopAtSCEV = *SR.LowLimit;
7585f757f3fSDimitry Andric     else if (cannotBeMinInLoop(*SR.HighLimit, &OriginalLoop, SE,
7595f757f3fSDimitry Andric                                IsSignedPredicate))
7605f757f3fSDimitry Andric       ExitPreLoopAtSCEV = SE.getAddExpr(*SR.HighLimit, MinusOneS);
7615f757f3fSDimitry Andric     else {
7625f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "could not prove no-overflow when computing "
7635f757f3fSDimitry Andric                         << "preloop exit limit.  HighLimit = "
7645f757f3fSDimitry Andric                         << *(*SR.HighLimit) << "\n");
7655f757f3fSDimitry Andric       return false;
7665f757f3fSDimitry Andric     }
7675f757f3fSDimitry Andric 
7685f757f3fSDimitry Andric     if (!Expander.isSafeToExpandAt(ExitPreLoopAtSCEV, InsertPt)) {
7695f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "could not prove that it is safe to expand the"
7705f757f3fSDimitry Andric                         << " preloop exit limit " << *ExitPreLoopAtSCEV
7715f757f3fSDimitry Andric                         << " at block " << InsertPt->getParent()->getName()
7725f757f3fSDimitry Andric                         << "\n");
7735f757f3fSDimitry Andric       return false;
7745f757f3fSDimitry Andric     }
7755f757f3fSDimitry Andric 
7765f757f3fSDimitry Andric     ExitPreLoopAt = Expander.expandCodeFor(ExitPreLoopAtSCEV, IVTy, InsertPt);
7775f757f3fSDimitry Andric     ExitPreLoopAt->setName("exit.preloop.at");
7785f757f3fSDimitry Andric   }
7795f757f3fSDimitry Andric 
7805f757f3fSDimitry Andric   if (NeedsPostLoop) {
7815f757f3fSDimitry Andric     const SCEV *ExitMainLoopAtSCEV = nullptr;
7825f757f3fSDimitry Andric 
7835f757f3fSDimitry Andric     if (Increasing)
7845f757f3fSDimitry Andric       ExitMainLoopAtSCEV = *SR.HighLimit;
7855f757f3fSDimitry Andric     else if (cannotBeMinInLoop(*SR.LowLimit, &OriginalLoop, SE,
7865f757f3fSDimitry Andric                                IsSignedPredicate))
7875f757f3fSDimitry Andric       ExitMainLoopAtSCEV = SE.getAddExpr(*SR.LowLimit, MinusOneS);
7885f757f3fSDimitry Andric     else {
7895f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "could not prove no-overflow when computing "
7905f757f3fSDimitry Andric                         << "mainloop exit limit.  LowLimit = "
7915f757f3fSDimitry Andric                         << *(*SR.LowLimit) << "\n");
7925f757f3fSDimitry Andric       return false;
7935f757f3fSDimitry Andric     }
7945f757f3fSDimitry Andric 
7955f757f3fSDimitry Andric     if (!Expander.isSafeToExpandAt(ExitMainLoopAtSCEV, InsertPt)) {
7965f757f3fSDimitry Andric       LLVM_DEBUG(dbgs() << "could not prove that it is safe to expand the"
7975f757f3fSDimitry Andric                         << " main loop exit limit " << *ExitMainLoopAtSCEV
7985f757f3fSDimitry Andric                         << " at block " << InsertPt->getParent()->getName()
7995f757f3fSDimitry Andric                         << "\n");
8005f757f3fSDimitry Andric       return false;
8015f757f3fSDimitry Andric     }
8025f757f3fSDimitry Andric 
8035f757f3fSDimitry Andric     ExitMainLoopAt = Expander.expandCodeFor(ExitMainLoopAtSCEV, IVTy, InsertPt);
8045f757f3fSDimitry Andric     ExitMainLoopAt->setName("exit.mainloop.at");
8055f757f3fSDimitry Andric   }
8065f757f3fSDimitry Andric 
8075f757f3fSDimitry Andric   // We clone these ahead of time so that we don't have to deal with changing
8085f757f3fSDimitry Andric   // and temporarily invalid IR as we transform the loops.
8095f757f3fSDimitry Andric   if (NeedsPreLoop)
8105f757f3fSDimitry Andric     cloneLoop(PreLoop, "preloop");
8115f757f3fSDimitry Andric   if (NeedsPostLoop)
8125f757f3fSDimitry Andric     cloneLoop(PostLoop, "postloop");
8135f757f3fSDimitry Andric 
8145f757f3fSDimitry Andric   RewrittenRangeInfo PreLoopRRI;
8155f757f3fSDimitry Andric 
8165f757f3fSDimitry Andric   if (NeedsPreLoop) {
8175f757f3fSDimitry Andric     Preheader->getTerminator()->replaceUsesOfWith(MainLoopStructure.Header,
8185f757f3fSDimitry Andric                                                   PreLoop.Structure.Header);
8195f757f3fSDimitry Andric 
8205f757f3fSDimitry Andric     MainLoopPreheader =
8215f757f3fSDimitry Andric         createPreheader(MainLoopStructure, Preheader, "mainloop");
8225f757f3fSDimitry Andric     PreLoopRRI = changeIterationSpaceEnd(PreLoop.Structure, Preheader,
8235f757f3fSDimitry Andric                                          ExitPreLoopAt, MainLoopPreheader);
8245f757f3fSDimitry Andric     rewriteIncomingValuesForPHIs(MainLoopStructure, MainLoopPreheader,
8255f757f3fSDimitry Andric                                  PreLoopRRI);
8265f757f3fSDimitry Andric   }
8275f757f3fSDimitry Andric 
8285f757f3fSDimitry Andric   BasicBlock *PostLoopPreheader = nullptr;
8295f757f3fSDimitry Andric   RewrittenRangeInfo PostLoopRRI;
8305f757f3fSDimitry Andric 
8315f757f3fSDimitry Andric   if (NeedsPostLoop) {
8325f757f3fSDimitry Andric     PostLoopPreheader =
8335f757f3fSDimitry Andric         createPreheader(PostLoop.Structure, Preheader, "postloop");
8345f757f3fSDimitry Andric     PostLoopRRI = changeIterationSpaceEnd(MainLoopStructure, MainLoopPreheader,
8355f757f3fSDimitry Andric                                           ExitMainLoopAt, PostLoopPreheader);
8365f757f3fSDimitry Andric     rewriteIncomingValuesForPHIs(PostLoop.Structure, PostLoopPreheader,
8375f757f3fSDimitry Andric                                  PostLoopRRI);
8385f757f3fSDimitry Andric   }
8395f757f3fSDimitry Andric 
8405f757f3fSDimitry Andric   BasicBlock *NewMainLoopPreheader =
8415f757f3fSDimitry Andric       MainLoopPreheader != Preheader ? MainLoopPreheader : nullptr;
8425f757f3fSDimitry Andric   BasicBlock *NewBlocks[] = {PostLoopPreheader,        PreLoopRRI.PseudoExit,
8435f757f3fSDimitry Andric                              PreLoopRRI.ExitSelector,  PostLoopRRI.PseudoExit,
8445f757f3fSDimitry Andric                              PostLoopRRI.ExitSelector, NewMainLoopPreheader};
8455f757f3fSDimitry Andric 
8465f757f3fSDimitry Andric   // Some of the above may be nullptr, filter them out before passing to
8475f757f3fSDimitry Andric   // addToParentLoopIfNeeded.
8485f757f3fSDimitry Andric   auto NewBlocksEnd =
8495f757f3fSDimitry Andric       std::remove(std::begin(NewBlocks), std::end(NewBlocks), nullptr);
8505f757f3fSDimitry Andric 
8515f757f3fSDimitry Andric   addToParentLoopIfNeeded(ArrayRef(std::begin(NewBlocks), NewBlocksEnd));
8525f757f3fSDimitry Andric 
8535f757f3fSDimitry Andric   DT.recalculate(F);
8545f757f3fSDimitry Andric 
8555f757f3fSDimitry Andric   // We need to first add all the pre and post loop blocks into the loop
8565f757f3fSDimitry Andric   // structures (as part of createClonedLoopStructure), and then update the
8575f757f3fSDimitry Andric   // LCSSA form and LoopSimplifyForm. This is necessary for correctly updating
8585f757f3fSDimitry Andric   // LI when LoopSimplifyForm is generated.
8595f757f3fSDimitry Andric   Loop *PreL = nullptr, *PostL = nullptr;
8605f757f3fSDimitry Andric   if (!PreLoop.Blocks.empty()) {
8615f757f3fSDimitry Andric     PreL = createClonedLoopStructure(&OriginalLoop,
8625f757f3fSDimitry Andric                                      OriginalLoop.getParentLoop(), PreLoop.Map,
8635f757f3fSDimitry Andric                                      /* IsSubLoop */ false);
8645f757f3fSDimitry Andric   }
8655f757f3fSDimitry Andric 
8665f757f3fSDimitry Andric   if (!PostLoop.Blocks.empty()) {
8675f757f3fSDimitry Andric     PostL =
8685f757f3fSDimitry Andric         createClonedLoopStructure(&OriginalLoop, OriginalLoop.getParentLoop(),
8695f757f3fSDimitry Andric                                   PostLoop.Map, /* IsSubLoop */ false);
8705f757f3fSDimitry Andric   }
8715f757f3fSDimitry Andric 
8725f757f3fSDimitry Andric   // This function canonicalizes the loop into Loop-Simplify and LCSSA forms.
8735f757f3fSDimitry Andric   auto CanonicalizeLoop = [&](Loop *L, bool IsOriginalLoop) {
8745f757f3fSDimitry Andric     formLCSSARecursively(*L, DT, &LI, &SE);
8755f757f3fSDimitry Andric     simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr, true);
8765f757f3fSDimitry Andric     // Pre/post loops are slow paths, we do not need to perform any loop
8775f757f3fSDimitry Andric     // optimizations on them.
8785f757f3fSDimitry Andric     if (!IsOriginalLoop)
8795f757f3fSDimitry Andric       DisableAllLoopOptsOnLoop(*L);
8805f757f3fSDimitry Andric   };
8815f757f3fSDimitry Andric   if (PreL)
8825f757f3fSDimitry Andric     CanonicalizeLoop(PreL, false);
8835f757f3fSDimitry Andric   if (PostL)
8845f757f3fSDimitry Andric     CanonicalizeLoop(PostL, false);
8855f757f3fSDimitry Andric   CanonicalizeLoop(&OriginalLoop, true);
8865f757f3fSDimitry Andric 
8875f757f3fSDimitry Andric   /// At this point:
8885f757f3fSDimitry Andric   /// - We've broken a "main loop" out of the loop in a way that the "main loop"
8895f757f3fSDimitry Andric   /// runs with the induction variable in a subset of [Begin, End).
8905f757f3fSDimitry Andric   /// - There is no overflow when computing "main loop" exit limit.
8915f757f3fSDimitry Andric   /// - Max latch taken count of the loop is limited.
8925f757f3fSDimitry Andric   /// It guarantees that induction variable will not overflow iterating in the
8935f757f3fSDimitry Andric   /// "main loop".
8945f757f3fSDimitry Andric   if (isa<OverflowingBinaryOperator>(MainLoopStructure.IndVarBase))
8955f757f3fSDimitry Andric     if (IsSignedPredicate)
8965f757f3fSDimitry Andric       cast<BinaryOperator>(MainLoopStructure.IndVarBase)
8975f757f3fSDimitry Andric           ->setHasNoSignedWrap(true);
8985f757f3fSDimitry Andric   /// TODO: support unsigned predicate.
8995f757f3fSDimitry Andric   /// To add NUW flag we need to prove that both operands of BO are
9005f757f3fSDimitry Andric   /// non-negative. E.g:
9015f757f3fSDimitry Andric   /// ...
9025f757f3fSDimitry Andric   /// %iv.next = add nsw i32 %iv, -1
9035f757f3fSDimitry Andric   /// %cmp = icmp ult i32 %iv.next, %n
9045f757f3fSDimitry Andric   /// br i1 %cmp, label %loopexit, label %loop
9055f757f3fSDimitry Andric   ///
9065f757f3fSDimitry Andric   /// -1 is MAX_UINT in terms of unsigned int. Adding anything but zero will
9075f757f3fSDimitry Andric   /// overflow, therefore NUW flag is not legal here.
9085f757f3fSDimitry Andric 
9095f757f3fSDimitry Andric   return true;
9105f757f3fSDimitry Andric }
911