@@ -239,6 +239,42 @@ bool AffineExpr::isPureAffine() const {
239239 llvm_unreachable (" Unknown AffineExpr" );
240240}
241241
242+ static bool isNonNegativeConstant (AffineExpr expr) {
243+ auto constant = dyn_cast<AffineConstantExpr>(expr);
244+ return constant && constant.getValue () >= 0 ;
245+ }
246+
247+ bool AffineExpr::isMonotonicallyIncreasing () const {
248+ switch (getKind ()) {
249+ case AffineExprKind::SymbolId:
250+ case AffineExprKind::DimId:
251+ case AffineExprKind::Constant:
252+ return true ;
253+ case AffineExprKind::Add: {
254+ auto op = llvm::cast<AffineBinaryOpExpr>(*this );
255+ return op.getLHS ().isMonotonicallyIncreasing () &&
256+ op.getRHS ().isMonotonicallyIncreasing ();
257+ }
258+ case AffineExprKind::Mul: {
259+ // One operand must be a non-negative constant.
260+ auto op = llvm::cast<AffineBinaryOpExpr>(*this );
261+ return op.getLHS ().isMonotonicallyIncreasing () &&
262+ op.getRHS ().isMonotonicallyIncreasing () &&
263+ (isNonNegativeConstant (op.getLHS ()) ||
264+ isNonNegativeConstant (op.getRHS ()));
265+ }
266+ case AffineExprKind::FloorDiv:
267+ case AffineExprKind::CeilDiv: {
268+ auto op = llvm::cast<AffineBinaryOpExpr>(*this );
269+ return op.getLHS ().isMonotonicallyIncreasing () &&
270+ isNonNegativeConstant (op.getRHS ());
271+ }
272+ case AffineExprKind::Mod:
273+ return false ;
274+ }
275+ llvm_unreachable (" Unknown AffineExpr" );
276+ }
277+
242278// Returns the greatest known integral divisor of this affine expression.
243279int64_t AffineExpr::getLargestKnownDivisor () const {
244280 AffineBinaryOpExpr binExpr (nullptr );
0 commit comments