@@ -5509,6 +5509,17 @@ ScalarEvolution::getRangeRef(const SCEV *S,
5509
5509
ConservativeResult =
5510
5510
ConservativeResult.intersectWith (RangeFromFactoring, RangeType);
5511
5511
}
5512
+
5513
+ // Now try symbolic BE count and more powerful methods.
5514
+ MaxBECount = computeMaxBackedgeTakenCount (AddRec->getLoop ());
5515
+ if (!isa<SCEVCouldNotCompute>(MaxBECount) &&
5516
+ getTypeSizeInBits (MaxBECount->getType ()) <= BitWidth &&
5517
+ AddRec->hasNoSelfWrap ()) {
5518
+ auto RangeFromAffineNew = getRangeForAffineNoSelfWrappingAR (
5519
+ AddRec, MaxBECount, BitWidth, SignHint);
5520
+ ConservativeResult =
5521
+ ConservativeResult.intersectWith (RangeFromAffineNew, RangeType);
5522
+ }
5512
5523
}
5513
5524
5514
5525
return setRange (AddRec, SignHint, std::move (ConservativeResult));
@@ -5678,6 +5689,67 @@ ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
5678
5689
return SR.intersectWith (UR, ConstantRange::Smallest);
5679
5690
}
5680
5691
5692
+ ConstantRange ScalarEvolution::getRangeForAffineNoSelfWrappingAR (
5693
+ const SCEVAddRecExpr *AddRec, const SCEV *MaxBECount, unsigned BitWidth,
5694
+ ScalarEvolution::RangeSignHint SignHint) {
5695
+ assert (AddRec->isAffine () && " Non-affine AddRecs are not suppored!\n " );
5696
+ assert (AddRec->hasNoSelfWrap () &&
5697
+ " This only works for non-self-wrapping AddRecs!" );
5698
+ const bool IsSigned = SignHint == HINT_RANGE_SIGNED;
5699
+ const SCEV *Step = AddRec->getStepRecurrence (*this );
5700
+ // Let's make sure that we can prove that we do not self-wrap during
5701
+ // MaxBECount iterations. We need this because MaxBECount is a maximum
5702
+ // iteration count estimate, and we might infer nw from some exit for which we
5703
+ // do not know max exit count (or any other side reasoning).
5704
+ // TODO: Turn into assert at some point.
5705
+ MaxBECount = getNoopOrZeroExtend (MaxBECount, AddRec->getType ());
5706
+ const SCEV *RangeWidth = getNegativeSCEV (getOne (AddRec->getType ()));
5707
+ const SCEV *StepAbs = getUMinExpr (Step, getNegativeSCEV (Step));
5708
+ const SCEV *MaxItersWithoutWrap = getUDivExpr (RangeWidth, StepAbs);
5709
+ if (!isKnownPredicate (ICmpInst::ICMP_ULE, MaxBECount, MaxItersWithoutWrap))
5710
+ return ConstantRange::getFull (BitWidth);
5711
+
5712
+ ICmpInst::Predicate LEPred =
5713
+ IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
5714
+ ICmpInst::Predicate GEPred =
5715
+ IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
5716
+ const SCEV *Start = AddRec->getStart ();
5717
+ const SCEV *End = AddRec->evaluateAtIteration (MaxBECount, *this );
5718
+ // We could handle non-constant End, but it harms compile time a lot.
5719
+ if (!isa<SCEVConstant>(End))
5720
+ return ConstantRange::getFull (BitWidth);
5721
+
5722
+ // We know that there is no self-wrap. Let's take Start and End values and
5723
+ // look at all intermediate values V1, V2, ..., Vn that IndVar takes during
5724
+ // the iteration. They either lie inside the range [Min(Start, End),
5725
+ // Max(Start, End)] or outside it:
5726
+ //
5727
+ // Case 1: RangeMin ... Start V1 ... VN End ... RangeMax;
5728
+ // Case 2: RangeMin Vk ... V1 Start ... End Vn ... Vk + 1 RangeMax;
5729
+ //
5730
+ // No self wrap flag guarantees that the intermediate values cannot be BOTH
5731
+ // outside and inside the range [Min(Start, End), Max(Start, End)]. Using that
5732
+ // knowledge, let's try to prove that we are dealing with Case 1. It is so if
5733
+ // Start <= End and step is positive, or Start >= End and step is negative.
5734
+ ConstantRange StartRange =
5735
+ IsSigned ? getSignedRange (Start) : getUnsignedRange (Start);
5736
+ ConstantRange EndRange =
5737
+ IsSigned ? getSignedRange (End) : getUnsignedRange (End);
5738
+ ConstantRange RangeBetween = StartRange.unionWith (EndRange);
5739
+ // If they already cover full iteration space, we will know nothing useful
5740
+ // even if we prove what we want to prove.
5741
+ if (RangeBetween.isFullSet ())
5742
+ return RangeBetween;
5743
+
5744
+ if (isKnownPositive (Step) &&
5745
+ isKnownViaNonRecursiveReasoning (LEPred, Start, End))
5746
+ return RangeBetween;
5747
+ else if (isKnownNegative (Step) &&
5748
+ isKnownViaNonRecursiveReasoning (GEPred, Start, End))
5749
+ return RangeBetween;
5750
+ return ConstantRange::getFull (BitWidth);
5751
+ }
5752
+
5681
5753
ConstantRange ScalarEvolution::getRangeViaFactoring (const SCEV *Start,
5682
5754
const SCEV *Step,
5683
5755
const SCEV *MaxBECount,
0 commit comments