[llvm] [RISC-V][GISEL] Select G_BITCAST for scalable vectors (PR #101486)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 16 13:29:18 PDT 2024


topperc wrote:

> Currently, we need to support `load/store` of a vector of pointers. For GISEL, we need to define some new patterns in`RISCVInstrInfoVPseudos.td`.
> 
> If I were to do it in a brute-force way, should we get something like the following (largely copied from [`AllIntegerVectors`](https://github.com/llvm/llvm-project/blob/4eb978026152772bcdd139899e8d0192f7ddbc11/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td#L285)):
> 
> ```c
>     def nxv1i32p0 = VTScalableVec<1, i32, 0>;
>     def nxv2i32p0 = VTScalableVec<2, i32, 0>;
>     def nxv4i32p0 = VTScalableVec<4, i32, 0>;
>     def nxv8i32p0 = VTScalableVec<8, i32, 0>;
>     def nxv1i64p0 = VTScalableVec<1, i64, 0>;
>     def nxv2i64p0 = VTScalableVec<2, i64, 0>;
>     def nxv4i64p0 = VTScalableVec<4, i64, 0>;
>     def nxv8i64p0 = VTScalableVec<8, i64, 0>;
> 
>     defvar vptr32mf2_t = nxv1i32p0;
>     defvar vptr32m1_t = nxv2i32p0;
>     defvar vptr32m2_t = nxv4i32p0;
>     defvar vptr32m4_t = nxv8i32p0;
>     defvar vptr64m1_t = nxv1i64p0;
>     defvar vptr64m2_t = nxv2i64p0;
>     defvar vptr64m4_t = nxv4i64p0;
>     defvar vptr64m8_t = nxv8i64p0;
> 
>     defset list<VTypeInfo> PtrVectors = {
>       def VPTR32MF2: VTypeInfo<vptr32mf2_t, vbool64_t, 32, V_MF2>;
>       def VPTR32M1: VTypeInfo<vptr32m1_t, vbool32_t, 32, V_M1>;
>       def VPTR32M2: GroupVTypeInfo<vptr32m2_t, vptr32m1_t, vbool16_t, 32, V_M2>;
>       def VPTR32M4: GroupVTypeInfo<vptr32m4_t, vptr32m1_t, vbool8_t, 32, V_M4>;
> 
>       def VPTR64M1: VTypeInfo<vptr64m1_t, vbool64_t, 64, V_M1>;
>       def VPTR64M2: GroupVTypeInfo<vptr64m2_t, vptr64m1_t, vbool32_t, 64, V_M2>;
>       def VPTR64M4: GroupVTypeInfo<vptr64m4_t, vptr64m1_t, vbool16_t, 64, V_M4>;
>       def VPTR64M8: GroupVTypeInfo<vptr64m8_t, vptr64m1_t, vbool8_t, 64, V_M8>;
>     }
>   }
> ```
> 
> did I write the patterns correctly?
> 
> And then in `RISCVGISEL.td`:
> 
> ```c
> let Predicates = [IsRV32] in {
> foreach vti = PtrVectors in
>   def VPatUSLoadStoreSDNode<vti.Vector, vti.Log2SEW, vti.LMul, vti.AVL, vti.RegClass>;
> }
> 
> let Predicates = [IsRV64] in ...
> ```
> 
> Even if I wrote the patterns correctly, the issue is that we should really have `XLen` in place of explicit `i32/i64`:
> 
> ```c
>     def p0XLen : PtrValueType<XLenVT, 0>;
>     def  nxv1p0 = VTScalableVec<1, p0XLen, 0>;
>     def  nxv2p0 = VTScalableVec<2, p0XLen, 0>;
>     def  nxv4p0 = VTScalableVec<4, p0XLen, 0>;
>     def  nxv8p0 = VTScalableVec<8, p0XLen, 0>;
> ```
> 
> And how should we use `XLen` uniformly instead of brute-force 32-bit and 64-bit machine separately?

AArch64 handles scalar load/stores of pointers in AArch64InstructionSelector::preISelLower by forcing the type to integer. Can we do something similar?

https://github.com/llvm/llvm-project/pull/101486


More information about the llvm-commits mailing list