30#include "llvm/ADT/SmallVector.h"
31#include "llvm/Analysis/LoopInfo.h"
32#include "llvm/Analysis/ScalarEvolution.h"
35#pragma clang diagnostic push
36#pragma clang diagnostic ignored "-Wunused-variable"
38#pragma GCC diagnostic push
39#pragma GCC diagnostic ignored "-Wunused-variable"
42#if LLVM_VERSION_MAJOR <= 22
43#define SCEVUse const SCEV *
53 const Loop *L, Value *ExitCond,
bool ExitIfTrue,
bool ControlsExit,
54 bool AllowPredicates) {
55 ScalarEvolution::ExitLimitCacheTy Cache(L, ExitIfTrue, AllowPredicates);
57 ControlsExit, AllowPredicates);
61 llvm::TargetLibraryInfo &TLI,
62 llvm::AssumptionCache &AC,
63 llvm::DominatorTree &DT,
65 : ScalarEvolution(F, TLI, AC, DT, LI),
69 const Loop *L, BasicBlock *ExitingBlock,
bool AllowPredicates) {
71 SmallVector<BasicBlock *, 8> ExitingBlocks;
72 L->getExitingBlocks(ExitingBlocks);
73 for (
auto &ExitingBlock : ExitingBlocks) {
74 BasicBlock *Exit =
nullptr;
75 for (
auto *SBB : successors(ExitingBlock)) {
76 if (!L->contains(SBB)) {
84 ExitingBlock =
nullptr;
87 std::remove(ExitingBlocks.begin(), ExitingBlocks.end(),
nullptr),
90 assert(L->contains(ExitingBlock) &&
"Exit count for non-loop block?");
93 const BasicBlock *Latch = L->getLoopLatch();
94 if (!Latch || !DT.dominates(ExitingBlock, Latch))
95 return getCouldNotCompute();
97 bool IsOnlyExit = ExitingBlocks.size() == 1;
98 auto *Term = ExitingBlock->getTerminator();
99 if (BranchInst *BI = dyn_cast<BranchInst>(Term)) {
100 assert(BI->isConditional() &&
"If unconditional, it can't be in loop!");
101 bool ExitIfTrue = !L->contains(BI->getSuccessor(0));
102 assert(ExitIfTrue == L->contains(BI->getSuccessor(1)) &&
103 "It should have one successor in loop and one exit block!");
110 if (SwitchInst *SI = dyn_cast<SwitchInst>(Term)) {
112 BasicBlock *Exit =
nullptr;
113 for (
auto *SBB : successors(ExitingBlock))
114 if (!L->contains(SBB)) {
118 return getCouldNotCompute();
121 assert(Exit &&
"Exiting block must have at least one exit");
126 return getCouldNotCompute();
129ScalarEvolution::ExitLimit
131 const Loop *L, SwitchInst *Switch, BasicBlock *ExitingBlock,
132 bool ControlsOnlyExit) {
133 assert(!L->contains(ExitingBlock) &&
"Not an exiting block!");
136 if (Switch->getDefaultDest() == ExitingBlock)
137 return getCouldNotCompute();
141 assert(L->contains(Switch->getDefaultDest()) &&
142 "Default case must not exit the loop!");
143 const SCEV *LHS = getSCEVAtScope(Switch->getCondition(), L);
144 const SCEV *RHS = getConstant(Switch->findCaseDest(ExitingBlock));
147 ExitLimit EL = howFarToZero(getMinusSCEV(LHS, RHS), L, ControlsOnlyExit);
151 return getCouldNotCompute();
154ScalarEvolution::ExitLimit
156 ExitLimitCacheTy &Cache,
const Loop *L, Value *ExitCond,
bool ExitIfTrue,
157 bool ControlsExit,
bool AllowPredicates) {
160 Cache.find(L, ExitCond, ExitIfTrue, ControlsExit, AllowPredicates))
164 ControlsExit, AllowPredicates);
165 Cache.insert(L, ExitCond, ExitIfTrue, ControlsExit, AllowPredicates, EL);
169ScalarEvolution::ExitLimit
171 ExitLimitCacheTy &Cache,
const Loop *L, Value *ExitCond,
bool ExitIfTrue,
172 bool ControlsExit,
bool AllowPredicates) {
174 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(ExitCond)) {
175 if (BO->getOpcode() == Instruction::And) {
177 bool EitherMayExit = !ExitIfTrue;
179 Cache, L, BO->getOperand(0), ExitIfTrue,
180 ControlsExit && !EitherMayExit, AllowPredicates);
182 Cache, L, BO->getOperand(1), ExitIfTrue,
183 ControlsExit && !EitherMayExit, AllowPredicates);
184 const SCEV *BECount = getCouldNotCompute();
185 const SCEV *MaxBECount = getCouldNotCompute();
189 if (EL0.ExactNotTaken == getCouldNotCompute() ||
190 EL1.ExactNotTaken == getCouldNotCompute())
191 BECount = getCouldNotCompute();
194 getUMinFromMismatchedTypes(EL0.ExactNotTaken, EL1.ExactNotTaken);
195#if LLVM_VERSION_MAJOR >= 16
196 if (EL0.ConstantMaxNotTaken == getCouldNotCompute())
197 MaxBECount = EL1.ConstantMaxNotTaken;
198 else if (EL1.ConstantMaxNotTaken == getCouldNotCompute())
199 MaxBECount = EL0.ConstantMaxNotTaken;
201 MaxBECount = getUMinFromMismatchedTypes(EL0.ConstantMaxNotTaken,
202 EL1.ConstantMaxNotTaken);
206 if (EL0.ConstantMaxNotTaken == EL1.ConstantMaxNotTaken)
207 MaxBECount = EL0.ConstantMaxNotTaken;
208 if (EL0.ExactNotTaken == EL1.ExactNotTaken)
209 BECount = EL0.ExactNotTaken;
212 if (EL0.MaxNotTaken == getCouldNotCompute())
213 MaxBECount = EL1.MaxNotTaken;
214 else if (EL1.MaxNotTaken == getCouldNotCompute())
215 MaxBECount = EL0.MaxNotTaken;
218 getUMinFromMismatchedTypes(EL0.MaxNotTaken, EL1.MaxNotTaken);
222 if (EL0.MaxNotTaken == EL1.MaxNotTaken)
223 MaxBECount = EL0.MaxNotTaken;
224 if (EL0.ExactNotTaken == EL1.ExactNotTaken)
225 BECount = EL0.ExactNotTaken;
233 if (isa<SCEVCouldNotCompute>(MaxBECount) &&
234 !isa<SCEVCouldNotCompute>(BECount))
235 MaxBECount = getConstant(getUnsignedRangeMax(BECount));
237#if LLVM_VERSION_MAJOR >= 20
238 return ExitLimit(BECount, MaxBECount, MaxBECount,
false,
239 {ArrayRef(EL0.Predicates), ArrayRef(EL1.Predicates)});
240#elif LLVM_VERSION_MAJOR >= 16
241 return ExitLimit(BECount, MaxBECount, MaxBECount,
false,
242 {&EL0.Predicates, &EL1.Predicates});
244 return ExitLimit(BECount, MaxBECount,
false,
245 {&EL0.Predicates, &EL1.Predicates});
248 if (BO->getOpcode() == Instruction::Or) {
250 bool EitherMayExit = ExitIfTrue;
252 Cache, L, BO->getOperand(0), ExitIfTrue,
253 ControlsExit && !EitherMayExit, AllowPredicates);
255 Cache, L, BO->getOperand(1), ExitIfTrue,
256 ControlsExit && !EitherMayExit, AllowPredicates);
257 const SCEV *BECount = getCouldNotCompute();
258 const SCEV *MaxBECount = getCouldNotCompute();
262 if (EL0.ExactNotTaken == getCouldNotCompute() ||
263 EL1.ExactNotTaken == getCouldNotCompute())
264 BECount = getCouldNotCompute();
267 getUMinFromMismatchedTypes(EL0.ExactNotTaken, EL1.ExactNotTaken);
268#if LLVM_VERSION_MAJOR >= 16
269 if (EL0.ConstantMaxNotTaken == getCouldNotCompute())
270 MaxBECount = EL1.ConstantMaxNotTaken;
271 else if (EL1.ConstantMaxNotTaken == getCouldNotCompute())
272 MaxBECount = EL0.ConstantMaxNotTaken;
274 MaxBECount = getUMinFromMismatchedTypes(EL0.ConstantMaxNotTaken,
275 EL1.ConstantMaxNotTaken);
279 if (EL0.ConstantMaxNotTaken == EL1.ConstantMaxNotTaken)
280 MaxBECount = EL0.ConstantMaxNotTaken;
281 if (EL0.ExactNotTaken == EL1.ExactNotTaken)
282 BECount = EL0.ExactNotTaken;
284#if LLVM_VERSION_MAJOR >= 20
285 return ExitLimit(BECount, MaxBECount, MaxBECount,
false,
286 {ArrayRef(EL0.Predicates), ArrayRef(EL1.Predicates)});
288 return ExitLimit(BECount, MaxBECount, MaxBECount,
false,
289 {&EL0.Predicates, &EL1.Predicates});
292 if (EL0.MaxNotTaken == getCouldNotCompute())
293 MaxBECount = EL1.MaxNotTaken;
294 else if (EL1.MaxNotTaken == getCouldNotCompute())
295 MaxBECount = EL0.MaxNotTaken;
298 getUMinFromMismatchedTypes(EL0.MaxNotTaken, EL1.MaxNotTaken);
302 if (EL0.MaxNotTaken == EL1.MaxNotTaken)
303 MaxBECount = EL0.MaxNotTaken;
304 if (EL0.ExactNotTaken == EL1.ExactNotTaken)
305 BECount = EL0.ExactNotTaken;
307 return ExitLimit(BECount, MaxBECount,
false,
308 {&EL0.Predicates, &EL1.Predicates});
315 if (ICmpInst *ExitCondICmp = dyn_cast<ICmpInst>(ExitCond)) {
317 computeExitLimitFromICmp(L, ExitCondICmp, ExitIfTrue, ControlsExit);
318 if (EL.hasFullInfo() || !AllowPredicates)
322 return computeExitLimitFromICmp(L, ExitCondICmp, ExitIfTrue, ControlsExit,
330 if (ConstantInt *CI = dyn_cast<ConstantInt>(ExitCond)) {
331 if (ExitIfTrue == !CI->getZExtValue())
333 return getCouldNotCompute();
336 return getZero(CI->getType());
340 return computeExitCountExhaustively(L, ExitCond, ExitIfTrue);
344 const Loop *L, ICmpInst *ExitCond,
bool ExitIfTrue,
bool ControlsExit,
345 bool AllowPredicates) {
347#if LLVM_VERSION_MAJOR >= 20
348 llvm::CmpPredicate Pred = ExitCond->getPredicate();
350 auto Pred = ExitCond->getPredicate();
353 Pred = ExitCond->getInversePredicate();
354 const auto OriginalPred = Pred;
356#if LLVM_VERSION_MAJOR < 14
358 if (LoadInst *LI = dyn_cast<LoadInst>(ExitCond->getOperand(0)))
359 if (
Constant *RHS = dyn_cast<Constant>(ExitCond->getOperand(1))) {
360 ExitLimit ItCnt = computeLoadConstantCompareExitLimit(LI, RHS, L, Pred);
361 if (ItCnt.hasAnyInfo())
366 SCEVUse LHS = getSCEV(ExitCond->getOperand(0));
367 SCEVUse RHS = getSCEV(ExitCond->getOperand(1));
369#define PROP_PHI(LHS) \
370 if (auto un = dyn_cast<SCEVUnknown>(LHS)) { \
371 if (auto pn = dyn_cast_or_null<PHINode>(un->getValue())) { \
372 const SCEV *sc = nullptr; \
373 bool failed = false; \
374 for (auto &a : pn->incoming_values()) { \
375 auto subsc = getSCEV(a); \
376 if (sc == nullptr) { \
394 LHS = getSCEVAtScope(LHS, L);
395 RHS = getSCEVAtScope(RHS, L);
399 if (isLoopInvariant(LHS, L) && !isLoopInvariant(RHS, L)) {
402 Pred = ICmpInst::getSwappedPredicate(Pred);
406 (void)SimplifyICmpOperands(Pred, LHS, RHS);
410 if (
const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS))
411 if (
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(LHS))
412 if (AddRec->getLoop() == L) {
414 ConstantRange CompRange =
415 ConstantRange::makeExactICmpRegion(Pred, RHSC->getAPInt());
417 const SCEV *Ret = AddRec->getNumIterationsInRange(CompRange, *
this);
418 if (!isa<SCEVCouldNotCompute>(Ret))
423 case ICmpInst::ICMP_NE: {
426 howFarToZero(getMinusSCEV(LHS, RHS), L, ControlsExit, AllowPredicates);
431 case ICmpInst::ICMP_EQ: {
433 ExitLimit EL = howFarToNonZero(getMinusSCEV(LHS, RHS), L);
438 case ICmpInst::ICMP_SLT:
439 case ICmpInst::ICMP_ULT:
440 case ICmpInst::ICMP_SLE:
441 case ICmpInst::ICMP_ULE: {
442 bool IsSigned = Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SLE;
444 if (Pred == ICmpInst::ICMP_SLE || Pred == ICmpInst::ICMP_ULE) {
445 if (!isa<IntegerType>(RHS->getType()))
447 SmallVector<SCEVUse, 2> sv = {
449 getConstant(ConstantInt::get(cast<IntegerType>(RHS->getType()), 1))};
453 RHS = getAddExpr(sv, SCEV::FlagNSW);
455 RHS = getAddExpr(sv, SCEV::FlagNUW);
463 case ICmpInst::ICMP_SGT:
464 case ICmpInst::ICMP_UGT:
465 case ICmpInst::ICMP_SGE:
466 case ICmpInst::ICMP_UGE: {
467 bool IsSigned = Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_SLE;
468 if (Pred == ICmpInst::ICMP_SGE || Pred == ICmpInst::ICMP_UGE) {
469 if (!isa<IntegerType>(RHS->getType()))
471 SmallVector<SCEVUse, 2> sv = {
473 getConstant(ConstantInt::get(cast<IntegerType>(RHS->getType()), -1))};
477 RHS = getAddExpr(sv, SCEV::FlagNSW);
479 RHS = getAddExpr(sv, SCEV::FlagNUW);
481 ExitLimit EL = howManyGreaterThans(LHS, RHS, L, IsSigned, ControlsExit,
491 auto *ExhaustiveCount = computeExitCountExhaustively(L, ExitCond, ExitIfTrue);
493 if (!isa<SCEVCouldNotCompute>(ExhaustiveCount))
494 return ExhaustiveCount;
496 return computeShiftCompareExitLimit(ExitCond->getOperand(0),
497 ExitCond->getOperand(1), L, OriginalPred);
500#if LLVM_VERSION_MAJOR >= 13
501static const SCEV *getSignedOverflowLimitForStep(
const SCEV *Step,
502 ICmpInst::Predicate *Pred,
503 ScalarEvolution *SE) {
504 unsigned BitWidth = SE->getTypeSizeInBits(Step->getType());
505 if (SE->isKnownPositive(Step)) {
506 *Pred = ICmpInst::ICMP_SLT;
507 return SE->getConstant(APInt::getSignedMinValue(BitWidth) -
508 SE->getSignedRangeMax(Step));
510 if (SE->isKnownNegative(Step)) {
511 *Pred = ICmpInst::ICMP_SGT;
512 return SE->getConstant(APInt::getSignedMaxValue(BitWidth) -
513 SE->getSignedRangeMin(Step));
517static const SCEV *getUnsignedOverflowLimitForStep(
const SCEV *Step,
518 ICmpInst::Predicate *Pred,
519 ScalarEvolution *SE) {
520 unsigned BitWidth = SE->getTypeSizeInBits(Step->getType());
521 *Pred = ICmpInst::ICMP_ULT;
523 return SE->getConstant(APInt::getMinValue(BitWidth) -
524 SE->getUnsignedRangeMax(Step));
529struct ExtendOpTraitsBase {
530 typedef const SCEV *(ScalarEvolution::*GetExtendExprTy)(
const SCEV *, Type *,
535template <
typename ExtendOp>
struct ExtendOpTraits {
548struct ExtendOpTraits<SCEVSignExtendExpr> :
public ExtendOpTraitsBase {
549 static const SCEV::NoWrapFlags WrapType = SCEV::FlagNSW;
551 static const GetExtendExprTy GetExtendExpr;
553 static const SCEV *getOverflowLimitForStep(
const SCEV *Step,
554 ICmpInst::Predicate *Pred,
555 ScalarEvolution *SE) {
556 return getSignedOverflowLimitForStep(Step, Pred, SE);
560const ExtendOpTraitsBase::GetExtendExprTy
561 ExtendOpTraits<SCEVSignExtendExpr>::GetExtendExpr =
562 &ScalarEvolution::getSignExtendExpr;
565struct ExtendOpTraits<SCEVZeroExtendExpr> :
public ExtendOpTraitsBase {
566 static const SCEV::NoWrapFlags WrapType = SCEV::FlagNUW;
568 static const GetExtendExprTy GetExtendExpr;
570 static const SCEV *getOverflowLimitForStep(
const SCEV *Step,
571 ICmpInst::Predicate *Pred,
572 ScalarEvolution *SE) {
573 return getUnsignedOverflowLimitForStep(Step, Pred, SE);
577const ExtendOpTraitsBase::GetExtendExprTy
578 ExtendOpTraits<SCEVZeroExtendExpr>::GetExtendExpr =
579 &ScalarEvolution::getZeroExtendExpr;
583static bool hasFlags(SCEV::NoWrapFlags Flags, SCEV::NoWrapFlags TestFlags) {
584 return TestFlags == ScalarEvolution::maskFlags(Flags, TestFlags);
587template <
typename ExtendOpTy>
588static const SCEV *getPreStartForExtend(
const SCEVAddRecExpr *AR, Type *Ty,
589 ScalarEvolution *SE,
unsigned Depth) {
590 auto WrapType = ExtendOpTraits<ExtendOpTy>::WrapType;
591 auto GetExtendExpr = ExtendOpTraits<ExtendOpTy>::GetExtendExpr;
593 const Loop *L = AR->getLoop();
594 const SCEV *Start = AR->getStart();
595 const SCEV *Step = AR->getStepRecurrence(*SE);
598 const SCEVAddExpr *SA = dyn_cast<SCEVAddExpr>(Start);
605 SmallVector<SCEVUse, 4> DiffOps;
606 for (
const SCEV *Op : SA->operands())
608 DiffOps.push_back(Op);
610 if (DiffOps.size() == SA->getNumOperands())
618 ScalarEvolution::maskFlags(SA->getNoWrapFlags(), SCEV::FlagNUW);
619 const SCEV *PreStart = SE->getAddExpr(DiffOps, PreStartFlags);
620 const SCEVAddRecExpr *PreAR = dyn_cast<SCEVAddRecExpr>(
621 SE->getAddRecExpr(PreStart, Step, L, SCEV::FlagAnyWrap));
627 const SCEV *BECount = SE->getBackedgeTakenCount(L);
628#if LLVM_VERSION_MAJOR >= 23
629 if (PreAR && any(PreAR->getNoWrapFlags(WrapType)) &&
630 !isa<SCEVCouldNotCompute>(BECount) && SE->isKnownPositive(BECount))
633 if (PreAR && PreAR->getNoWrapFlags(WrapType) &&
634 !isa<SCEVCouldNotCompute>(BECount) && SE->isKnownPositive(BECount))
639 unsigned BitWidth = SE->getTypeSizeInBits(AR->getType());
640 Type *WideTy = IntegerType::get(SE->getContext(), BitWidth * 2);
641 const SCEV *OperandExtendedStart =
642 SE->getAddExpr((SE->*GetExtendExpr)(PreStart, WideTy, Depth),
643 (SE->*GetExtendExpr)(Step, WideTy, Depth));
644 if ((SE->*GetExtendExpr)(Start, WideTy, Depth) == OperandExtendedStart) {
645#if LLVM_VERSION_MAJOR >= 23
646 if (PreAR && any(AR->getNoWrapFlags(WrapType)))
648 if (PreAR && AR->getNoWrapFlags(WrapType))
654 SE->setNoWrapFlags(
const_cast<SCEVAddRecExpr *
>(PreAR), WrapType);
660 ICmpInst::Predicate Pred;
661 const SCEV *OverflowLimit =
662 ExtendOpTraits<ExtendOpTy>::getOverflowLimitForStep(Step, &Pred, SE);
665 SE->isLoopEntryGuardedByCond(L, Pred, PreStart, OverflowLimit))
671template <
typename ExtendOpTy>
672static const SCEV *getExtendAddRecStart(
const SCEVAddRecExpr *AR, Type *Ty,
673 ScalarEvolution *SE,
unsigned Depth) {
674 auto GetExtendExpr = ExtendOpTraits<ExtendOpTy>::GetExtendExpr;
676 const SCEV *PreStart = getPreStartForExtend<ExtendOpTy>(AR, Ty, SE, Depth);
678 return (SE->*GetExtendExpr)(AR->getStart(), Ty, Depth);
680 return SE->getAddExpr(
681 (SE->*GetExtendExpr)(AR->getStepRecurrence(*SE), Ty, Depth),
682 (SE->*GetExtendExpr)(PreStart, Ty, Depth));
685static SCEV::NoWrapFlags StrengthenNoWrapFlags(ScalarEvolution *SE,
687 const ArrayRef<const SCEV *> Ops,
688 SCEV::NoWrapFlags Flags) {
689 using namespace std::placeholders;
691 using OBO = OverflowingBinaryOperator;
694 Type == scAddExpr || Type == scAddRecExpr || Type == scMulExpr;
696 assert(CanAnalyze &&
"don't call from other places!");
698 auto SignOrUnsignMask = SCEV::FlagNUW | SCEV::FlagNSW;
699 SCEV::NoWrapFlags SignOrUnsignWrap =
700 ScalarEvolution::maskFlags(Flags, SignOrUnsignMask);
703 auto IsKnownNonNegative = [&](
const SCEV *S) {
704 return SE->isKnownNonNegative(S);
707 if (SignOrUnsignWrap == SCEV::FlagNSW && all_of(Ops, IsKnownNonNegative))
709 ScalarEvolution::setFlags(Flags, (SCEV::NoWrapFlags)SignOrUnsignMask);
711 SignOrUnsignWrap = ScalarEvolution::maskFlags(Flags, SignOrUnsignMask);
713 if (SignOrUnsignWrap != SignOrUnsignMask &&
714 (Type == scAddExpr || Type == scMulExpr) && Ops.size() == 2 &&
715 isa<SCEVConstant>(Ops[0])) {
720 return Instruction::Add;
722 return Instruction::Mul;
724 llvm_unreachable(
"Unexpected SCEV op.");
728 const APInt &C = cast<SCEVConstant>(Ops[0])->getAPInt();
731 if (!(SignOrUnsignWrap & SCEV::FlagNSW)) {
732 auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
733 Opcode, C, OBO::NoSignedWrap);
734 if (NSWRegion.contains(SE->getSignedRange(Ops[1])))
735 Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNSW);
739 if (!(SignOrUnsignWrap & SCEV::FlagNUW)) {
740 auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
741 Opcode, C, OBO::NoUnsignedWrap);
742 if (NUWRegion.contains(SE->getUnsignedRange(Ops[1])))
743 Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
749 if (Type == scAddRecExpr && hasFlags(Flags, SCEV::FlagNW) &&
750 !hasFlags(Flags, SCEV::FlagNUW) && Ops.size() == 2 && Ops[0]->isZero() &&
751 IsKnownNonNegative(Ops[1]))
752 Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
755 if (Type == scMulExpr && !hasFlags(Flags, SCEV::FlagNUW) && Ops.size() == 2) {
756 if (
auto *UDiv = dyn_cast<SCEVUDivExpr>(Ops[0]))
757 if (UDiv->getOperand(1) == Ops[1])
758 Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
759 if (
auto *UDiv = dyn_cast<SCEVUDivExpr>(Ops[1]))
760 if (UDiv->getOperand(1) == Ops[0])
761 Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
768 const SCEV *LHS,
const SCEV *RHS,
const Loop *L,
bool IsSigned,
769 bool ControlsExit,
bool AllowPredicates) {
770#if LLVM_VERSION_MAJOR >= 20
771 SmallVector<const SCEVPredicate *, 4> Predicates;
773 SmallPtrSet<const SCEVPredicate *, 4> Predicates;
776 const SCEVAddRecExpr *IV = dyn_cast<SCEVAddRecExpr>(LHS);
777 bool PredicatedIV =
false;
779 auto canAssumeNoSelfWrap = [&](
const SCEVAddRecExpr *AR) {
794 if (!isLoopInvariant(RHS, L))
797 auto *StrideC = dyn_cast<SCEVConstant>(AR->getStepRecurrence(*
this));
798 if (!StrideC || !StrideC->getAPInt().isPowerOf2())
801 if (!ControlsExit || !loopHasNoAbnormalExits(L))
808 if (
auto *ZExt = dyn_cast<SCEVZeroExtendExpr>(LHS)) {
809 const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(ZExt->getOperand());
810 if (AR && AR->getLoop() == L && AR->isAffine()) {
811 auto Flags = AR->getNoWrapFlags();
812 if (!hasFlags(Flags, SCEV::FlagNW) && canAssumeNoSelfWrap(AR)) {
813 Flags = setFlags(Flags, SCEV::FlagNW);
815 SmallVector<const SCEV *, 4> Operands{AR->operands()};
816 Flags = StrengthenNoWrapFlags(
this, scAddRecExpr, Operands, Flags);
818 setNoWrapFlags(
const_cast<SCEVAddRecExpr *
>(AR), Flags);
820 if (AR->hasNoUnsignedWrap()) {
823 const SCEV *Step = AR->getStepRecurrence(*
this);
824 Type *Ty = ZExt->getType();
825 auto *S = getAddRecExpr(
826 getExtendAddRecStart<SCEVZeroExtendExpr>(AR, Ty,
this, 0),
827 getZeroExtendExpr(Step, Ty, 0), L, AR->getNoWrapFlags());
828 IV = dyn_cast<SCEVAddRecExpr>(S);
834 if (!IV && AllowPredicates) {
838 IV = convertSCEVToAddRecWithPredicates(LHS, L, Predicates);
843 if (!IV || IV->getLoop() != L || !IV->isAffine())
844 return getCouldNotCompute();
856 auto WrapType = IsSigned ? SCEV::FlagNSW : SCEV::FlagNUW;
858#if LLVM_VERSION_MAJOR >= 23
859 bool NoWrap = ControlsExit && any(IV->getNoWrapFlags(WrapType));
861 bool NoWrap = ControlsExit && IV->getNoWrapFlags(WrapType);
864 ICmpInst::Predicate Cond = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
866 const SCEV *Stride = IV->getStepRecurrence(*
this);
868 bool PositiveStride = isKnownPositive(Stride);
871 if (!PositiveStride) {
905 !loopHasNoAbnormalExits(L)) {
906 return getCouldNotCompute();
913 if (IsSigned && isKnownNonPositive(Stride))
914 return getCouldNotCompute();
916 if (!isKnownNonZero(Stride)) {
920 if (!isLoopInvariant(RHS, L))
921 return getCouldNotCompute();
931 auto wouldZeroStrideBeUB = [&]() {
940 auto *StartIfZero = getMinusSCEV(IV->getStart(), Stride);
941 return isLoopEntryGuardedByCond(L, Cond, StartIfZero, RHS);
943 if (!wouldZeroStrideBeUB()) {
944 Stride = getUMaxExpr(Stride, getOne(Stride->getType()));
947 }
else if (!Stride->isOne() && !NoWrap) {
948 auto isUBOnWrap = [&]() {
954 return canAssumeNoSelfWrap(IV);
961 if (canIVOverflowOnLT(RHS, Stride, IsSigned) && !isUBOnWrap())
962 return getCouldNotCompute();
974 const SCEV *Start = IV->getStart();
980 const SCEV *OrigStart = Start;
981 const SCEV *OrigRHS = RHS;
982 if (Start->getType()->isPointerTy()) {
983 Start = getLosslessPtrToIntExpr(Start);
984 if (isa<SCEVCouldNotCompute>(Start))
987 if (RHS->getType()->isPointerTy()) {
988 RHS = getLosslessPtrToIntExpr(RHS);
989 if (isa<SCEVCouldNotCompute>(RHS))
998 if (!isLoopInvariant(RHS, L)) {
999 const SCEV *MaxBECount = computeMaxBECountForLT(
1000 Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned);
1001#if LLVM_VERSION_MAJOR >= 16
1002 return ExitLimit(getCouldNotCompute() , MaxBECount,
1003 MaxBECount,
false , Predicates);
1005 return ExitLimit(getCouldNotCompute() , MaxBECount,
1006 false , Predicates);
1014 const SCEV *BECount =
nullptr;
1015 auto *OrigStartMinusStride = getMinusSCEV(OrigStart, Stride);
1016 assert(isAvailableAtLoopEntry(OrigStartMinusStride, L) &&
"Must be!");
1017 assert(isAvailableAtLoopEntry(OrigStart, L) &&
"Must be!");
1018 assert(isAvailableAtLoopEntry(OrigRHS, L) &&
"Must be!");
1020 if (isLoopEntryGuardedByCond(L, Cond, OrigStartMinusStride, OrigStart) &&
1021 isLoopEntryGuardedByCond(L, Cond, OrigStartMinusStride, OrigRHS)) {
1040 const SCEV *MinusOne = getMinusOne(Stride->getType());
1041 const SCEV *Numerator =
1042 getMinusSCEV(getAddExpr(RHS, MinusOne), getMinusSCEV(Start, Stride));
1043 BECount = getUDivExpr(Numerator, Stride);
1046 const SCEV *BECountIfBackedgeTaken =
nullptr;
1048 auto canProveRHSGreaterThanEqualStart = [&]() {
1049 auto CondGE = IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
1050 if (isLoopEntryGuardedByCond(L, CondGE, OrigRHS, OrigStart))
1062 auto CondGT = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
1063 auto *StartMinusOne =
1064 getAddExpr(OrigStart, getMinusOne(OrigStart->getType()));
1065 return isLoopEntryGuardedByCond(L, CondGT, OrigRHS, StartMinusOne);
1071 if (canProveRHSGreaterThanEqualStart()) {
1082 End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);
1086 BECountIfBackedgeTaken =
1087 getUDivCeilSCEV(getMinusSCEV(RHS, Start), Stride);
1101 const SCEV *One = getOne(Stride->getType());
1102 bool MayAddOverflow = [&] {
1103 if (
auto *StrideC = dyn_cast<SCEVConstant>(Stride)) {
1104 if (StrideC->getAPInt().isPowerOf2()) {
1149 if (Start == Stride || Start == getMinusSCEV(Stride, One)) {
1160 const SCEV *Delta = getMinusSCEV(End, Start);
1161 if (!MayAddOverflow) {
1165 getUDivExpr(getAddExpr(Delta, getMinusSCEV(Stride, One)), Stride);
1167 BECount = getUDivCeilSCEV(Delta, Stride);
1171 const SCEV *MaxBECount;
1172 bool MaxOrZero =
false;
1173 if (isa<SCEVConstant>(BECount)) {
1174 MaxBECount = BECount;
1175 }
else if (BECountIfBackedgeTaken &&
1176 isa<SCEVConstant>(BECountIfBackedgeTaken)) {
1180 MaxBECount = BECountIfBackedgeTaken;
1183 MaxBECount = computeMaxBECountForLT(
1184 Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned);
1187 if (isa<SCEVCouldNotCompute>(MaxBECount) &&
1188 !isa<SCEVCouldNotCompute>(BECount))
1189 MaxBECount = getConstant(getUnsignedRangeMax(BECount));
1190#if LLVM_VERSION_MAJOR >= 16
1191 return ExitLimit(BECount, MaxBECount, MaxBECount, MaxOrZero, Predicates);
1193 return ExitLimit(BECount, MaxBECount, MaxOrZero, Predicates);
1198 const SCEV *LHS,
const SCEV *RHS,
const Loop *L,
bool IsSigned,
1199 bool ControlsExit,
bool AllowPredicates) {
1200 SmallPtrSet<const SCEVPredicate *, 4> Predicates;
1202 const SCEVAddRecExpr *IV = dyn_cast<SCEVAddRecExpr>(LHS);
1204 if (!IV && AllowPredicates) {
1208 IV = convertSCEVToAddRecWithPredicates(LHS, L, Predicates);
1212 if (!IV || IV->getLoop() != L || !IV->isAffine())
1213 return getCouldNotCompute();
1215 bool NoWrap = ControlsExit &&
true;
1218 const SCEV *Stride = IV->getStepRecurrence(*
this);
1220 bool PositiveStride = isKnownPositive(Stride);
1223 if (!PositiveStride) {
1267 return getCouldNotCompute();
1268 }
else if (!Stride->isOne() &&
1269 doesIVOverflowOnLT(RHS, Stride, IsSigned, NoWrap))
1274 return getCouldNotCompute();
1276 ICmpInst::Predicate Cond = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
1277 const SCEV *Start = IV->getStart();
1278 const SCEV *End = RHS;
1284 if (!isLoopInvariant(RHS, L)) {
1285 const SCEV *MaxBECount = computeMaxBECountForLT(
1286 Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned);
1287 return ExitLimit(getCouldNotCompute() , MaxBECount,
1288 false , Predicates);
1294 const SCEV *BECountIfBackedgeTaken =
1295 computeBECount(getMinusSCEV(End, Start), Stride,
false);
1303 const SCEV *BECount;
1304 if (isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(Start, Stride), RHS))
1305 BECount = BECountIfBackedgeTaken;
1307 End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);
1308 BECount = computeBECount(getMinusSCEV(End, Start), Stride,
false);
1311 const SCEV *MaxBECount;
1312 bool MaxOrZero =
false;
1313 if (isa<SCEVConstant>(BECount))
1314 MaxBECount = BECount;
1315 else if (isa<SCEVConstant>(BECountIfBackedgeTaken)) {
1319 MaxBECount = BECountIfBackedgeTaken;
1322 MaxBECount = computeMaxBECountForLT(
1323 Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned);
1326 if (isa<SCEVCouldNotCompute>(MaxBECount) &&
1327 !isa<SCEVCouldNotCompute>(BECount))
1328 MaxBECount = getConstant(getUnsignedRangeMax(BECount));
1330 return ExitLimit(BECount, MaxBECount, MaxOrZero, Predicates);
1334#pragma clang diagnostic pop
1336#pragma GCC diagnostic pop
static llvm::SmallPtrSet< llvm::BasicBlock *, 4 > getGuaranteedUnreachable(llvm::Function *F)
ScalarEvolution::ExitLimit howManyLessThans(const llvm::SCEV *LHS, const llvm::SCEV *RHS, const llvm::Loop *L, bool IsSigned, bool ControlsExit, bool AllowPredicates)
llvm::SmallPtrSet< llvm::BasicBlock *, 4 > GuaranteedUnreachable
ScalarEvolution::ExitLimit computeExitLimitFromICmp(const llvm::Loop *L, llvm::ICmpInst *ExitCond, bool ExitIfTrue, bool ControlsExit, bool AllowPredicates=false)
ScalarEvolution::ExitLimit computeExitLimitFromCond(const llvm::Loop *L, llvm::Value *ExitCond, bool ExitIfTrue, bool ControlsExit, bool AllowPredicates)
ScalarEvolution::ExitLimit computeExitLimitFromSingleExitSwitch(const llvm::Loop *L, llvm::SwitchInst *Switch, llvm::BasicBlock *ExitingBB, bool IsSubExpr)
ScalarEvolution::ExitLimit computeExitLimit(const llvm::Loop *L, llvm::BasicBlock *ExitingBlock, bool AllowPredicates)
ScalarEvolution::ExitLimit computeExitLimitFromCondCached(ExitLimitCacheTy &Cache, const llvm::Loop *L, llvm::Value *ExitCond, bool ExitIfTrue, bool ControlsExit, bool AllowPredicates)
ScalarEvolution::ExitLimit computeExitLimitFromCondImpl(ExitLimitCacheTy &Cache, const llvm::Loop *L, llvm::Value *ExitCond, bool ExitIfTrue, bool ControlsExit, bool AllowPredicates)
MustExitScalarEvolution(llvm::Function &F, llvm::TargetLibraryInfo &TLI, llvm::AssumptionCache &AC, llvm::DominatorTree &DT, llvm::LoopInfo &LI)
bool loopIsFiniteByAssumption(const llvm::Loop *L)