public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v1] RISC-V: Bugfix for vls integer mode calling convention
@ 2024-01-24  3:16 pan2.li
  2024-01-24  3:18 ` juzhe.zhong
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: pan2.li @ 2024-01-24  3:16 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

From: Pan Li <pan2.li@intel.com>

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 <pan2.li@intel.com>
---
 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 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-6.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3ba45ffaa74..fb79a475bbe 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1382,6 +1382,106 @@ riscv_v_ext_mode_p (machine_mode mode)
 	 || riscv_v_ext_vls_mode_p (mode);
 }
 
+/* Return true if it is either of below modes.
+   1. RVV vector mode.
+   2. RVV tuple mode.  */
+
+static bool
+riscv_v_ext_vector_or_tuple_mode_p (machine_mode mode)
+{
+  return riscv_v_ext_vector_mode_p (mode) || riscv_v_ext_tuple_mode_p (mode);
+}
+
+static unsigned
+riscv_v_vls_mode_aggregate_reg_count (unsigned vls_unit_size,
+				      unsigned scalar_unit_size)
+{
+  gcc_assert (vls_unit_size != 0 && scalar_unit_size != 0);
+
+  if (vls_unit_size < scalar_unit_size)
+    return 1;
+
+  return vls_unit_size / scalar_unit_size;
+}
+
+static unsigned short
+riscv_gpr_unit_size ()
+{
+  return GET_MODE_SIZE (Xmode);
+}
+
+static unsigned short
+riscv_fpr_unit_size ()
+{
+  unsigned fpr_size = 0;
+
+  if (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
+    {
+      switch (riscv_abi)
+	{
+	  case ABI_LP64F:
+	  case ABI_ILP32F:
+	    fpr_size = GET_MODE_SIZE (SFmode);
+	    break;
+	}
+    }
+
+  if (TARGET_DOUBLE_FLOAT)
+    {
+      switch (riscv_abi)
+	{
+	  case ABI_LP64F:
+	  case ABI_ILP32F:
+	    fpr_size = GET_MODE_SIZE (SFmode);
+	    break;
+	  case ABI_LP64D:
+	  case ABI_ILP32D:
+	    fpr_size = GET_MODE_SIZE (DFmode);
+	    break;
+	}
+    }
+
+  return fpr_size;
+}
+
+static machine_mode
+riscv_v_vls_to_gpr_mode (unsigned vls_mode_size)
+{
+  switch (vls_mode_size)
+    {
+      case 16:
+	return TImode;
+      case 8:
+	return DImode;
+      case 4:
+	return SImode;
+      case 2:
+	return HImode;
+      case 1:
+	return QImode;
+      default:
+	gcc_unreachable ();
+    }
+}
+
+static machine_mode
+riscv_v_vls_to_fpr_mode (unsigned vls_mode_size)
+{
+  switch (vls_mode_size)
+    {
+      case 16:
+	return TFmode;
+      case 8:
+	return DFmode;
+      case 4:
+	return SFmode;
+      case 2:
+	return HFmode;
+      default:
+	gcc_unreachable ();
+    }
+}
+
 /* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
    NUNITS size for corresponding machine_mode.  */
 
@@ -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)
+{
+  gcc_assert (riscv_v_ext_vls_mode_p (mode));
+
+  unsigned vls_size = GET_MODE_SIZE (mode).to_constant ();
+  unsigned gpr_size = riscv_gpr_unit_size ();
+  unsigned fpr_size = riscv_fpr_unit_size ();
+  unsigned regnum = 0, count = 0;
+  unsigned vls_elem_count = vls_size / GET_MODE_SIZE (GET_MODE_INNER (mode));
+  machine_mode smode = VOIDmode;
+
+  /* For vls floating point >= 16 bytes, it cannot be well token care of when
+     emit_move_multi_word.  For example vls size == 16 bytes when move multi
+     word.  We will hit assert similar to gcc_assert (xpart && ypart).
+     x=(reg:TF 42 fa0)
+     y=(subreg:TF (reg:TI 136) 0)
+
+     Thus, we will go with gpr for vls size >= 16.
+  */
+  if (vls_elem_count <= 2 && FLOAT_MODE_P (mode) && fpr_size && vls_size < 16
+    && IN_RANGE (vls_size, 0, fpr_size * 2))
+    {
+      count = riscv_v_vls_mode_aggregate_reg_count (vls_size, fpr_size);
+
+      if (count + info->fpr_offset <= MAX_ARGS_IN_REGISTERS)
+	{
+	  regnum = fpr_base + info->fpr_offset;
+	  info->num_fprs = count;
+	  smode = riscv_v_vls_to_fpr_mode (vls_size);
+	}
+    }
+  else if (IN_RANGE (vls_size, 0, gpr_size * 2))
+    {
+      count = riscv_v_vls_mode_aggregate_reg_count (vls_size, gpr_size);
+
+      if (count + info->gpr_offset <= MAX_ARGS_IN_REGISTERS)
+	{
+	  regnum = gpr_base + info->gpr_offset;
+	  info->num_gprs = count;
+	  smode = riscv_v_vls_to_gpr_mode (vls_size);
+	}
+    }
+
+  if (!regnum)
+    return NULL_RTX; /* Return NULL_RTX if we cannot find a suitable reg.  */
+
+  gcc_assert (smode != VOIDmode);
+
+  rtx reg = gen_rtx_REG (smode, regnum);
+  rtx x = gen_rtx_EXPR_LIST (VOIDmode, reg, CONST0_RTX (smode));
+
+  return gen_rtx_PARALLEL (mode, gen_rtvec (1, x));
+}
+
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
@@ -4975,6 +5132,22 @@ riscv_get_vector_arg (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
   return NULL_RTX;
 }
 
+/* Return true if the argument mode is passed by reference. Aka:
+   1. Scalable vector argument is anonymous.
+   2. The vector abi is disabled for vector or tuple mode.
+   Else return false.  */
+static bool
+riscv_mode_pass_by_reference_p (machine_mode mode, bool named)
+{
+  if (riscv_v_ext_mode_p (mode) && !named)
+    return true;
+
+  if (riscv_v_ext_vector_or_tuple_mode_p (mode) && !riscv_vector_abi)
+    return true;
+
+  return false;
+}
+
 /* Fill INFO with information about a single argument, and return an RTL
    pattern to pass or return the argument. Return NULL_RTX if argument cannot
    pass or return in registers, then the argument may be passed by reference or
@@ -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))
     return NULL_RTX;
 
   if (named)
@@ -5064,6 +5235,10 @@ riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
 				      fields[1].offset);
 	}
 
+      if (riscv_v_ext_vls_mode_p (mode))
+	return riscv_pass_vls_aggregate_in_gpr_or_fpr (info, mode, gpr_base,
+						       fpr_base);
+
       /* For scalable vector argument.  */
       if (riscv_vector_type_p (type) && riscv_v_ext_mode_p (mode))
 	return riscv_get_vector_arg (info, cum, mode, return_p);
@@ -5196,6 +5371,10 @@ riscv_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
       if (info.num_fprs)
 	return false;
 
+      /* Don't pass by reference if we can use general register(s) for vls.  */
+      if (info.num_gprs && riscv_v_ext_vls_mode_p (arg.mode))
+	return false;
+
       /* Don't pass by reference if we can use vector register groups.  */
       if (info.num_vrs > 0 || info.num_mrs > 0)
 	return false;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-1.c
new file mode 100644
index 00000000000..41e31c258f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-1.c
@@ -0,0 +1,154 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b --param riscv-autovec-preference=scalable -mabi=lp64d -O3" } */
+
+#include "def.h"
+
+DEF_RET1_ARG0 (v1qi)
+DEF_RET1_ARG0 (v2qi)
+DEF_RET1_ARG0 (v4qi)
+DEF_RET1_ARG0 (v8qi)
+DEF_RET1_ARG0 (v16qi)
+DEF_RET1_ARG0 (v32qi)
+DEF_RET1_ARG0 (v64qi)
+DEF_RET1_ARG0 (v128qi)
+DEF_RET1_ARG0 (v256qi)
+DEF_RET1_ARG0 (v512qi)
+DEF_RET1_ARG0 (v1024qi)
+DEF_RET1_ARG0 (v2048qi)
+DEF_RET1_ARG0 (v4096qi)
+
+DEF_RET1_ARG1 (v1qi)
+DEF_RET1_ARG1 (v2qi)
+DEF_RET1_ARG1 (v4qi)
+DEF_RET1_ARG1 (v8qi)
+DEF_RET1_ARG1 (v16qi)
+DEF_RET1_ARG1 (v32qi)
+DEF_RET1_ARG1 (v64qi)
+DEF_RET1_ARG1 (v128qi)
+DEF_RET1_ARG1 (v256qi)
+DEF_RET1_ARG1 (v512qi)
+DEF_RET1_ARG1 (v1024qi)
+DEF_RET1_ARG1 (v2048qi)
+DEF_RET1_ARG1 (v4096qi)
+
+DEF_RET1_ARG2 (v1qi)
+DEF_RET1_ARG2 (v2qi)
+DEF_RET1_ARG2 (v4qi)
+DEF_RET1_ARG2 (v8qi)
+DEF_RET1_ARG2 (v16qi)
+DEF_RET1_ARG2 (v32qi)
+DEF_RET1_ARG2 (v64qi)
+DEF_RET1_ARG2 (v128qi)
+DEF_RET1_ARG2 (v256qi)
+DEF_RET1_ARG2 (v512qi)
+DEF_RET1_ARG2 (v1024qi)
+DEF_RET1_ARG2 (v2048qi)
+DEF_RET1_ARG2 (v4096qi)
+
+DEF_RET1_ARG3 (v1qi)
+DEF_RET1_ARG3 (v2qi)
+DEF_RET1_ARG3 (v4qi)
+DEF_RET1_ARG3 (v8qi)
+DEF_RET1_ARG3 (v16qi)
+DEF_RET1_ARG3 (v32qi)
+DEF_RET1_ARG3 (v64qi)
+DEF_RET1_ARG3 (v128qi)
+DEF_RET1_ARG3 (v256qi)
+DEF_RET1_ARG3 (v512qi)
+DEF_RET1_ARG3 (v1024qi)
+DEF_RET1_ARG3 (v2048qi)
+DEF_RET1_ARG3 (v4096qi)
+
+DEF_RET1_ARG4 (v1qi)
+DEF_RET1_ARG4 (v2qi)
+DEF_RET1_ARG4 (v4qi)
+DEF_RET1_ARG4 (v8qi)
+DEF_RET1_ARG4 (v16qi)
+DEF_RET1_ARG4 (v32qi)
+DEF_RET1_ARG4 (v64qi)
+DEF_RET1_ARG4 (v128qi)
+DEF_RET1_ARG4 (v256qi)
+DEF_RET1_ARG4 (v512qi)
+DEF_RET1_ARG4 (v1024qi)
+DEF_RET1_ARG4 (v2048qi)
+DEF_RET1_ARG4 (v4096qi)
+
+DEF_RET1_ARG5 (v1qi)
+DEF_RET1_ARG5 (v2qi)
+DEF_RET1_ARG5 (v4qi)
+DEF_RET1_ARG5 (v8qi)
+DEF_RET1_ARG5 (v16qi)
+DEF_RET1_ARG5 (v32qi)
+DEF_RET1_ARG5 (v64qi)
+DEF_RET1_ARG5 (v128qi)
+DEF_RET1_ARG5 (v256qi)
+DEF_RET1_ARG5 (v512qi)
+DEF_RET1_ARG5 (v1024qi)
+DEF_RET1_ARG5 (v2048qi)
+DEF_RET1_ARG5 (v4096qi)
+
+DEF_RET1_ARG6 (v1qi)
+DEF_RET1_ARG6 (v2qi)
+DEF_RET1_ARG6 (v4qi)
+DEF_RET1_ARG6 (v8qi)
+DEF_RET1_ARG6 (v16qi)
+DEF_RET1_ARG6 (v32qi)
+DEF_RET1_ARG6 (v64qi)
+DEF_RET1_ARG6 (v128qi)
+DEF_RET1_ARG6 (v256qi)
+DEF_RET1_ARG6 (v512qi)
+DEF_RET1_ARG6 (v1024qi)
+DEF_RET1_ARG6 (v2048qi)
+DEF_RET1_ARG6 (v4096qi)
+
+DEF_RET1_ARG7 (v1qi)
+DEF_RET1_ARG7 (v2qi)
+DEF_RET1_ARG7 (v4qi)
+DEF_RET1_ARG7 (v8qi)
+DEF_RET1_ARG7 (v16qi)
+DEF_RET1_ARG7 (v32qi)
+DEF_RET1_ARG7 (v64qi)
+DEF_RET1_ARG7 (v128qi)
+DEF_RET1_ARG7 (v256qi)
+DEF_RET1_ARG7 (v512qi)
+DEF_RET1_ARG7 (v1024qi)
+DEF_RET1_ARG7 (v2048qi)
+DEF_RET1_ARG7 (v4096qi)
+
+DEF_RET1_ARG8 (v1qi)
+DEF_RET1_ARG8 (v2qi)
+DEF_RET1_ARG8 (v4qi)
+DEF_RET1_ARG8 (v8qi)
+DEF_RET1_ARG8 (v16qi)
+DEF_RET1_ARG8 (v32qi)
+DEF_RET1_ARG8 (v64qi)
+DEF_RET1_ARG8 (v128qi)
+DEF_RET1_ARG8 (v256qi)
+DEF_RET1_ARG8 (v512qi)
+DEF_RET1_ARG8 (v1024qi)
+DEF_RET1_ARG8 (v2048qi)
+DEF_RET1_ARG8 (v4096qi)
+
+DEF_RET1_ARG9 (v1qi)
+DEF_RET1_ARG9 (v2qi)
+DEF_RET1_ARG9 (v4qi)
+DEF_RET1_ARG9 (v8qi)
+DEF_RET1_ARG9 (v16qi)
+DEF_RET1_ARG9 (v32qi)
+DEF_RET1_ARG9 (v64qi)
+DEF_RET1_ARG9 (v128qi)
+DEF_RET1_ARG9 (v256qi)
+DEF_RET1_ARG9 (v512qi)
+DEF_RET1_ARG9 (v1024qi)
+DEF_RET1_ARG9 (v2048qi)
+DEF_RET1_ARG9 (v4096qi)
+
+/* { dg-final { scan-assembler-times {li\s+a[0-1],\s*0} 9 } } */
+/* { dg-final { scan-assembler-times {lbu\s+a0,\s*[0-9]+\(sp\)} 8 } } */
+/* { dg-final { scan-assembler-times {lhu\s+a0,\s*[0-9]+\(sp\)} 8 } } */
+/* { dg-final { scan-assembler-times {lw\s+a0,\s*[0-9]+\(sp\)} 8 } } */
+/* { dg-final { scan-assembler-times {ld\s+a[0-1],\s*[0-9]+\(sp\)} 35 } } */
+/* { dg-final { scan-assembler-times {sb\s+a[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sh\s+a[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sw\s+a[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sd\s+a[0-7],\s*[0-9]+\(sp\)} 103 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-10.c
new file mode 100644
index 00000000000..0abc6cf0146
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-10.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64 --param riscv-autovec-preference=scalable -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "def.h"
+
+/*
+** v4hf_RET1_ARG1:
+** ret
+*/
+DEF_RET1_ARG1 (v4hf)
+
+/*
+** v2sf_RET1_ARG2:
+** addi\s+sp,\s*sp,\s*-16
+** sd\s+a0,\s*0\(sp\)
+** sd\s+a1,\s*8\(sp\)
+** ...
+** ld\s+a0,\s*0\(sp\)
+** addi\s+sp,\s*sp,\s*16
+** jr\s+ra
+*/
+DEF_RET1_ARG2 (v2sf)
+
+/*
+** v4sf_RET1_ARG2:
+** addi\s+sp,\s*sp,\s*-32
+** sd\s+a0,\s*0\(sp\)
+** sd\s+a1,\s*8\(sp\)
+** sd\s+a2,\s*16\(sp\)
+** sd\s+a3,\s*24\(sp\)
+** ...
+** ld\s+a0,\s*0\(sp\)
+** ld\s+a1,\s*8\(sp\)
+** addi\s+sp,\s*sp,\s*32
+** jr\s+ra
+*/
+DEF_RET1_ARG2 (v4sf)
+
+/*
+** v1df_RET1_ARG3:
+** addi\s+sp,\s*sp,\s*-32
+** sd\s+a0,\s*8\(sp\)
+** sd\s+a1,\s*16\(sp\)
+** sd\s+a2,\s*24\(sp\)
+** ...
+** ld\s+a0,\s*8\(sp\)
+** addi\s+sp,\s*sp,\s*32
+** jr\s+ra
+*/
+DEF_RET1_ARG3 (v1df)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-2.c
new file mode 100644
index 00000000000..8544f160e93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-2.c
@@ -0,0 +1,142 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b --param riscv-autovec-preference=scalable -mabi=lp64d -O3" } */
+
+#include "def.h"
+
+DEF_RET1_ARG0 (v1hi)
+DEF_RET1_ARG0 (v2hi)
+DEF_RET1_ARG0 (v4hi)
+DEF_RET1_ARG0 (v8hi)
+DEF_RET1_ARG0 (v16hi)
+DEF_RET1_ARG0 (v32hi)
+DEF_RET1_ARG0 (v64hi)
+DEF_RET1_ARG0 (v128hi)
+DEF_RET1_ARG0 (v256hi)
+DEF_RET1_ARG0 (v512hi)
+DEF_RET1_ARG0 (v1024hi)
+DEF_RET1_ARG0 (v2048hi)
+
+DEF_RET1_ARG1 (v1hi)
+DEF_RET1_ARG1 (v2hi)
+DEF_RET1_ARG1 (v4hi)
+DEF_RET1_ARG1 (v8hi)
+DEF_RET1_ARG1 (v16hi)
+DEF_RET1_ARG1 (v32hi)
+DEF_RET1_ARG1 (v64hi)
+DEF_RET1_ARG1 (v128hi)
+DEF_RET1_ARG1 (v256hi)
+DEF_RET1_ARG1 (v512hi)
+DEF_RET1_ARG1 (v1024hi)
+DEF_RET1_ARG1 (v2048hi)
+
+DEF_RET1_ARG2 (v1hi)
+DEF_RET1_ARG2 (v2hi)
+DEF_RET1_ARG2 (v4hi)
+DEF_RET1_ARG2 (v8hi)
+DEF_RET1_ARG2 (v16hi)
+DEF_RET1_ARG2 (v32hi)
+DEF_RET1_ARG2 (v64hi)
+DEF_RET1_ARG2 (v128hi)
+DEF_RET1_ARG2 (v256hi)
+DEF_RET1_ARG2 (v512hi)
+DEF_RET1_ARG2 (v1024hi)
+DEF_RET1_ARG2 (v2048hi)
+
+DEF_RET1_ARG3 (v1hi)
+DEF_RET1_ARG3 (v2hi)
+DEF_RET1_ARG3 (v4hi)
+DEF_RET1_ARG3 (v8hi)
+DEF_RET1_ARG3 (v16hi)
+DEF_RET1_ARG3 (v32hi)
+DEF_RET1_ARG3 (v64hi)
+DEF_RET1_ARG3 (v128hi)
+DEF_RET1_ARG3 (v256hi)
+DEF_RET1_ARG3 (v512hi)
+DEF_RET1_ARG3 (v1024hi)
+DEF_RET1_ARG3 (v2048hi)
+
+DEF_RET1_ARG4 (v1hi)
+DEF_RET1_ARG4 (v2hi)
+DEF_RET1_ARG4 (v4hi)
+DEF_RET1_ARG4 (v8hi)
+DEF_RET1_ARG4 (v16hi)
+DEF_RET1_ARG4 (v32hi)
+DEF_RET1_ARG4 (v64hi)
+DEF_RET1_ARG4 (v128hi)
+DEF_RET1_ARG4 (v256hi)
+DEF_RET1_ARG4 (v512hi)
+DEF_RET1_ARG4 (v1024hi)
+DEF_RET1_ARG4 (v2048hi)
+
+DEF_RET1_ARG5 (v1hi)
+DEF_RET1_ARG5 (v2hi)
+DEF_RET1_ARG5 (v4hi)
+DEF_RET1_ARG5 (v8hi)
+DEF_RET1_ARG5 (v16hi)
+DEF_RET1_ARG5 (v32hi)
+DEF_RET1_ARG5 (v64hi)
+DEF_RET1_ARG5 (v128hi)
+DEF_RET1_ARG5 (v256hi)
+DEF_RET1_ARG5 (v512hi)
+DEF_RET1_ARG5 (v1024hi)
+DEF_RET1_ARG5 (v2048hi)
+
+DEF_RET1_ARG6 (v1hi)
+DEF_RET1_ARG6 (v2hi)
+DEF_RET1_ARG6 (v4hi)
+DEF_RET1_ARG6 (v8hi)
+DEF_RET1_ARG6 (v16hi)
+DEF_RET1_ARG6 (v32hi)
+DEF_RET1_ARG6 (v64hi)
+DEF_RET1_ARG6 (v128hi)
+DEF_RET1_ARG6 (v256hi)
+DEF_RET1_ARG6 (v512hi)
+DEF_RET1_ARG6 (v1024hi)
+DEF_RET1_ARG6 (v2048hi)
+
+DEF_RET1_ARG7 (v1hi)
+DEF_RET1_ARG7 (v2hi)
+DEF_RET1_ARG7 (v4hi)
+DEF_RET1_ARG7 (v8hi)
+DEF_RET1_ARG7 (v16hi)
+DEF_RET1_ARG7 (v32hi)
+DEF_RET1_ARG7 (v64hi)
+DEF_RET1_ARG7 (v128hi)
+DEF_RET1_ARG7 (v256hi)
+DEF_RET1_ARG7 (v512hi)
+DEF_RET1_ARG7 (v1024hi)
+DEF_RET1_ARG7 (v2048hi)
+
+DEF_RET1_ARG8 (v1hi)
+DEF_RET1_ARG8 (v2hi)
+DEF_RET1_ARG8 (v4hi)
+DEF_RET1_ARG8 (v8hi)
+DEF_RET1_ARG8 (v16hi)
+DEF_RET1_ARG8 (v32hi)
+DEF_RET1_ARG8 (v64hi)
+DEF_RET1_ARG8 (v128hi)
+DEF_RET1_ARG8 (v256hi)
+DEF_RET1_ARG8 (v512hi)
+DEF_RET1_ARG8 (v1024hi)
+DEF_RET1_ARG8 (v2048hi)
+
+DEF_RET1_ARG9 (v1hi)
+DEF_RET1_ARG9 (v2hi)
+DEF_RET1_ARG9 (v4hi)
+DEF_RET1_ARG9 (v8hi)
+DEF_RET1_ARG9 (v16hi)
+DEF_RET1_ARG9 (v32hi)
+DEF_RET1_ARG9 (v64hi)
+DEF_RET1_ARG9 (v128hi)
+DEF_RET1_ARG9 (v256hi)
+DEF_RET1_ARG9 (v512hi)
+DEF_RET1_ARG9 (v1024hi)
+DEF_RET1_ARG9 (v2048hi)
+
+/* { dg-final { scan-assembler-times {li\s+a[0-1],\s*0} 8 } } */
+/* { dg-final { scan-assembler-times {lhu\s+a0,\s*[0-9]+\(sp\)} 8 } } */
+/* { dg-final { scan-assembler-times {lw\s+a0,\s*[0-9]+\(sp\)} 8 } } */
+/* { dg-final { scan-assembler-times {ld\s+a[0-1],\s*[0-9]+\(sp\)} 33 } } */
+/* { dg-final { scan-assembler-times {sh\s+a[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sw\s+a[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sd\s+a[0-7],\s*[0-9]+\(sp\)} 103 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-3.c
new file mode 100644
index 00000000000..17b06933c72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-3.c
@@ -0,0 +1,130 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b --param riscv-autovec-preference=scalable -mabi=lp64d -O3" } */
+
+#include "def.h"
+
+DEF_RET1_ARG0 (v1si)
+DEF_RET1_ARG0 (v2si)
+DEF_RET1_ARG0 (v4si)
+DEF_RET1_ARG0 (v8si)
+DEF_RET1_ARG0 (v16si)
+DEF_RET1_ARG0 (v32si)
+DEF_RET1_ARG0 (v64si)
+DEF_RET1_ARG0 (v128si)
+DEF_RET1_ARG0 (v256si)
+DEF_RET1_ARG0 (v512si)
+DEF_RET1_ARG0 (v1024si)
+
+DEF_RET1_ARG1 (v1si)
+DEF_RET1_ARG1 (v2si)
+DEF_RET1_ARG1 (v4si)
+DEF_RET1_ARG1 (v8si)
+DEF_RET1_ARG1 (v16si)
+DEF_RET1_ARG1 (v32si)
+DEF_RET1_ARG1 (v64si)
+DEF_RET1_ARG1 (v128si)
+DEF_RET1_ARG1 (v256si)
+DEF_RET1_ARG1 (v512si)
+DEF_RET1_ARG1 (v1024si)
+
+DEF_RET1_ARG2 (v1si)
+DEF_RET1_ARG2 (v2si)
+DEF_RET1_ARG2 (v4si)
+DEF_RET1_ARG2 (v8si)
+DEF_RET1_ARG2 (v16si)
+DEF_RET1_ARG2 (v32si)
+DEF_RET1_ARG2 (v64si)
+DEF_RET1_ARG2 (v128si)
+DEF_RET1_ARG2 (v256si)
+DEF_RET1_ARG2 (v512si)
+DEF_RET1_ARG2 (v1024si)
+
+DEF_RET1_ARG3 (v1si)
+DEF_RET1_ARG3 (v2si)
+DEF_RET1_ARG3 (v4si)
+DEF_RET1_ARG3 (v8si)
+DEF_RET1_ARG3 (v16si)
+DEF_RET1_ARG3 (v32si)
+DEF_RET1_ARG3 (v64si)
+DEF_RET1_ARG3 (v128si)
+DEF_RET1_ARG3 (v256si)
+DEF_RET1_ARG3 (v512si)
+DEF_RET1_ARG3 (v1024si)
+
+DEF_RET1_ARG4 (v1si)
+DEF_RET1_ARG4 (v2si)
+DEF_RET1_ARG4 (v4si)
+DEF_RET1_ARG4 (v8si)
+DEF_RET1_ARG4 (v16si)
+DEF_RET1_ARG4 (v32si)
+DEF_RET1_ARG4 (v64si)
+DEF_RET1_ARG4 (v128si)
+DEF_RET1_ARG4 (v256si)
+DEF_RET1_ARG4 (v512si)
+DEF_RET1_ARG4 (v1024si)
+
+DEF_RET1_ARG5 (v1si)
+DEF_RET1_ARG5 (v2si)
+DEF_RET1_ARG5 (v4si)
+DEF_RET1_ARG5 (v8si)
+DEF_RET1_ARG5 (v16si)
+DEF_RET1_ARG5 (v32si)
+DEF_RET1_ARG5 (v64si)
+DEF_RET1_ARG5 (v128si)
+DEF_RET1_ARG5 (v256si)
+DEF_RET1_ARG5 (v512si)
+DEF_RET1_ARG5 (v1024si)
+
+DEF_RET1_ARG6 (v1si)
+DEF_RET1_ARG6 (v2si)
+DEF_RET1_ARG6 (v4si)
+DEF_RET1_ARG6 (v8si)
+DEF_RET1_ARG6 (v16si)
+DEF_RET1_ARG6 (v32si)
+DEF_RET1_ARG6 (v64si)
+DEF_RET1_ARG6 (v128si)
+DEF_RET1_ARG6 (v256si)
+DEF_RET1_ARG6 (v512si)
+DEF_RET1_ARG6 (v1024si)
+
+DEF_RET1_ARG7 (v1si)
+DEF_RET1_ARG7 (v2si)
+DEF_RET1_ARG7 (v4si)
+DEF_RET1_ARG7 (v8si)
+DEF_RET1_ARG7 (v16si)
+DEF_RET1_ARG7 (v32si)
+DEF_RET1_ARG7 (v64si)
+DEF_RET1_ARG7 (v128si)
+DEF_RET1_ARG7 (v256si)
+DEF_RET1_ARG7 (v512si)
+DEF_RET1_ARG7 (v1024si)
+
+DEF_RET1_ARG8 (v1si)
+DEF_RET1_ARG8 (v2si)
+DEF_RET1_ARG8 (v4si)
+DEF_RET1_ARG8 (v8si)
+DEF_RET1_ARG8 (v16si)
+DEF_RET1_ARG8 (v32si)
+DEF_RET1_ARG8 (v64si)
+DEF_RET1_ARG8 (v128si)
+DEF_RET1_ARG8 (v256si)
+DEF_RET1_ARG8 (v512si)
+DEF_RET1_ARG8 (v1024si)
+
+DEF_RET1_ARG9 (v1si)
+DEF_RET1_ARG9 (v2si)
+DEF_RET1_ARG9 (v4si)
+DEF_RET1_ARG9 (v8si)
+DEF_RET1_ARG9 (v16si)
+DEF_RET1_ARG9 (v32si)
+DEF_RET1_ARG9 (v64si)
+DEF_RET1_ARG9 (v128si)
+DEF_RET1_ARG9 (v256si)
+DEF_RET1_ARG9 (v512si)
+DEF_RET1_ARG9 (v1024si)
+
+/* { dg-final { scan-assembler-times {li\s+a[0-1],\s*0} 7 } } */
+/* { dg-final { scan-assembler-times {lw\s+a0,\s*[0-9]+\(sp\)} 8 } } */
+/* { dg-final { scan-assembler-times {ld\s+a[0-1],\s*[0-9]+\(sp\)} 31 } } */
+/* { dg-final { scan-assembler-times {sw\s+a[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sd\s+a[0-7],\s*[0-9]+\(sp\)} 103 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-4.c
new file mode 100644
index 00000000000..8c3f6ba98e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-4.c
@@ -0,0 +1,118 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b --param riscv-autovec-preference=scalable -mabi=lp64d -O3" } */
+
+#include "def.h"
+
+DEF_RET1_ARG0 (v1di)
+DEF_RET1_ARG0 (v2di)
+DEF_RET1_ARG0 (v4di)
+DEF_RET1_ARG0 (v8di)
+DEF_RET1_ARG0 (v16di)
+DEF_RET1_ARG0 (v32di)
+DEF_RET1_ARG0 (v64di)
+DEF_RET1_ARG0 (v128di)
+DEF_RET1_ARG0 (v256di)
+DEF_RET1_ARG0 (v512di)
+
+DEF_RET1_ARG1 (v1di)
+DEF_RET1_ARG1 (v2di)
+DEF_RET1_ARG1 (v4di)
+DEF_RET1_ARG1 (v8di)
+DEF_RET1_ARG1 (v16di)
+DEF_RET1_ARG1 (v32di)
+DEF_RET1_ARG1 (v64di)
+DEF_RET1_ARG1 (v128di)
+DEF_RET1_ARG1 (v256di)
+DEF_RET1_ARG1 (v512di)
+
+DEF_RET1_ARG2 (v1di)
+DEF_RET1_ARG2 (v2di)
+DEF_RET1_ARG2 (v4di)
+DEF_RET1_ARG2 (v8di)
+DEF_RET1_ARG2 (v16di)
+DEF_RET1_ARG2 (v32di)
+DEF_RET1_ARG2 (v64di)
+DEF_RET1_ARG2 (v128di)
+DEF_RET1_ARG2 (v256di)
+DEF_RET1_ARG2 (v512di)
+
+DEF_RET1_ARG3 (v1di)
+DEF_RET1_ARG3 (v2di)
+DEF_RET1_ARG3 (v4di)
+DEF_RET1_ARG3 (v8di)
+DEF_RET1_ARG3 (v16di)
+DEF_RET1_ARG3 (v32di)
+DEF_RET1_ARG3 (v64di)
+DEF_RET1_ARG3 (v128di)
+DEF_RET1_ARG3 (v256di)
+DEF_RET1_ARG3 (v512di)
+
+DEF_RET1_ARG4 (v1di)
+DEF_RET1_ARG4 (v2di)
+DEF_RET1_ARG4 (v4di)
+DEF_RET1_ARG4 (v8di)
+DEF_RET1_ARG4 (v16di)
+DEF_RET1_ARG4 (v32di)
+DEF_RET1_ARG4 (v64di)
+DEF_RET1_ARG4 (v128di)
+DEF_RET1_ARG4 (v256di)
+DEF_RET1_ARG4 (v512di)
+
+DEF_RET1_ARG5 (v1di)
+DEF_RET1_ARG5 (v2di)
+DEF_RET1_ARG5 (v4di)
+DEF_RET1_ARG5 (v8di)
+DEF_RET1_ARG5 (v16di)
+DEF_RET1_ARG5 (v32di)
+DEF_RET1_ARG5 (v64di)
+DEF_RET1_ARG5 (v128di)
+DEF_RET1_ARG5 (v256di)
+DEF_RET1_ARG5 (v512di)
+
+DEF_RET1_ARG6 (v1di)
+DEF_RET1_ARG6 (v2di)
+DEF_RET1_ARG6 (v4di)
+DEF_RET1_ARG6 (v8di)
+DEF_RET1_ARG6 (v16di)
+DEF_RET1_ARG6 (v32di)
+DEF_RET1_ARG6 (v64di)
+DEF_RET1_ARG6 (v128di)
+DEF_RET1_ARG6 (v256di)
+DEF_RET1_ARG6 (v512di)
+
+DEF_RET1_ARG7 (v1di)
+DEF_RET1_ARG7 (v2di)
+DEF_RET1_ARG7 (v4di)
+DEF_RET1_ARG7 (v8di)
+DEF_RET1_ARG7 (v16di)
+DEF_RET1_ARG7 (v32di)
+DEF_RET1_ARG7 (v64di)
+DEF_RET1_ARG7 (v128di)
+DEF_RET1_ARG7 (v256di)
+DEF_RET1_ARG7 (v512di)
+
+DEF_RET1_ARG8 (v1di)
+DEF_RET1_ARG8 (v2di)
+DEF_RET1_ARG8 (v4di)
+DEF_RET1_ARG8 (v8di)
+DEF_RET1_ARG8 (v16di)
+DEF_RET1_ARG8 (v32di)
+DEF_RET1_ARG8 (v64di)
+DEF_RET1_ARG8 (v128di)
+DEF_RET1_ARG8 (v256di)
+DEF_RET1_ARG8 (v512di)
+
+DEF_RET1_ARG9 (v1di)
+DEF_RET1_ARG9 (v2di)
+DEF_RET1_ARG9 (v4di)
+DEF_RET1_ARG9 (v8di)
+DEF_RET1_ARG9 (v16di)
+DEF_RET1_ARG9 (v32di)
+DEF_RET1_ARG9 (v64di)
+DEF_RET1_ARG9 (v128di)
+DEF_RET1_ARG9 (v256di)
+DEF_RET1_ARG9 (v512di)
+
+/* { dg-final { scan-assembler-times {li\s+a[0-1],\s*0} 6 } } */
+/* { dg-final { scan-assembler-times {ld\s+a[0-1],\s*[0-9]+\(sp\)} 29 } } */
+/* { dg-final { scan-assembler-times {sd\s+a[0-7],\s*[0-9]+\(sp\)} 103 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-5.c
new file mode 100644
index 00000000000..cfa4f5db372
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-5.c
@@ -0,0 +1,141 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b --param riscv-autovec-preference=scalable -mabi=lp64d -O3" } */
+
+#include "def.h"
+
+DEF_RET1_ARG0 (v1hf)
+DEF_RET1_ARG0 (v2hf)
+DEF_RET1_ARG0 (v4hf)
+DEF_RET1_ARG0 (v8hf)
+DEF_RET1_ARG0 (v16hf)
+DEF_RET1_ARG0 (v32hf)
+DEF_RET1_ARG0 (v64hf)
+DEF_RET1_ARG0 (v128hf)
+DEF_RET1_ARG0 (v256hf)
+DEF_RET1_ARG0 (v512hf)
+DEF_RET1_ARG0 (v1024hf)
+DEF_RET1_ARG0 (v2048hf)
+
+DEF_RET1_ARG1 (v1hf)
+DEF_RET1_ARG1 (v2hf)
+DEF_RET1_ARG1 (v4hf)
+DEF_RET1_ARG1 (v8hf)
+DEF_RET1_ARG1 (v16hf)
+DEF_RET1_ARG1 (v32hf)
+DEF_RET1_ARG1 (v64hf)
+DEF_RET1_ARG1 (v128hf)
+DEF_RET1_ARG1 (v256hf)
+DEF_RET1_ARG1 (v512hf)
+DEF_RET1_ARG1 (v1024hf)
+DEF_RET1_ARG1 (v2048hf)
+
+DEF_RET1_ARG2 (v1hf)
+DEF_RET1_ARG2 (v2hf)
+DEF_RET1_ARG2 (v4hf)
+DEF_RET1_ARG2 (v8hf)
+DEF_RET1_ARG2 (v16hf)
+DEF_RET1_ARG2 (v32hf)
+DEF_RET1_ARG2 (v64hf)
+DEF_RET1_ARG2 (v128hf)
+DEF_RET1_ARG2 (v256hf)
+DEF_RET1_ARG2 (v512hf)
+DEF_RET1_ARG2 (v1024hf)
+DEF_RET1_ARG2 (v2048hf)
+
+DEF_RET1_ARG3 (v1hf)
+DEF_RET1_ARG3 (v2hf)
+DEF_RET1_ARG3 (v4hf)
+DEF_RET1_ARG3 (v8hf)
+DEF_RET1_ARG3 (v16hf)
+DEF_RET1_ARG3 (v32hf)
+DEF_RET1_ARG3 (v64hf)
+DEF_RET1_ARG3 (v128hf)
+DEF_RET1_ARG3 (v256hf)
+DEF_RET1_ARG3 (v512hf)
+DEF_RET1_ARG3 (v1024hf)
+DEF_RET1_ARG3 (v2048hf)
+
+DEF_RET1_ARG4 (v1hf)
+DEF_RET1_ARG4 (v2hf)
+DEF_RET1_ARG4 (v4hf)
+DEF_RET1_ARG4 (v8hf)
+DEF_RET1_ARG4 (v16hf)
+DEF_RET1_ARG4 (v32hf)
+DEF_RET1_ARG4 (v64hf)
+DEF_RET1_ARG4 (v128hf)
+DEF_RET1_ARG4 (v256hf)
+DEF_RET1_ARG4 (v512hf)
+DEF_RET1_ARG4 (v1024hf)
+DEF_RET1_ARG4 (v2048hf)
+
+DEF_RET1_ARG5 (v1hf)
+DEF_RET1_ARG5 (v2hf)
+DEF_RET1_ARG5 (v4hf)
+DEF_RET1_ARG5 (v8hf)
+DEF_RET1_ARG5 (v16hf)
+DEF_RET1_ARG5 (v32hf)
+DEF_RET1_ARG5 (v64hf)
+DEF_RET1_ARG5 (v128hf)
+DEF_RET1_ARG5 (v256hf)
+DEF_RET1_ARG5 (v512hf)
+DEF_RET1_ARG5 (v1024hf)
+DEF_RET1_ARG5 (v2048hf)
+
+DEF_RET1_ARG6 (v1hf)
+DEF_RET1_ARG6 (v2hf)
+DEF_RET1_ARG6 (v4hf)
+DEF_RET1_ARG6 (v8hf)
+DEF_RET1_ARG6 (v16hf)
+DEF_RET1_ARG6 (v32hf)
+DEF_RET1_ARG6 (v64hf)
+DEF_RET1_ARG6 (v128hf)
+DEF_RET1_ARG6 (v256hf)
+DEF_RET1_ARG6 (v512hf)
+DEF_RET1_ARG6 (v1024hf)
+DEF_RET1_ARG6 (v2048hf)
+
+DEF_RET1_ARG7 (v1hf)
+DEF_RET1_ARG7 (v2hf)
+DEF_RET1_ARG7 (v4hf)
+DEF_RET1_ARG7 (v8hf)
+DEF_RET1_ARG7 (v16hf)
+DEF_RET1_ARG7 (v32hf)
+DEF_RET1_ARG7 (v64hf)
+DEF_RET1_ARG7 (v128hf)
+DEF_RET1_ARG7 (v256hf)
+DEF_RET1_ARG7 (v512hf)
+DEF_RET1_ARG7 (v1024hf)
+DEF_RET1_ARG7 (v2048hf)
+
+DEF_RET1_ARG8 (v1hf)
+DEF_RET1_ARG8 (v2hf)
+DEF_RET1_ARG8 (v4hf)
+DEF_RET1_ARG8 (v8hf)
+DEF_RET1_ARG8 (v16hf)
+DEF_RET1_ARG8 (v32hf)
+DEF_RET1_ARG8 (v64hf)
+DEF_RET1_ARG8 (v128hf)
+DEF_RET1_ARG8 (v256hf)
+DEF_RET1_ARG8 (v512hf)
+DEF_RET1_ARG8 (v1024hf)
+DEF_RET1_ARG8 (v2048hf)
+
+DEF_RET1_ARG9 (v1hf)
+DEF_RET1_ARG9 (v2hf)
+DEF_RET1_ARG9 (v4hf)
+DEF_RET1_ARG9 (v8hf)
+DEF_RET1_ARG9 (v16hf)
+DEF_RET1_ARG9 (v32hf)
+DEF_RET1_ARG9 (v64hf)
+DEF_RET1_ARG9 (v128hf)
+DEF_RET1_ARG9 (v256hf)
+DEF_RET1_ARG9 (v512hf)
+DEF_RET1_ARG9 (v1024hf)
+DEF_RET1_ARG9 (v2048hf)
+
+/* { dg-final { scan-assembler-times {li\s+a[0-1],\s*0} 6 } } */
+/* { dg-final { scan-assembler-times {flh\s+fa[0-1],\s*[0-9]+\(sp\)} 9 } } */
+/* { dg-final { scan-assembler-times {flw\s+fa[0-1],\s*[0-9]+\(sp\)} 9 } } */
+/* { dg-final { scan-assembler-times {fsh\s+fa[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {fsw\s+fa[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sd\s+a[0-7],\s*[0-9]+\(sp\)} 103 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-6.c
new file mode 100644
index 00000000000..45a9e2debe8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-6.c
@@ -0,0 +1,129 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b --param riscv-autovec-preference=scalable -mabi=lp64d -O3" } */
+
+#include "def.h"
+
+DEF_RET1_ARG0 (v1sf)
+DEF_RET1_ARG0 (v2sf)
+DEF_RET1_ARG0 (v4sf)
+DEF_RET1_ARG0 (v8sf)
+DEF_RET1_ARG0 (v16sf)
+DEF_RET1_ARG0 (v32sf)
+DEF_RET1_ARG0 (v64sf)
+DEF_RET1_ARG0 (v128sf)
+DEF_RET1_ARG0 (v256sf)
+DEF_RET1_ARG0 (v512sf)
+DEF_RET1_ARG0 (v1024sf)
+
+DEF_RET1_ARG1 (v1sf)
+DEF_RET1_ARG1 (v2sf)
+DEF_RET1_ARG1 (v4sf)
+DEF_RET1_ARG1 (v8sf)
+DEF_RET1_ARG1 (v16sf)
+DEF_RET1_ARG1 (v32sf)
+DEF_RET1_ARG1 (v64sf)
+DEF_RET1_ARG1 (v128sf)
+DEF_RET1_ARG1 (v256sf)
+DEF_RET1_ARG1 (v512sf)
+DEF_RET1_ARG1 (v1024sf)
+
+DEF_RET1_ARG2 (v1sf)
+DEF_RET1_ARG2 (v2sf)
+DEF_RET1_ARG2 (v4sf)
+DEF_RET1_ARG2 (v8sf)
+DEF_RET1_ARG2 (v16sf)
+DEF_RET1_ARG2 (v32sf)
+DEF_RET1_ARG2 (v64sf)
+DEF_RET1_ARG2 (v128sf)
+DEF_RET1_ARG2 (v256sf)
+DEF_RET1_ARG2 (v512sf)
+DEF_RET1_ARG2 (v1024sf)
+
+DEF_RET1_ARG3 (v1sf)
+DEF_RET1_ARG3 (v2sf)
+DEF_RET1_ARG3 (v4sf)
+DEF_RET1_ARG3 (v8sf)
+DEF_RET1_ARG3 (v16sf)
+DEF_RET1_ARG3 (v32sf)
+DEF_RET1_ARG3 (v64sf)
+DEF_RET1_ARG3 (v128sf)
+DEF_RET1_ARG3 (v256sf)
+DEF_RET1_ARG3 (v512sf)
+DEF_RET1_ARG3 (v1024sf)
+
+DEF_RET1_ARG4 (v1sf)
+DEF_RET1_ARG4 (v2sf)
+DEF_RET1_ARG4 (v4sf)
+DEF_RET1_ARG4 (v8sf)
+DEF_RET1_ARG4 (v16sf)
+DEF_RET1_ARG4 (v32sf)
+DEF_RET1_ARG4 (v64sf)
+DEF_RET1_ARG4 (v128sf)
+DEF_RET1_ARG4 (v256sf)
+DEF_RET1_ARG4 (v512sf)
+DEF_RET1_ARG4 (v1024sf)
+
+DEF_RET1_ARG5 (v1sf)
+DEF_RET1_ARG5 (v2sf)
+DEF_RET1_ARG5 (v4sf)
+DEF_RET1_ARG5 (v8sf)
+DEF_RET1_ARG5 (v16sf)
+DEF_RET1_ARG5 (v32sf)
+DEF_RET1_ARG5 (v64sf)
+DEF_RET1_ARG5 (v128sf)
+DEF_RET1_ARG5 (v256sf)
+DEF_RET1_ARG5 (v512sf)
+DEF_RET1_ARG5 (v1024sf)
+
+DEF_RET1_ARG6 (v1sf)
+DEF_RET1_ARG6 (v2sf)
+DEF_RET1_ARG6 (v4sf)
+DEF_RET1_ARG6 (v8sf)
+DEF_RET1_ARG6 (v16sf)
+DEF_RET1_ARG6 (v32sf)
+DEF_RET1_ARG6 (v64sf)
+DEF_RET1_ARG6 (v128sf)
+DEF_RET1_ARG6 (v256sf)
+DEF_RET1_ARG6 (v512sf)
+DEF_RET1_ARG6 (v1024sf)
+
+DEF_RET1_ARG7 (v1sf)
+DEF_RET1_ARG7 (v2sf)
+DEF_RET1_ARG7 (v4sf)
+DEF_RET1_ARG7 (v8sf)
+DEF_RET1_ARG7 (v16sf)
+DEF_RET1_ARG7 (v32sf)
+DEF_RET1_ARG7 (v64sf)
+DEF_RET1_ARG7 (v128sf)
+DEF_RET1_ARG7 (v256sf)
+DEF_RET1_ARG7 (v512sf)
+DEF_RET1_ARG7 (v1024sf)
+
+DEF_RET1_ARG8 (v1sf)
+DEF_RET1_ARG8 (v2sf)
+DEF_RET1_ARG8 (v4sf)
+DEF_RET1_ARG8 (v8sf)
+DEF_RET1_ARG8 (v16sf)
+DEF_RET1_ARG8 (v32sf)
+DEF_RET1_ARG8 (v64sf)
+DEF_RET1_ARG8 (v128sf)
+DEF_RET1_ARG8 (v256sf)
+DEF_RET1_ARG8 (v512sf)
+DEF_RET1_ARG8 (v1024sf)
+
+DEF_RET1_ARG9 (v1sf)
+DEF_RET1_ARG9 (v2sf)
+DEF_RET1_ARG9 (v4sf)
+DEF_RET1_ARG9 (v8sf)
+DEF_RET1_ARG9 (v16sf)
+DEF_RET1_ARG9 (v32sf)
+DEF_RET1_ARG9 (v64sf)
+DEF_RET1_ARG9 (v128sf)
+DEF_RET1_ARG9 (v256sf)
+DEF_RET1_ARG9 (v512sf)
+DEF_RET1_ARG9 (v1024sf)
+
+/* { dg-final { scan-assembler-times {li\s+a[0-1],\s*0} 5 } } */
+/* { dg-final { scan-assembler-times {flw\s+fa[0-1],\s*[0-9]+\(sp\)} 9 } } */
+/* { dg-final { scan-assembler-times {fsw\s+fa[0-7],\s*[0-9]+\(sp\)} 43 } } */
+/* { dg-final { scan-assembler-times {sd\s+a[0-7],\s*[0-9]+\(sp\)} 60 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-7.c
new file mode 100644
index 00000000000..a607786afea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-7.c
@@ -0,0 +1,120 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b --param riscv-autovec-preference=scalable -mabi=lp64d -O3" } */
+
+#include "def.h"
+
+DEF_RET1_ARG0 (v1df)
+DEF_RET1_ARG0 (v2df)
+DEF_RET1_ARG0 (v4df)
+DEF_RET1_ARG0 (v8df)
+DEF_RET1_ARG0 (v16df)
+DEF_RET1_ARG0 (v32df)
+DEF_RET1_ARG0 (v64df)
+DEF_RET1_ARG0 (v128df)
+DEF_RET1_ARG0 (v256df)
+DEF_RET1_ARG0 (v512df)
+
+DEF_RET1_ARG1 (v1df)
+DEF_RET1_ARG1 (v2df)
+DEF_RET1_ARG1 (v4df)
+DEF_RET1_ARG1 (v8df)
+DEF_RET1_ARG1 (v16df)
+DEF_RET1_ARG1 (v32df)
+DEF_RET1_ARG1 (v64df)
+DEF_RET1_ARG1 (v128df)
+DEF_RET1_ARG1 (v256df)
+DEF_RET1_ARG1 (v512df)
+
+DEF_RET1_ARG2 (v1df)
+DEF_RET1_ARG2 (v2df)
+DEF_RET1_ARG2 (v4df)
+DEF_RET1_ARG2 (v8df)
+DEF_RET1_ARG2 (v16df)
+DEF_RET1_ARG2 (v32df)
+DEF_RET1_ARG2 (v64df)
+DEF_RET1_ARG2 (v128df)
+DEF_RET1_ARG2 (v256df)
+DEF_RET1_ARG2 (v512df)
+
+DEF_RET1_ARG3 (v1df)
+DEF_RET1_ARG3 (v2df)
+DEF_RET1_ARG3 (v4df)
+DEF_RET1_ARG3 (v8df)
+DEF_RET1_ARG3 (v16df)
+DEF_RET1_ARG3 (v32df)
+DEF_RET1_ARG3 (v64df)
+DEF_RET1_ARG3 (v128df)
+DEF_RET1_ARG3 (v256df)
+DEF_RET1_ARG3 (v512df)
+
+DEF_RET1_ARG4 (v1df)
+DEF_RET1_ARG4 (v2df)
+DEF_RET1_ARG4 (v4df)
+DEF_RET1_ARG4 (v8df)
+DEF_RET1_ARG4 (v16df)
+DEF_RET1_ARG4 (v32df)
+DEF_RET1_ARG4 (v64df)
+DEF_RET1_ARG4 (v128df)
+DEF_RET1_ARG4 (v256df)
+DEF_RET1_ARG4 (v512df)
+
+DEF_RET1_ARG5 (v1df)
+DEF_RET1_ARG5 (v2df)
+DEF_RET1_ARG5 (v4df)
+DEF_RET1_ARG5 (v8df)
+DEF_RET1_ARG5 (v16df)
+DEF_RET1_ARG5 (v32df)
+DEF_RET1_ARG5 (v64df)
+DEF_RET1_ARG5 (v128df)
+DEF_RET1_ARG5 (v256df)
+DEF_RET1_ARG5 (v512df)
+
+DEF_RET1_ARG6 (v1df)
+DEF_RET1_ARG6 (v2df)
+DEF_RET1_ARG6 (v4df)
+DEF_RET1_ARG6 (v8df)
+DEF_RET1_ARG6 (v16df)
+DEF_RET1_ARG6 (v32df)
+DEF_RET1_ARG6 (v64df)
+DEF_RET1_ARG6 (v128df)
+DEF_RET1_ARG6 (v256df)
+DEF_RET1_ARG6 (v512df)
+
+DEF_RET1_ARG7 (v1df)
+DEF_RET1_ARG7 (v2df)
+DEF_RET1_ARG7 (v4df)
+DEF_RET1_ARG7 (v8df)
+DEF_RET1_ARG7 (v16df)
+DEF_RET1_ARG7 (v32df)
+DEF_RET1_ARG7 (v64df)
+DEF_RET1_ARG7 (v128df)
+DEF_RET1_ARG7 (v256df)
+DEF_RET1_ARG7 (v512df)
+
+DEF_RET1_ARG8 (v1df)
+DEF_RET1_ARG8 (v2df)
+DEF_RET1_ARG8 (v4df)
+DEF_RET1_ARG8 (v8df)
+DEF_RET1_ARG8 (v16df)
+DEF_RET1_ARG8 (v32df)
+DEF_RET1_ARG8 (v64df)
+DEF_RET1_ARG8 (v128df)
+DEF_RET1_ARG8 (v256df)
+DEF_RET1_ARG8 (v512df)
+
+DEF_RET1_ARG9 (v1df)
+DEF_RET1_ARG9 (v2df)
+DEF_RET1_ARG9 (v4df)
+DEF_RET1_ARG9 (v8df)
+DEF_RET1_ARG9 (v16df)
+DEF_RET1_ARG9 (v32df)
+DEF_RET1_ARG9 (v64df)
+DEF_RET1_ARG9 (v128df)
+DEF_RET1_ARG9 (v256df)
+DEF_RET1_ARG9 (v512df)
+
+/* { dg-final { scan-assembler-times {li\s+a[0-1],\s*0} 5 } } */
+/* { dg-final { scan-assembler-times {ld\s+a[0-1],\s*[0-9]+\(sp\)} 21 } } */
+/* { dg-final { scan-assembler-times {fld\s+fa[0-1],\s*[0-9]+\(sp\)} 9 } } */
+/* { dg-final { scan-assembler-times {sd\s+a[0-7],\s*[0-9]+\(sp\)} 60 } } */
+/* { dg-final { scan-assembler-times {fsd\s+fa[0-7],\s*[0-9]+\(sp\)} 43 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-8.c
new file mode 100644
index 00000000000..ed66a2cb9eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-8.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d --param riscv-autovec-preference=scalable -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "def.h"
+
+/*
+** v8qi_RET1_ARG0:
+** li\s+a0,\s*0
+** ret
+*/
+DEF_RET1_ARG0 (v8qi)
+
+/*
+** v4hi_RET1_ARG1:
+** ret
+*/
+DEF_RET1_ARG1 (v4hi)
+
+/*
+** v2si_RET1_ARG2:
+** addi\s+sp,\s*sp,\s*-16
+** sd\s+a0,\s*0\(sp\)
+** sd\s+a1,\s*8\(sp\)
+** ...
+** ld\s+a0,\s*0\(sp\)
+** addi\s+sp,\s*sp,\s*16
+** jr\s+ra
+*/
+DEF_RET1_ARG2 (v2si)
+
+/*
+** v1di_RET1_ARG3:
+** addi\s+sp,\s*sp,\s*-32
+** sd\s+a0,\s*8\(sp\)
+** sd\s+a1,\s*16\(sp\)
+** sd\s+a2,\s*24\(sp\)
+** ...
+** ld\s+a0,\s*8\(sp\)
+** addi\s+sp,\s*sp,\s*32
+** jr\s+ra
+*/
+DEF_RET1_ARG3 (v1di)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-9.c
new file mode 100644
index 00000000000..dd8e709ee59
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-9.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d --param riscv-autovec-preference=scalable -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "def.h"
+
+/*
+** v4hf_RET1_ARG1:
+** ret
+*/
+DEF_RET1_ARG1 (v4hf)
+
+/*
+** v2sf_RET1_ARG2:
+** addi\s+sp,\s*sp,\s*-16
+** fsd\s+fa0,\s*0\(sp\)
+** fsd\s+fa1,\s*8\(sp\)
+** ...
+** fld\s+fa0,\s*0\(sp\)
+** addi\s+sp,\s*sp,\s*16
+** jr\s+ra
+*/
+DEF_RET1_ARG2 (v2sf)
+
+/*
+** v4sf_RET1_ARG2:
+** addi\s+sp,\s*sp,\s*-32
+** sd\s+a0,\s*0\(sp\)
+** sd\s+a1,\s*8\(sp\)
+** sd\s+a2,\s*16\(sp\)
+** sd\s+a3,\s*24\(sp\)
+** ...
+** ld\s+a0,\s*0\(sp\)
+** ld\s+a1,\s*8\(sp\)
+** addi\s+sp,\s*sp,\s*32
+** jr\s+ra
+*/
+DEF_RET1_ARG2 (v4sf)
+
+/*
+** v1df_RET1_ARG3:
+** addi\s+sp,\s*sp,\s*-32
+** fsd\s+fa0,\s*8\(sp\)
+** fsd\s+fa1,\s*16\(sp\)
+** fsd\s+fa2,\s*24\(sp\)
+** ...
+** fld\s+fa0,\s*8\(sp\)
+** addi\s+sp,\s*sp,\s*32
+** jr\s+ra
+*/
+DEF_RET1_ARG3 (v1df)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-1.c
new file mode 100644
index 00000000000..d8aa5c51cac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-1.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+typedef char v16qi __attribute__ ((vector_size (16)));
+
+v16qi
+add (v16qi a1, v16qi a2, v16qi a3, v16qi a4, v16qi a5, v16qi a6, v16qi a7,
+     v16qi a8, v16qi a9)
+{
+  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+int
+main ()
+{
+  v16qi a1 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a2 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a3 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a4 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a5 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a6 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a7 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a8 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi a9 = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v16qi expected = {
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+  };
+  v16qi result = add (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  unsigned i;
+
+  for (i = 0; i < 16; i++)
+    if (result[i] != expected[i])
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-2.c
new file mode 100644
index 00000000000..57376a3924c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-2.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+typedef short v8hi __attribute__ ((vector_size (16)));
+
+v8hi
+add (v8hi a1, v8hi a2, v8hi a3, v8hi a4, v8hi a5, v8hi a6, v8hi a7,
+     v8hi a8, v8hi a9)
+{
+  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+int
+main ()
+{
+  v8hi a1 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a2 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a3 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a4 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a5 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a6 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a7 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a8 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi a9 = {
+    1, 1, 1, 1, 1, 1, 1, 1,
+  };
+  v8hi expected = {
+    9, 9, 9, 9, 9, 9, 9, 9,
+  };
+  v8hi result = add (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  unsigned i;
+
+  for (i = 0; i < 8; i++)
+    if (result[i] != expected[i])
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-3.c
new file mode 100644
index 00000000000..b37cd5669d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-3.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+v4si
+add (v4si a1, v4si a2, v4si a3, v4si a4, v4si a5, v4si a6, v4si a7,
+     v4si a8, v4si a9)
+{
+  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+int
+main ()
+{
+  v4si a1 = {
+    1, 1, 1, 1,
+  };
+  v4si a2 = {
+    1, 1, 1, 1,
+  };
+  v4si a3 = {
+    1, 1, 1, 1,
+  };
+  v4si a4 = {
+    1, 1, 1, 1,
+  };
+  v4si a5 = {
+    1, 1, 1, 1,
+  };
+  v4si a6 = {
+    1, 1, 1, 1,
+  };
+  v4si a7 = {
+    1, 1, 1, 1,
+  };
+  v4si a8 = {
+    1, 1, 1, 1,
+  };
+  v4si a9 = {
+    1, 1, 1, 1,
+  };
+  v4si expected = {
+    9, 9, 9, 9,
+  };
+  v4si result = add (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  unsigned i;
+
+  for (i = 0; i < 4; i++)
+    if (result[i] != expected[i])
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-4.c
new file mode 100644
index 00000000000..0788447b501
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-4.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+v2di
+add (v2di a1, v2di a2, v2di a3, v2di a4, v2di a5, v2di a6, v2di a7,
+     v2di a8, v2di a9)
+{
+  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+int
+main ()
+{
+  v2di a1 = {
+    1, 1,
+  };
+  v2di a2 = {
+    1, 1,
+  };
+  v2di a3 = {
+    1, 1,
+  };
+  v2di a4 = {
+    1, 1,
+  };
+  v2di a5 = {
+    1, 1,
+  };
+  v2di a6 = {
+    1, 1,
+  };
+  v2di a7 = {
+    1, 1,
+  };
+  v2di a8 = {
+    1, 1,
+  };
+  v2di a9 = {
+    1, 1,
+  };
+  v2di expected = {
+    9, 9,
+  };
+  v2di result = add (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  unsigned i;
+
+  for (i = 0; i < 2; i++)
+    if (result[i] != expected[i])
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-5.c
new file mode 100644
index 00000000000..ec8658d6a02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-5.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+typedef float v4sf __attribute__ ((vector_size (16)));
+
+v4sf
+add (v4sf a1, v4sf a2, v4sf a3, v4sf a4, v4sf a5, v4sf a6, v4sf a7,
+     v4sf a8, v4sf a9)
+{
+  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+int
+main ()
+{
+  v4sf a1 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a2 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a3 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a4 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a5 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a6 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a7 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a8 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf a9 = {
+    1.0, 1.0, 1.0, 1.0,
+  };
+  v4sf expected = {
+    9.0, 9.0, 9.0, 9.0,
+  };
+  v4sf result = add (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  unsigned i;
+
+  for (i = 0; i < 4; i++)
+    if (result[i] != expected[i])
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-6.c
new file mode 100644
index 00000000000..bbb53a1a4af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/calling-convention-run-6.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable" } */
+
+typedef long long v2df __attribute__ ((vector_size (16)));
+
+v2df
+add (v2df a1, v2df a2, v2df a3, v2df a4, v2df a5, v2df a6, v2df a7,
+     v2df a8, v2df a9)
+{
+  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+int
+main ()
+{
+  v2df a1 = {
+    1.0, 1.0,
+  };
+  v2df a2 = {
+    1.0, 1.0,
+  };
+  v2df a3 = {
+    1.0, 1.0,
+  };
+  v2df a4 = {
+    1.0, 1.0,
+  };
+  v2df a5 = {
+    1.0, 1.0,
+  };
+  v2df a6 = {
+    1.0, 1.0,
+  };
+  v2df a7 = {
+    1.0, 1.0,
+  };
+  v2df a8 = {
+    1.0, 1.0,
+  };
+  v2df a9 = {
+    1.0, 1.0,
+  };
+  v2df expected = {
+    9.0, 9.0,
+  };
+  v2df result = add (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  unsigned i;
+
+  for (i = 0; i < 2; i++)
+    if (result[i] != expected[i])
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
index cb7a1c97ded..ef55c4d7ecf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
@@ -860,3 +860,77 @@ typedef double v512df __attribute__ ((vector_size (4096)));
     TYPE1 v = {__VA_ARGS__};                                                   \
     *(TYPE1 *) out = v;                                                        \
   }
+
+#define DEF_RET1_ARG0(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG0 ()                                                          \
+  {                                                                            \
+    TYPE r = {};                                                               \
+    return r;                                                                  \
+  }
+
+#define DEF_RET1_ARG1(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG1 (TYPE a1)                                                   \
+  {                                                                            \
+    return a1;                                                                 \
+  }
+
+#define DEF_RET1_ARG2(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG2 (TYPE a1, TYPE a2)                                          \
+  {                                                                            \
+    return a1 + a2;                                                            \
+  }
+
+#define DEF_RET1_ARG3(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG3 (TYPE a1, TYPE a2, TYPE a3)                                 \
+  {                                                                            \
+    return a1 + a2 + a3;                                                       \
+  }
+
+#define DEF_RET1_ARG4(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG4 (TYPE a1, TYPE a2, TYPE a3, TYPE a4)                        \
+  {                                                                            \
+    return a1 + a2 + a3 + a4;                                                  \
+  }
+
+#define DEF_RET1_ARG5(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG5 (TYPE a1, TYPE a2, TYPE a3, TYPE a4, TYPE a5)               \
+  {                                                                            \
+    return a1 + a2 + a3 + a4 + a5;                                             \
+  }
+
+#define DEF_RET1_ARG6(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG6 (TYPE a1, TYPE a2, TYPE a3, TYPE a4, TYPE a5, TYPE a6)      \
+  {                                                                            \
+    return a1 + a2 + a3 + a4 + a5 + a6;                                        \
+  }
+
+#define DEF_RET1_ARG7(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG7 (TYPE a1, TYPE a2, TYPE a3, TYPE a4, TYPE a5, TYPE a6,      \
+		    TYPE a7)                                                   \
+  {                                                                            \
+    return a1 + a2 + a3 + a4 + a5 + a6 + a7;                                   \
+  }
+
+#define DEF_RET1_ARG8(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG8 (TYPE a1, TYPE a2, TYPE a3, TYPE a4, TYPE a5, TYPE a6,      \
+		    TYPE a7, TYPE a8)                                          \
+  {                                                                            \
+    return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;                              \
+  }
+
+#define DEF_RET1_ARG9(TYPE)                                                    \
+  TYPE __attribute__((noinline))                                               \
+  TYPE##_RET1_ARG9 (TYPE a1, TYPE a2, TYPE a3, TYPE a4, TYPE a5, TYPE a6,      \
+		    TYPE a7, TYPE a8, TYPE a9)                                 \
+  {                                                                            \
+    return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;                         \
+  }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-01-30 13:49 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-24  3:16 [PATCH v1] RISC-V: Bugfix for vls integer mode calling convention pan2.li
2024-01-24  3:18 ` juzhe.zhong
2024-01-24  3:41   ` Li, Pan2
2024-01-24  3:43     ` juzhe.zhong
2024-01-29 13:22 ` Kito Cheng
2024-01-30  8:39   ` Li, Pan2
2024-01-30  8:37 ` [PATCH v2] RISC-V: Bugfix for vls mode aggregated in GPR " pan2.li
2024-01-30 12:54   ` Kito Cheng
2024-01-30 13:10     ` Li, Pan2
2024-01-30 13:49       ` Li, Pan2

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).