Fail to convert memref to llvm

Hi Eveyone,
Could you please help me with this example to understand why I could not lower memref.expand_shape to llvm:

mlir-opt -convert-memref-to-llvm -convert-std-to-llvm -reconcile-unrealized-casts

 #map0 = affine_map<(d0, d1)[s0, s1, s2] -> (d0 * s1 + s0 + d1 * s2)>
 #map1 = affine_map<(d0, d1, d2, d3)[s0, s1, s2, s3, s4] -> (d0 * s1 + s0 + d1 * s2 + d2 * s3 + d3 * s4)>

 func @test(%a: memref<?x?xf64, #map0> ) -> memref<1x?x?x1xf64, #map1>{

    %b = memref.expand_shape %a [[0, 1], [2, 3]] : memref<?x?xf64, #map0> into memref<1x?x?x1xf64, #map1>
     return %b : memref<1x?x?x1xf64, #map1>
 }

The same example works fine if I remove #map1 and #map0.

@ftynse

The lowering is only implemented for memrefs with either a static shape or identity layouts - https://github.com/llvm/llvm-project/blob/main/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp#L1362-L1369. In general, if something fails to lower, running mlir-opt -convert-X-to-Y -debug-only=dialect-conversion gives you enough information to find which pattern failed specifically. @pifon2a may know more about the limitations.

1 Like

@messadki the “identity layout” limitation was introduced mostly to simplify the implementation. Of course, for some cases this limitation can be lifted. There were also plans to introduce a dynamic version of this operation, i.e. the operation that would allow to expand shape from ?x? to ?x?x?x? etc.