Beginner Q: Help with loops/affine/linalg

This isn’t actually accurate. It is possible to represent parametrically tiled loops with affine.for.

loop.for %i = 0 to %N step %B
affine.for %i = 0 to affine_map<()[s0, s1] -> (s0 ceildiv s1)> (%N, %B)

The approach is to normalize the step to one by scaling your bounds (since %B is expected/known to be positive). I think I’ve mentioned this in the past — there isn’t a loop.for that an affine.for cannot structurally represent.

The above of course makes the lower and upper bound maps semi-affine, which many of the analyses on affine for ops don’t support - but there are still canonicalizations and simplifications that just work (composition, unused/duplicate operand removal, const prop/folding). In any case, it only provides more than what loop.for does in terms of structure and the lowering from affine.for to loop.for always succeeds. With affine grayboxes, even the bounds can trivially become pure affine in cases like these + the restrictions on what dim/symbols can be effectively go away.