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