[Mlir-commits] [mlir] [mlir][vector] Support multi-dimensional vectors in VectorFromElementsLowering (PR #151175)
Kunwar Grover
llvmlistbot at llvm.org
Fri Aug 8 07:47:16 PDT 2025
Groverkss wrote:
> IIUC, we now have two ways to convert vector to LLVM:
>
> 1. convert-vector-to-llvm pass. It includes two stages: a transformation stage that "lowers vector ops to other vector ops", and a conversion that "lowers vector ops to LLVM ops".
> 2. convert-to-llvm: only includes the latter conversion stage.
>
> We only need to support lowering multi-dim from_elements ops in convert-vector-to-llvm. Please correct me if I'm wrong.
>
> > Expanding populateVectorShapeCastLoweringPatterns (or creating patterns that inject vector.shape_cast and then leveraging populateVectorShapeCastLoweringPatterns) less so - wouldn't we be simply shifting the complexity within vector-to-llvm (as opposed to making it simpler)?
>
> Our goal is keeping the conversion stage simple, right? So it is ok to shift the complexity to `populateVectorShapeCastLoweringPatterns` or `populateVectorFromElementsOpLoweringPatterns`, which both belong to the transformation stage.
>
> > Or my suggestion was to add a pattern there to split a rank-D from_elements op into a rank-1 from_elements op preceded by a shape_cast, and then populateVectorShapeCastLoweringPatterns will kick in and generate the inserts/extracts.
>
> Using shapecast or iteratively unrolling N-D vectors are both ok for me. I'd like to do some experiments to study which method can generate more efficient operations.
I think you are looking at it differently than I think about this. The main thing we are trying to do is:
Convert vector dialect operations on N-D vectors to LLVM (only 1-D vectors) , SPIRV (1-D vectors + other restrictions)
For a N-D vector operation, you can write a simple conversion as this patch did, where you take an N-D operation, and directly lower it to llvm using `llvm.extractvalue/llvm.insertvalue` to model N-D vectors. This has multiple problems:
1. You are relying on LLVM to cleanup chains of llvm.extractvalue/llvm.insertvalue . If you accidently mix directly lowering vector operations using llvm.extractvalue/llvm.insertvalue and unrolled operations, you are using LLVM as a magic box which will fix it for you.
2. In long term, we do not want to emit llvm.extractvalue/llvm.insertvalue at all. Have a look at the recent RFC: https://discourse.llvm.org/t/rfc-towards-disallowing-struct-array-ir-values/87154
3. It's hard to maintain consistency like this. There are two ways to go from N-D vectors to 1-D vectors, unrolling operations or flattening them. If you mix these accidently during conversion, you will never be able to cleanup the boundary between a flattend operation and a unrolled operation.
4. And probably the most important thing, LLVM is not the only backend that vector dialect lowers to. SPIRV is a supported backend and also needs unrolling.
How we ideally want to structure conversion to backends is:
- Set of patterns to do unrolling from N-D vectors to 1-D vectors
- Set of patterns to do flattening from N-D vectors to 1-D vectors (in case someone wants to do this, we dont have patterns for this today)
- Set of patterns to cleanup boundary ops created by unrolling/flattening
- Set of patterns to convert 1-D vector dialect operations to LLVM dialect
- Set of patterns to convert 1-D vector (+ spirv restrictions) dialect operations to SPIRV dialect
with these patterns, we can build any of the passes we have above. But we do not want to mix things between these set of patterns. For example, we should never have a N-D vector dialect operation conversion to LLVM dialect, because that breaks the whole cleanup contract and we have no reuse for SPIRV.
https://github.com/llvm/llvm-project/pull/151175
More information about the Mlir-commits
mailing list