Memref.reinterpret_cast op - static sizes, strides, offset - redundant op attributes

A couple of things reg. memref.reinterpret_cast that was added in Oct 2020.

def MemRef_ReinterpretCastOp:

let description = [{
    Modify offset, sizes and strides of an unranked/ranked memref.

    memref.reinterpret_cast %ranked to
      offset: [0],
      sizes: [%size0, 10],
      strides: [1, %stride1]
    : memref<?x?xf32> to memref<?x10xf32, offset: 0, strides: [1, ?]>
    memref.reinterpret_cast %unranked to
      offset: [%offset],
      sizes: [%size0, %size1],
      strides: [%stride0, %stride1]
    : memref<*xf32> to memref<?x?xf32, offset: ?, strides: [?, ?]>
  let arguments = (ins
    Arg<AnyRankedOrUnrankedMemRef, "", []>:$source,

  1. I couldn’t tell here from the description as to why memref.reinterpret_cast was storing static_sizes/strides/offsets as op attributes! These are already part of the result memref type of the op (its shape and affine layout map carry this information)! They can already be obtained via getStridesAndOffset and getShape() from the result type. So these are just redundant information and potentially introduce inconsistency.

  2. Both the syntax and description suggests a single offset - it’s not clear why static_offsets is an ArrayAttr.

  3. The build method can either take the result type or the constant strides, shape, and offset (when they are constant) but not both! – because these represent the same information! One can add a custom build method when the stride/shape/offset info is all static and then construct the op from that.

Update: I noticed that the sizes, strides and offset of the result memref are being carried along separately on the op instead of in the memref type itself - so one has to look at the op definition to see what these are. But these can just be carried in the memref type itself.

Tagging authors: @pifon2a