Indeed, the bare pointer calling convention only allows statically known shapes: LLVM IR Target - MLIR
In this convention, you cannot pass size, stride and offset info to the lowered function because the memref is lowered to a single “bare” pointer, and nothing else. The size/stride/offset information in the memref must be known statically, so that it can be lowered to llvm.mlir.constant instances in the function body, both in the caller and callee. So, as far as I understand, this is a fundamental limitation of the bare pointer calling convention.
Have you considered using the emit-c-wrappers flag? Also, if this is only for debugging, maybe you can use the execution engine, and you can find some helpers in and around this file that can give you some inspiration: llvm-project/CRunnerUtils.h at main · llvm/llvm-project · GitHub
Thank you for the link!
I found that the link is talking about unranked memrefs, but not dynamically sized memrefs - they should be different, am I understanding right?
For memref<?xi32> type, its rank is fixed to 1 (memref with rank 2 must be memref<?x?xi32>), and the stride still must be 1 because it does not have a custom layout. Hence, I think it is still fine to lower it to a bare pointer.
I haven’t tried it because the generated IR has vector operations for performance and not sure emit-c-wrapper can successfully translate it.
The C runner indeed looks interesting to me!
The link points to a documentation subsection “Bare Pointer Calling Convention for Ranked MemRef”. It clearly states that the bare pointer calling convention supports only “memref types with all dimensions statically known.”
No, it is not. We must have a possibility to query the size of this dimension, i.e. be able to implement memref.dim. It is impossible if the size is not stored anywhere nor known statically. (And before somebody asks, I am certainly aware of the possibility to have null-terminated arrays and I am strongly against it in memref.)
I don’t think convert-func-to-llvm cares if you have vector operations in the function body IR. It only cares about arguments and results of the function. In fact the following works fine when lowered with mlir-opt discourse.mlir --convert-vector-to-llvm -convert-memref-to-llvm -convert-func-to-llvm=emit-c-wrappers -reconcile-unrealized-casts: