@@ -5527,6 +5527,17 @@ ScalarEvolution::getRangeRef(const SCEV *S,
5527
5527
ConservativeResult =
5528
5528
ConservativeResult.intersectWith (RangeFromFactoring, RangeType);
5529
5529
}
5530
+
5531
+ // Now try symbolic BE count and more powerful methods.
5532
+ MaxBECount = computeMaxBackedgeTakenCount (AddRec->getLoop ());
5533
+ if (!isa<SCEVCouldNotCompute>(MaxBECount) &&
5534
+ getTypeSizeInBits (MaxBECount->getType ()) <= BitWidth &&
5535
+ AddRec->hasNoSelfWrap ()) {
5536
+ auto RangeFromAffineNew = getRangeForAffineNoSelfWrappingAR (
5537
+ AddRec, MaxBECount, BitWidth, SignHint);
5538
+ ConservativeResult =
5539
+ ConservativeResult.intersectWith (RangeFromAffineNew, RangeType);
5540
+ }
5530
5541
}
5531
5542
5532
5543
return setRange (AddRec, SignHint, std::move (ConservativeResult));
@@ -5696,6 +5707,70 @@ ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
5696
5707
return SR.intersectWith (UR, ConstantRange::Smallest);
5697
5708
}
5698
5709
5710
+ ConstantRange ScalarEvolution::getRangeForAffineNoSelfWrappingAR (
5711
+ const SCEVAddRecExpr *AddRec, const SCEV *MaxBECount, unsigned BitWidth,
5712
+ ScalarEvolution::RangeSignHint SignHint) {
5713
+ assert (AddRec->isAffine () && " Non-affine AddRecs are not suppored!\n " );
5714
+ assert (AddRec->hasNoSelfWrap () &&
5715
+ " This only works for non-self-wrapping AddRecs!" );
5716
+ const bool IsSigned = SignHint == HINT_RANGE_SIGNED;
5717
+ const SCEV *Step = AddRec->getStepRecurrence (*this );
5718
+ // Let's make sure that we can prove that we do not self-wrap during
5719
+ // MaxBECount iterations. We need this because MaxBECount is a maximum
5720
+ // iteration count estimate, and we might infer nw from some exit for which we
5721
+ // do not know max exit count (or any other side reasoning).
5722
+ // TODO: Turn into assert at some point.
5723
+ MaxBECount = getNoopOrZeroExtend (MaxBECount, AddRec->getType ());
5724
+ const SCEV *RangeWidth = getNegativeSCEV (getOne (AddRec->getType ()));
5725
+ const SCEV *StepAbs = getUMinExpr (Step, getNegativeSCEV (Step));
5726
+ const SCEV *MaxItersWithoutWrap = getUDivExpr (RangeWidth, StepAbs);
5727
+ if (!isKnownPredicate (ICmpInst::ICMP_ULE, MaxBECount, MaxItersWithoutWrap))
5728
+ return ConstantRange::getFull (BitWidth);
5729
+
5730
+ ICmpInst::Predicate LEPred =
5731
+ IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
5732
+ ICmpInst::Predicate GEPred =
5733
+ IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
5734
+ const SCEV *Start = AddRec->getStart ();
5735
+ const SCEV *End = AddRec->evaluateAtIteration (MaxBECount, *this );
5736
+
5737
+ // We know that there is no self-wrap. Let's take Start and End values and
5738
+ // look at all intermediate values V1, V2, ..., Vn that IndVar takes during
5739
+ // the iteration. They either lie inside the range [Min(Start, End),
5740
+ // Max(Start, End)] or outside it:
5741
+ //
5742
+ // Case 1: RangeMin ... Start V1 ... VN End ... RangeMax;
5743
+ // Case 2: RangeMin Vk ... V1 Start ... End Vn ... Vk + 1 RangeMax;
5744
+ //
5745
+ // No self wrap flag guarantees that the intermediate values cannot be BOTH
5746
+ // outside and inside the range [Min(Start, End), Max(Start, End)]. Using that
5747
+ // knowledge, let's try to prove that we are dealing with Case 1. It is so if
5748
+ // Start <= End and step is positive, or Start >= End and step is negative.
5749
+ ConstantRange StartRange =
5750
+ IsSigned ? getSignedRange (Start) : getUnsignedRange (Start);
5751
+ ConstantRange EndRange =
5752
+ IsSigned ? getSignedRange (End) : getUnsignedRange (End);
5753
+ ConstantRange RangeBetween = StartRange.unionWith (EndRange);
5754
+ // If they already cover full iteration space, we will know nothing useful
5755
+ // even if we prove what we want to prove.
5756
+ if (RangeBetween.isFullSet ())
5757
+ return RangeBetween;
5758
+ // Only deal with ranges that do not wrap (i.e. RangeMin < RangeMax).
5759
+ bool IsWrappingRange =
5760
+ IsSigned ? RangeBetween.getLower ().sge (RangeBetween.getUpper ())
5761
+ : RangeBetween.getLower ().uge (RangeBetween.getUpper ());
5762
+ if (IsWrappingRange)
5763
+ return ConstantRange::getFull (BitWidth);
5764
+
5765
+ if (isKnownPositive (Step) &&
5766
+ isKnownPredicateViaConstantRanges (LEPred, Start, End))
5767
+ return RangeBetween;
5768
+ else if (isKnownNegative (Step) &&
5769
+ isKnownPredicateViaConstantRanges (GEPred, Start, End))
5770
+ return RangeBetween;
5771
+ return ConstantRange::getFull (BitWidth);
5772
+ }
5773
+
5699
5774
ConstantRange ScalarEvolution::getRangeViaFactoring (const SCEV *Start,
5700
5775
const SCEV *Step,
5701
5776
const SCEV *MaxBECount,
0 commit comments