// TODO: non-affine addrec
if (AddRec->isAffine()) {
- const SCEV *MaxBECount =
+ const SCEV *MaxBEScev =
getConstantMaxBackedgeTakenCount(AddRec->getLoop());
- if (!isa<SCEVCouldNotCompute>(MaxBECount) &&
- getTypeSizeInBits(MaxBECount->getType()) <= BitWidth) {
- auto RangeFromAffine = getRangeForAffineAR(
- AddRec->getStart(), AddRec->getStepRecurrence(*this), MaxBECount,
- BitWidth);
- ConservativeResult =
- ConservativeResult.intersectWith(RangeFromAffine, RangeType);
+ if (!isa<SCEVCouldNotCompute>(MaxBEScev)) {
+ APInt MaxBECount = cast<SCEVConstant>(MaxBEScev)->getAPInt();
+ if (MaxBECount.getBitWidth() < BitWidth)
+ MaxBECount = MaxBECount.zext(BitWidth);
+ if (MaxBECount.getBitWidth() == BitWidth) {
+ auto RangeFromAffine = getRangeForAffineAR(
+ AddRec->getStart(), AddRec->getStepRecurrence(*this), MaxBECount);
+ ConservativeResult =
+ ConservativeResult.intersectWith(RangeFromAffine, RangeType);
- auto RangeFromFactoring = getRangeViaFactoring(
- AddRec->getStart(), AddRec->getStepRecurrence(*this), MaxBECount,
- BitWidth);
- ConservativeResult =
- ConservativeResult.intersectWith(RangeFromFactoring, RangeType);
+ auto RangeFromFactoring = getRangeViaFactoring(
+ AddRec->getStart(), AddRec->getStepRecurrence(*this), MaxBECount);
+ ConservativeResult =
+ ConservativeResult.intersectWith(RangeFromFactoring, RangeType);
+ }
}
// Now try symbolic BE count and more powerful methods.
const SCEV *SymbolicMaxBECount =
getSymbolicMaxBackedgeTakenCount(AddRec->getLoop());
if (!isa<SCEVCouldNotCompute>(SymbolicMaxBECount) &&
- getTypeSizeInBits(MaxBECount->getType()) <= BitWidth &&
+ getTypeSizeInBits(MaxBEScev->getType()) <= BitWidth &&
AddRec->hasNoSelfWrap()) {
auto RangeFromAffineNew = getRangeForAffineNoSelfWrappingAR(
AddRec, SymbolicMaxBECount, BitWidth, SignHint);
static ConstantRange getRangeForAffineARHelper(APInt Step,
const ConstantRange &StartRange,
const APInt &MaxBECount,
- unsigned BitWidth, bool Signed) {
+ bool Signed) {
+ unsigned BitWidth = Step.getBitWidth();
+ assert(BitWidth == StartRange.getBitWidth() &&
+ BitWidth == MaxBECount.getBitWidth() && "mismatched bit widths");
// If either Step or MaxBECount is 0, then the expression won't change, and we
// just need to return the initial range.
if (Step == 0 || MaxBECount == 0)
ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
const SCEV *Step,
- const SCEV *MaxBECount,
- unsigned BitWidth) {
- assert(!isa<SCEVCouldNotCompute>(MaxBECount) &&
- getTypeSizeInBits(MaxBECount->getType()) <= BitWidth &&
- "Precondition!");
-
- MaxBECount = getNoopOrZeroExtend(MaxBECount, Start->getType());
- APInt MaxBECountValue = getUnsignedRangeMax(MaxBECount);
+ const APInt &MaxBECount) {
+ assert(getTypeSizeInBits(Start->getType()) ==
+ getTypeSizeInBits(Step->getType()) &&
+ getTypeSizeInBits(Start->getType()) == MaxBECount.getBitWidth() &&
+ "mismatched bit widths");
// First, consider step signed.
ConstantRange StartSRange = getSignedRange(Start);
// If Step can be both positive and negative, we need to find ranges for the
// maximum absolute step values in both directions and union them.
- ConstantRange SR =
- getRangeForAffineARHelper(StepSRange.getSignedMin(), StartSRange,
- MaxBECountValue, BitWidth, /* Signed = */ true);
+ ConstantRange SR = getRangeForAffineARHelper(
+ StepSRange.getSignedMin(), StartSRange, MaxBECount, /* Signed = */ true);
SR = SR.unionWith(getRangeForAffineARHelper(StepSRange.getSignedMax(),
- StartSRange, MaxBECountValue,
- BitWidth, /* Signed = */ true));
+ StartSRange, MaxBECount,
+ /* Signed = */ true));
// Next, consider step unsigned.
ConstantRange UR = getRangeForAffineARHelper(
- getUnsignedRangeMax(Step), getUnsignedRange(Start),
- MaxBECountValue, BitWidth, /* Signed = */ false);
+ getUnsignedRangeMax(Step), getUnsignedRange(Start), MaxBECount,
+ /* Signed = */ false);
// Finally, intersect signed and unsigned ranges.
return SR.intersectWith(UR, ConstantRange::Smallest);
ConstantRange ScalarEvolution::getRangeViaFactoring(const SCEV *Start,
const SCEV *Step,
- const SCEV *MaxBECount,
- unsigned BitWidth) {
+ const APInt &MaxBECount) {
// RangeOf({C?A:B,+,C?P:Q}) == RangeOf(C?{A,+,P}:{B,+,Q})
// == RangeOf({A,+,P}) union RangeOf({B,+,Q})
+ unsigned BitWidth = MaxBECount.getBitWidth();
+ assert(getTypeSizeInBits(Start->getType()) == BitWidth &&
+ getTypeSizeInBits(Step->getType()) == BitWidth &&
+ "mismatched bit widths");
+
struct SelectPattern {
Value *Condition = nullptr;
APInt TrueValue;
const SCEV *FalseStep = this->getConstant(StepPattern.FalseValue);
ConstantRange TrueRange =
- this->getRangeForAffineAR(TrueStart, TrueStep, MaxBECount, BitWidth);
+ this->getRangeForAffineAR(TrueStart, TrueStep, MaxBECount);
ConstantRange FalseRange =
- this->getRangeForAffineAR(FalseStart, FalseStep, MaxBECount, BitWidth);
+ this->getRangeForAffineAR(FalseStart, FalseStep, MaxBECount);
return TrueRange.unionWith(FalseRange);
}