Can't put AffineMin\Max into AffineIndexed values inside edsc builder

When building operation using edsc, I can’t put AffineMin\Max Values as indices for AffineIndexedValue.

            AffineIndexedValue iv(input), fv(filters), ov(convRes);
            Value ihBounded = affine_min(builder.getIndexType(), minMap, ValueRange{affine_max(builder.getIndexType(), maxMap, ValueRange{ih}), ihDim});
            Value iwBounded = affine_min(builder.getIndexType(), minMap, ValueRange{affine_max(builder.getIndexType(), maxMap, ValueRange{iw}), iwDim});
            iv(b, fi, ihBounded, iwBounded);

will cause an error

 error: 'affine.load' op index must be a dimension or symbol identifier

I traced error to function bool mlir::isValidDim(Value value, Region *region); inside mlir/lib/Dialect/Affine/IR/AffineOps.cpp file,

simple addition of this two cases fix the problem, MLIR successfully converted into LLVMIR and after into executable, computation was correct too.

My question is, is there any reason why affineMin\Max operators couldn’t be used as indicies for AffineIndexedValues, and is my straightforward fix correct? It looks like right now this funciton will always fail for affineMin/Max values.

affine.min/max values can’t actually be used in subscripts unless those values are defined “at the top level” (in which case they become valid symbols). When not at the top level, they introduce “a selection tree” in the access, and subscripts are currently kept free of such conditionals and the complexity that comes with it. The fix you say might have taken you all the way to LLVM but will break all other utilities as well as canonicalizations. You have four options depending on what your goals are with the rest of your pipeline:

  1. Use an affine.if/else instead of the max/min in the subscript.
  2. Create a new scope/“top level” using affine.execute_region and define your max or min right under it.
  3. Outline the part needing a max/min indexing to a separate function (which creates a new top-level - a FuncOp is a new AffineScope)
  4. Use a standard load/store (instead of an affine load/store): there would be no restriction on the index values for such load/stores and they can be used inside affine.for as well.
1 Like