Hi I am a beginner and I am struggling to understand the following error:
ukernel.mlir:25:5: error: failed to legalize operation 'builtin.unrealized_conversion_cast' that was explicitly marked illegal
%cmem: memref<1xvector<12x32xf32>>
^
ukernel.mlir:25:5: note: see current operation: %20 = "builtin.unrealized_conversion_cast"(%19) : (!llvm.struct<(ptr<array<12 x vector<32xf32>>>, ptr<array<12 x vector<32xf32>>>, i64, array<1 x i64>, array<1 x i64>)>) -> memref<1xvector<12x32xf32>>
I am using mlir-opt -pass-pipeline="convert-vector-to-llvm,convert-memref-to-llvm,convert-func-to-llvm,reconcile-unrealized-casts" ukernel.mlir > lowered/ukernel.lowered.mlir to lower the snippet to llvm MLIR.
Any insight would be greatly appreciated.
Thank you and apologies if this is a dumb question!
It generally means the type conversion wasn’t completed by some previous passes. Remove the reconcile-unrealized-casts to see the IR and look for unrealized_conversion_cast operations that are not paired with the casts going into the other direction.
Looking at your pass pipeline, it is missing at least lower-affine, convert-scf-to-cf, convert-cf-to-llvm. I also don’t know which version you are at because MLIR at HEAD no longer has convert-memref-to-llvm.
I removed unrealied_conversion_cast and found that there is a vector.load that is not being lowered correctly.
%43 = vector.load %20[%27] : memref<1xvector<12x32xf32>>, vector<12x32xf32>
%44 = builtin.unrealized_conversion_cast %43 : vector<12x32xf32> to !llvm.array<12 x vector<32xf32>>
However, I am unsure of how to get it to lower properly. Maybe this is due to me not using the most recent MLIR commit. I will try to update my LLVM repo and rebuild to see if anything changes.
In any case, does the code make sense? Do you think there might be a better way to express it in another dialect? In general, I am looking to generate code that will perform a sum of outer products using SIMD instructions (FMA specifically). I am doing this to see if the code that is being generated is efficiently utilizing the FMA units on my machine.
The issue is unlikely to just magically go away with a version bump Given that the memref already contains the vector type, it is possible to use memref.load/store here, vector.load/store is mostly intended from loading a vector from a memref of scalars. This will save one lowering steps like vector operation unrolling.
After that change, the code lowers to llvm with -lower-affine -convert-scf-to-cf -memref-expand -finalize-memref-to-llvm -convert-vector-to-llvm -convert-func-to-llvm -convert-cf-to-llvm -reconcile-unrealized-casts producing fmuladd intrinsics in my case.