/// that the result is undefined if it does.
const SCEV *computeBECount(const SCEV *Delta, const SCEV *Stride);
+ /// Compute ceil(N / D). N and D are treated as unsigned values.
+ ///
+ /// Since SCEV doesn't have native ceiling division, this generates a
+ /// SCEV expression of the following form:
+ ///
+ /// umin(N, 1) + floor((N - umin(N, 1)) / D)
+ ///
+ /// A denominator of zero or poison is handled the same way as getUDivExpr().
+ const SCEV *getUDivCeilSCEV(const SCEV *N, const SCEV *D);
+
/// Compute the maximum backedge count based on the range of values
/// permitted by Start, End, and Stride. This is for loops of the form
/// {Start, +, Stride} LT End.
return (std::move(MinValue) + MaxStrideMinusOne).ugt(MinRHS);
}
+const SCEV *ScalarEvolution::getUDivCeilSCEV(const SCEV *N, const SCEV *D) {
+ // umin(N, 1) + floor((N - umin(N, 1)) / D)
+ // This is equivalent to "1 + floor((N - 1) / D)" for N != 0. The umin
+ // expression fixes the case of N=0.
+ const SCEV *MinNOne = getUMinExpr(N, getOne(N->getType()));
+ const SCEV *NMinusOne = getMinusSCEV(N, MinNOne);
+ return getAddExpr(MinNOne, getUDivExpr(NMinusOne, D));
+}
+
const SCEV *ScalarEvolution::computeBECount(const SCEV *Delta,
const SCEV *Step) {
const SCEV *One = getOne(Step->getType());
APInt MaxEnd = IsSigned ? APIntOps::smin(getSignedRangeMax(End), Limit)
: APIntOps::umin(getUnsignedRangeMax(End), Limit);
- MaxBECount = computeBECount(getConstant(MaxEnd - MinStart) /* Delta */,
- getConstant(StrideForMaxBECount) /* Step */);
+ MaxBECount = getUDivCeilSCEV(getConstant(MaxEnd - MinStart) /* Delta */,
+ getConstant(StrideForMaxBECount) /* Step */);
return MaxBECount;
}
const SCEV *MaxBECount = isa<SCEVConstant>(BECount)
? BECount
- : computeBECount(getConstant(MaxStart - MinEnd),
- getConstant(MinStride));
+ : getUDivCeilSCEV(getConstant(MaxStart - MinEnd),
+ getConstant(MinStride));
if (isa<SCEVCouldNotCompute>(MaxBECount))
MaxBECount = BECount;