RE: [PATCH v1] RISC-V: Bugfix for vls integer mode calling convention

2024-01-30 Thread Li, Pan2
Thanks Kito for comments, rebase the upstream and always goes to GPR in V2.

https://gcc.gnu.org/pipermail/gcc-patches/2024-January/644291.html

Pan

-Original Message-
From: Kito Cheng  
Sent: Monday, January 29, 2024 9:23 PM
To: Li, Pan2 
Cc: gcc-patches@gcc.gnu.org; juzhe.zh...@rivai.ai; Wang, Yanzhang 

Subject: Re: [PATCH v1] RISC-V: Bugfix for vls integer mode calling convention

> @@ -4868,6 +4968,63 @@ riscv_pass_fpr_pair (machine_mode mode, unsigned 
> regno1,
>GEN_INT (offset2;
>  }
>
> +static rtx
> +riscv_pass_vls_aggregate_in_gpr_or_fpr (struct riscv_arg_info *info,
> +   machine_mode mode, unsigned gpr_base,
> +   unsigned fpr_base)

Tried a few more clang and GCC code gen and I found VLS vector is
always passed in
GPR, and never passed in FPR, so I think I should update psABI rather than fix
that on GCC side.

> @@ -4997,9 +5170,7 @@ riscv_get_arg_info (struct riscv_arg_info *info, const 
> CUMULATIVE_ARGS *cum,
>info->gpr_offset = cum->num_gprs;
>info->fpr_offset = cum->num_fprs;
>
> -  /* When disable vector_abi or scalable vector argument is anonymous, this
> - argument is passed by reference.  */
> -  if (riscv_v_ext_mode_p (mode) && (!riscv_vector_abi || !named))
> +  if (riscv_mode_pass_by_reference_p (mode, named))

Keep as it is fine since riscv_vector_abi is gone.

>  return NULL_RTX;
>
>if (named)


Re: [PATCH v1] RISC-V: Bugfix for vls integer mode calling convention

2024-01-29 Thread Kito Cheng
> @@ -4868,6 +4968,63 @@ riscv_pass_fpr_pair (machine_mode mode, unsigned 
> regno1,
>GEN_INT (offset2;
>  }
>
> +static rtx
> +riscv_pass_vls_aggregate_in_gpr_or_fpr (struct riscv_arg_info *info,
> +   machine_mode mode, unsigned gpr_base,
> +   unsigned fpr_base)

Tried a few more clang and GCC code gen and I found VLS vector is
always passed in
GPR, and never passed in FPR, so I think I should update psABI rather than fix
that on GCC side.

> @@ -4997,9 +5170,7 @@ riscv_get_arg_info (struct riscv_arg_info *info, const 
> CUMULATIVE_ARGS *cum,
>info->gpr_offset = cum->num_gprs;
>info->fpr_offset = cum->num_fprs;
>
> -  /* When disable vector_abi or scalable vector argument is anonymous, this
> - argument is passed by reference.  */
> -  if (riscv_v_ext_mode_p (mode) && (!riscv_vector_abi || !named))
> +  if (riscv_mode_pass_by_reference_p (mode, named))

Keep as it is fine since riscv_vector_abi is gone.

>  return NULL_RTX;
>
>if (named)


[PATCH v1] RISC-V: Bugfix for vls integer mode calling convention

2024-01-23 Thread pan2 . li
From: Pan Li 

According to the issue as below.

https://hub.fgit.cf/riscv-non-isa/riscv-elf-psabi-doc/pull/416

When the mode size of vls integer mode is less than 2 * XLEN, we will
take the gpr/fpr for both the args and the return values. Instead of
the reference. For example the below code:

typedef short v8hi __attribute__ ((vector_size (16)));

v8hi __attribute__((noinline))
add (v8hi a, v8hi b)
{
  v8hi r = a + b;
  return r;
}

Before this patch:
add:
  vsetivli zero,8,e16,m1,ta,ma
  vle16.v  v1,0(a1) <== arg by reference
  vle16.v  v2,0(a2) <== arg by reference
  vadd.vv  v1,v1,v2
  vse16.v  v1,0(a0) <== return by reference
  ret

After this patch:
add:
  addi sp,sp,-32
  sd   a0,0(sp)  <== arg by register a0 - a3
  sd   a1,8(sp)
  sd   a2,16(sp)
  sd   a3,24(sp)
  addi a5,sp,16
  vsetivli zero,8,e16,m1,ta,ma
  vle16.v  v2,0(sp)
  vle16.v  v1,0(a5)
  vadd.vv  v1,v1,v2
  vse16.v  v1,0(sp)
  ld   a0,0(sp)  <== return by a0 - a1.
  ld   a1,8(sp)
  addi sp,sp,32
  jr   ra

For vls floating point, the things get more complicated.  We follow
the below rules.

1. Vls element count <= 2 and vls size <= 2 * xlen, go fpr.
2. Vls size <= 2 * xlen, go gpr.
3. Vls size > 2 * xlen, go reference.

One exceptions is V2DF mode, we treat vls mode as aggregated and we will
have TFmode here.  Unforturnately, the emit_move_multi_word cannot take
care of TFmode elegantly and we go to gpr for V2DF mode.

The riscv regression passed for this patch.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_v_ext_vector_or_tuple_mode_p):
New predicate function for vector or tuple vector.
(riscv_v_vls_mode_aggregate_reg_count): New function to
calculate the gpr/fpr count required by vls mode.
(riscv_gpr_unit_size): New function to get gpr in bytes.
(riscv_fpr_unit_size): New function to get fpr in bytes.
(riscv_v_vls_to_gpr_mode): New function convert vls mode to gpr mode.
(riscv_v_vls_to_fpr_mode): New function convert vls mode to fpr mode.
(riscv_pass_vls_aggregate_in_gpr_or_fpr): New function to return
the rtx of gpr/fpr for vls mode.
(riscv_mode_pass_by_reference_p): New predicate function to
indicate the mode will be passed by reference or not.
(riscv_get_arg_info): Add vls mode handling.
(riscv_pass_by_reference): Return false if arg info has no zero
gpr count.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vls/def.h: Add helper marcos.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-1.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-10.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-2.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-3.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-4.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-5.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-6.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-7.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-8.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-9.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-1.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-2.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-3.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-4.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-5.c: New test.
* gcc.target/riscv/rvv/autovec/vls/calling-convention-run-6.c: New test.

Signed-off-by: Pan Li 
---
 gcc/config/riscv/riscv.cc | 185 +-
 .../rvv/autovec/vls/calling-convention-1.c| 154 +++
 .../rvv/autovec/vls/calling-convention-10.c   |  51 +
 .../rvv/autovec/vls/calling-convention-2.c| 142 ++
 .../rvv/autovec/vls/calling-convention-3.c| 130 
 .../rvv/autovec/vls/calling-convention-4.c| 118 +++
 .../rvv/autovec/vls/calling-convention-5.c| 141 +
 .../rvv/autovec/vls/calling-convention-6.c| 129 
 .../rvv/autovec/vls/calling-convention-7.c| 120 
 .../rvv/autovec/vls/calling-convention-8.c|  43 
 .../rvv/autovec/vls/calling-convention-9.c|  51 +
 .../autovec/vls/calling-convention-run-1.c|  55 ++
 .../autovec/vls/calling-convention-run-2.c|  55 ++
 .../autovec/vls/calling-convention-run-3.c|  55 ++
 .../autovec/vls/calling-convention-run-4.c|  55 ++
 .../autovec/vls/calling-convention-run-5.c|  55 ++
 .../autovec/vls/calling-convention-run-6.c|  55 ++
 .../gcc.target/riscv/rvv/autovec/vls/def.h|  74 +++
 18 files changed, 1665 insertions(+), 3 de