mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 03:56:08 +00:00

Summary: This patch proposes new llvm types for RISCV vector tuples represented as `TargetExtType` which contains both `LMUL` and `NF`(num_fields) information and keep it all the way down to `selectionDAG` to match the corresponding `MVT`(support in the following patch). Detail: Currently we have built-in C types for RISCV vector tuple type, e.g. `vint32m1x2_t`, however it's is represented as structure of scalable vector types, i.e. `{<vscale x 2 x i32>, <vscale x 2 x i32>}`. It loses the information for num_fields(NF) as struct is flattened during `selectionDAG`, thus it makes it not possible to handle inline assembly of vector tuple type, it also makes the calling convention of vector tuple types handing not strait forward and hard to realize the allocation code, i.e. `RVVArgDispatcher`. The llvm IR for the example above is then represented as `target("riscv.vector.tuple", <vscale x 8 x i8>, 2)` in which the first type parameter is the equivalent size scalable vecotr of i8 element type, the following integer parameter is the `NF` of the tuple. The new RISCV specific vector insert/extract intrinsics are also added as `llvm.riscv.vector.insert` and `llvm.riscv.vector.extract` to handle tuple type subvector insertion/extraction since the generic ones only operates on `VectorType` but not `TargetExtType`. There are total of 32 llvm types added for each `VREGS * NF <= 8`, where `VREGS` is the vector registers needed for each `LMUL` and `NF` is num_fields. The name of types are: ``` target("riscv.vector.tuple", <vscale x 1 x i8>, 2) // LMUL = mf8, NF = 2 target("riscv.vector.tuple", <vscale x 1 x i8>, 3) // LMUL = mf8, NF = 3 target("riscv.vector.tuple", <vscale x 1 x i8>, 4) // LMUL = mf8, NF = 4 target("riscv.vector.tuple", <vscale x 1 x i8>, 5) // LMUL = mf8, NF = 5 target("riscv.vector.tuple", <vscale x 1 x i8>, 6) // LMUL = mf8, NF = 6 target("riscv.vector.tuple", <vscale x 1 x i8>, 7) // LMUL = mf8, NF = 7 target("riscv.vector.tuple", <vscale x 1 x i8>, 8) // LMUL = mf8, NF = 8 target("riscv.vector.tuple", <vscale x 2 x i8>, 2) // LMUL = mf4, NF = 2 target("riscv.vector.tuple", <vscale x 2 x i8>, 3) // LMUL = mf4, NF = 3 target("riscv.vector.tuple", <vscale x 2 x i8>, 4) // LMUL = mf4, NF = 4 target("riscv.vector.tuple", <vscale x 2 x i8>, 5) // LMUL = mf4, NF = 5 target("riscv.vector.tuple", <vscale x 2 x i8>, 6) // LMUL = mf4, NF = 6 target("riscv.vector.tuple", <vscale x 2 x i8>, 7) // LMUL = mf4, NF = 7 target("riscv.vector.tuple", <vscale x 2 x i8>, 8) // LMUL = mf4, NF = 8 target("riscv.vector.tuple", <vscale x 4 x i8>, 2) // LMUL = mf2, NF = 2 target("riscv.vector.tuple", <vscale x 4 x i8>, 3) // LMUL = mf2, NF = 3 target("riscv.vector.tuple", <vscale x 4 x i8>, 4) // LMUL = mf2, NF = 4 target("riscv.vector.tuple", <vscale x 4 x i8>, 5) // LMUL = mf2, NF = 5 target("riscv.vector.tuple", <vscale x 4 x i8>, 6) // LMUL = mf2, NF = 6 target("riscv.vector.tuple", <vscale x 4 x i8>, 7) // LMUL = mf2, NF = 7 target("riscv.vector.tuple", <vscale x 4 x i8>, 8) // LMUL = mf2, NF = 8 target("riscv.vector.tuple", <vscale x 8 x i8>, 2) // LMUL = m1, NF = 2 target("riscv.vector.tuple", <vscale x 8 x i8>, 3) // LMUL = m1, NF = 3 target("riscv.vector.tuple", <vscale x 8 x i8>, 4) // LMUL = m1, NF = 4 target("riscv.vector.tuple", <vscale x 8 x i8>, 5) // LMUL = m1, NF = 5 target("riscv.vector.tuple", <vscale x 8 x i8>, 6) // LMUL = m1, NF = 6 target("riscv.vector.tuple", <vscale x 8 x i8>, 7) // LMUL = m1, NF = 7 target("riscv.vector.tuple", <vscale x 8 x i8>, 8) // LMUL = m1, NF = 8 target("riscv.vector.tuple", <vscale x 16 x i8>, 2) // LMUL = m2, NF = 2 target("riscv.vector.tuple", <vscale x 16 x i8>, 3) // LMUL = m2, NF = 3 target("riscv.vector.tuple", <vscale x 16 x i8>, 4) // LMUL = m2, NF = 4 target("riscv.vector.tuple", <vscale x 32 x i8>, 2) // LMUL = m4, NF = 2 ``` RFC: https://discourse.llvm.org/t/rfc-support-riscv-vector-tuple-type-in-llvm/80005