diff mbox series

[V2] RISC-V: Support MASK_LEN_{LOAD_LANES,STORE_LANES}

Message ID 20230816014519.3053770-1-juzhe.zhong@rivai.ai
State New
Headers show
Series [V2] RISC-V: Support MASK_LEN_{LOAD_LANES,STORE_LANES} | expand

Commit Message

juzhe.zhong@rivai.ai Aug. 16, 2023, 1:45 a.m. UTC
This patch allow us auto-vectorize this following case:

#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)                             \
  void __attribute__ ((noinline, noclone))                                     \
  NAME##_8 (OUTTYPE *__restrict dest, INTYPE *__restrict src,                  \
	    MASKTYPE *__restrict cond, intptr_t n)                             \
  {                                                                            \
    for (intptr_t i = 0; i < n; ++i)                                           \
      if (cond[i])                                                             \
	dest[i] = (src[i * 8] + src[i * 8 + 1] + src[i * 8 + 2]                \
		   + src[i * 8 + 3] + src[i * 8 + 4] + src[i * 8 + 5]          \
		   + src[i * 8 + 6] + src[i * 8 + 7]);                         \
  }

#define TEST2(NAME, OUTTYPE, INTYPE)                                           \
  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, int32_t)                               \

#define TEST1(NAME, OUTTYPE)                                                   \
  TEST2 (NAME##_i32, OUTTYPE, int32_t)                                         \

#define TEST(NAME)                                                             \
  TEST1 (NAME##_i32, int32_t)                                                  \

TEST (test)

ASM:

test_i32_i32_f32_8:
	ble	a3,zero,.L5
.L3:
	vsetvli	a4,a3,e8,mf4,ta,ma
	vle32.v	v0,0(a2)
	vsetvli	a5,zero,e32,m1,ta,ma
	vmsne.vi	v0,v0,0
	vsetvli	zero,a4,e32,m1,ta,ma
	vlseg8e32.v	v8,(a1),v0.t
	vsetvli	a5,zero,e32,m1,ta,ma
	slli	a6,a4,2
	vadd.vv	v1,v9,v8
	slli	a7,a4,5
	vadd.vv	v1,v1,v10
	sub	a3,a3,a4
	vadd.vv	v1,v1,v11
	vadd.vv	v1,v1,v12
	vadd.vv	v1,v1,v13
	vadd.vv	v1,v1,v14
	vadd.vv	v1,v1,v15
	vsetvli	zero,a4,e32,m1,ta,ma
	vse32.v	v1,0(a0),v0.t
	add	a2,a2,a6
	add	a1,a1,a7
	add	a0,a0,a6
	bne	a3,zero,.L3
.L5:
	ret

gcc/ChangeLog:

        * config/riscv/autovec.md (vec_mask_len_load_lanes<mode><vsingle>): New pattern.
        (vec_mask_len_store_lanes<mode><vsingle>): Ditto.
        * config/riscv/riscv-protos.h (expand_lanes_load_store): New function.
        * config/riscv/riscv-v.cc (get_mask_mode): Add tuple mask mode.
        (expand_lanes_load_store): New function.
        * config/riscv/vector-iterators.md: New iterator.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c: Adapt test.
        * gcc.target/riscv/rvv/autovec/partial/slp-1.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-16.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-17.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-18.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-19.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-2.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-3.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-4.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-5.c: Ditto.
        * gcc.target/riscv/rvv/autovec/partial/slp-6.c: Ditto.
        * gcc.target/riscv/rvv/rvv.exp: Add lanes tests.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c: New test.
        * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c: New test.

---
 gcc/config/riscv/autovec.md                   |  30 +++
 gcc/config/riscv/riscv-protos.h               |   1 +
 gcc/config/riscv/riscv-v.cc                   |  52 +++-
 gcc/config/riscv/vector-iterators.md          |  95 +++++++
 .../autovec/gather-scatter/strided_load-2.c   |   2 +-
 .../riscv/rvv/autovec/partial/slp-1.c         |   7 +-
 .../riscv/rvv/autovec/partial/slp-16.c        |   5 +-
 .../riscv/rvv/autovec/partial/slp-17.c        |   5 +-
 .../riscv/rvv/autovec/partial/slp-18.c        |   5 +-
 .../riscv/rvv/autovec/partial/slp-19.c        |   4 +-
 .../riscv/rvv/autovec/partial/slp-2.c         |   5 +-
 .../riscv/rvv/autovec/partial/slp-3.c         |   3 +-
 .../riscv/rvv/autovec/partial/slp-4.c         |   5 +-
 .../riscv/rvv/autovec/partial/slp-5.c         |   3 +-
 .../riscv/rvv/autovec/partial/slp-6.c         |   5 +-
 .../rvv/autovec/struct/mask_struct_load-1.c   |  42 ++++
 .../rvv/autovec/struct/mask_struct_load-2.c   |  44 ++++
 .../rvv/autovec/struct/mask_struct_load-3.c   |  45 ++++
 .../rvv/autovec/struct/mask_struct_load-4.c   |  43 ++++
 .../rvv/autovec/struct/mask_struct_load-5.c   |  43 ++++
 .../rvv/autovec/struct/mask_struct_load-6.c   |  44 ++++
 .../rvv/autovec/struct/mask_struct_load-7.c   |  44 ++++
 .../autovec/struct/mask_struct_load_run-1.c   |  38 +++
 .../autovec/struct/mask_struct_load_run-2.c   |  40 +++
 .../autovec/struct/mask_struct_load_run-3.c   |  41 ++++
 .../autovec/struct/mask_struct_load_run-4.c   |  42 ++++
 .../autovec/struct/mask_struct_load_run-5.c   |  43 ++++
 .../autovec/struct/mask_struct_load_run-6.c   |  44 ++++
 .../autovec/struct/mask_struct_load_run-7.c   |  45 ++++
 .../rvv/autovec/struct/mask_struct_store-1.c  |  48 ++++
 .../rvv/autovec/struct/mask_struct_store-2.c  |  49 ++++
 .../rvv/autovec/struct/mask_struct_store-3.c  |  50 ++++
 .../rvv/autovec/struct/mask_struct_store-4.c  |  51 ++++
 .../rvv/autovec/struct/mask_struct_store-5.c  |  52 ++++
 .../rvv/autovec/struct/mask_struct_store-6.c  |  53 ++++
 .../rvv/autovec/struct/mask_struct_store-7.c  |  54 ++++
 .../autovec/struct/mask_struct_store_run-1.c  |  38 +++
 .../autovec/struct/mask_struct_store_run-2.c  |  38 +++
 .../autovec/struct/mask_struct_store_run-3.c  |  38 +++
 .../autovec/struct/mask_struct_store_run-4.c  |  38 +++
 .../autovec/struct/mask_struct_store_run-5.c  |  38 +++
 .../autovec/struct/mask_struct_store_run-6.c  |  38 +++
 .../autovec/struct/mask_struct_store_run-7.c  |  38 +++
 .../riscv/rvv/autovec/struct/struct_vect-1.c  | 232 ++++++++++++++++++
 .../riscv/rvv/autovec/struct/struct_vect-10.c |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-11.c |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-12.c |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-13.c |  27 ++
 .../riscv/rvv/autovec/struct/struct_vect-14.c |  25 ++
 .../riscv/rvv/autovec/struct/struct_vect-15.c |  27 ++
 .../riscv/rvv/autovec/struct/struct_vect-16.c |  25 ++
 .../riscv/rvv/autovec/struct/struct_vect-17.c |  27 ++
 .../riscv/rvv/autovec/struct/struct_vect-18.c |  25 ++
 .../riscv/rvv/autovec/struct/struct_vect-2.c  |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-3.c  |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-4.c  |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-5.c  |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-6.c  | 225 +++++++++++++++++
 .../riscv/rvv/autovec/struct/struct_vect-7.c  |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-8.c  |  22 ++
 .../riscv/rvv/autovec/struct/struct_vect-9.c  |  22 ++
 .../rvv/autovec/struct/struct_vect_run-1.c    | 139 +++++++++++
 .../rvv/autovec/struct/struct_vect_run-10.c   |   6 +
 .../rvv/autovec/struct/struct_vect_run-11.c   |   6 +
 .../rvv/autovec/struct/struct_vect_run-12.c   |   6 +
 .../rvv/autovec/struct/struct_vect_run-13.c   |  36 +++
 .../rvv/autovec/struct/struct_vect_run-14.c   |  45 ++++
 .../rvv/autovec/struct/struct_vect_run-15.c   |  36 +++
 .../rvv/autovec/struct/struct_vect_run-16.c   |  45 ++++
 .../rvv/autovec/struct/struct_vect_run-17.c   |  36 +++
 .../rvv/autovec/struct/struct_vect_run-18.c   |  45 ++++
 .../rvv/autovec/struct/struct_vect_run-2.c    |   5 +
 .../rvv/autovec/struct/struct_vect_run-3.c    |   5 +
 .../rvv/autovec/struct/struct_vect_run-4.c    |   5 +
 .../rvv/autovec/struct/struct_vect_run-5.c    |   5 +
 .../rvv/autovec/struct/struct_vect_run-6.c    | 141 +++++++++++
 .../rvv/autovec/struct/struct_vect_run-7.c    |   6 +
 .../rvv/autovec/struct/struct_vect_run-8.c    |   6 +
 .../rvv/autovec/struct/struct_vect_run-9.c    |   6 +
 gcc/testsuite/gcc.target/riscv/rvv/rvv.exp    |   2 +
 80 files changed, 2841 insertions(+), 21 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c
diff mbox series

Patch

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index cf4efbae44f..21cf2ffaec5 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -283,6 +283,36 @@ 
   DONE;
 })
 
+;; =========================================================================
+;; == Array Load/Store
+;; =========================================================================
+
+(define_expand "vec_mask_len_load_lanes<mode><vsingle>"
+  [(match_operand:VT 0 "register_operand")
+   (match_operand:VT 1 "memory_operand")
+   (match_operand:<VM> 2 "vector_mask_operand")
+   (match_operand 3 "autovec_length_operand")
+   (match_operand 4 "const_0_operand")]
+  "TARGET_VECTOR"
+  {
+    riscv_vector::expand_lanes_load_store (operands, true);
+    DONE;
+  }
+)
+
+(define_expand "vec_mask_len_store_lanes<mode><vsingle>"
+  [(match_operand:VT 0 "memory_operand")
+   (match_operand:VT 1 "register_operand")
+   (match_operand:<VM> 2 "vector_mask_operand")
+   (match_operand 3 "autovec_length_operand")
+   (match_operand 4 "const_0_operand")]
+  "TARGET_VECTOR"
+  {
+    riscv_vector::expand_lanes_load_store (operands, false);
+    DONE;
+  }
+)
+
 ;; =========================================================================
 ;; == Vector creation
 ;; =========================================================================
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 2fbed04ff84..472c00dc439 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -325,6 +325,7 @@  void expand_load_store (rtx *, bool);
 void expand_gather_scatter (rtx *, bool);
 void expand_cond_len_ternop (unsigned, rtx *);
 void prepare_ternary_operands (rtx *, bool = false);
+void expand_lanes_load_store (rtx *, bool);
 
 /* Rounding mode bitfield for fixed point VXRM.  */
 enum fixed_point_rounding_mode
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 5f9b296c92e..b01028c6201 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -1900,7 +1900,13 @@  get_avl_type_rtx (enum avl_type type)
 machine_mode
 get_mask_mode (machine_mode mode)
 {
-  return get_vector_mode (BImode, GET_MODE_NUNITS (mode)).require();
+  poly_int64 nunits = GET_MODE_NUNITS (mode);
+  if (riscv_v_ext_tuple_mode_p (mode))
+    {
+      unsigned int nf = get_nf (mode);
+      nunits = exact_div (nunits, nf);
+    }
+  return get_vector_mode (BImode, nunits).require ();
 }
 
 /* Return the appropriate M1 mode for MODE.  */
@@ -3716,4 +3722,48 @@  prepare_ternary_operands (rtx *ops, bool split_p)
     }
 }
 
+/* Expand VEC_MASK_LEN_{LOAD_LANES,STORE_LANES}.  */
+void
+expand_lanes_load_store (rtx *ops, bool is_load)
+{
+  poly_int64 value;
+  rtx mask = ops[2];
+  rtx len = ops[3];
+  rtx addr = is_load ? XEXP (ops[1], 0) : XEXP (ops[0], 0);
+  rtx reg = is_load ? ops[0] : ops[1];
+  machine_mode mode = GET_MODE (ops[0]);
+
+  if (poly_int_rtx_p (len, &value) && known_eq (value, GET_MODE_NUNITS (mode)))
+    {
+      /* If the length operand is equal to VF, it is VLMAX load/store.  */
+      if (is_load)
+	{
+	  rtx m_ops[] = {reg, mask, RVV_VUNDEF (mode), addr};
+	  emit_vlmax_masked_insn (code_for_pred_unit_strided_load (mode),
+				  RVV_UNOP_M, m_ops);
+	}
+      else
+	{
+	  len = gen_reg_rtx (Pmode);
+	  emit_vlmax_vsetvl (mode, len);
+	  emit_insn (gen_pred_unit_strided_store (mode, mask, addr, reg, len,
+						  get_avl_type_rtx (VLMAX)));
+	}
+    }
+  else
+    {
+      if (!satisfies_constraint_K (len))
+	len = force_reg (Pmode, len);
+      if (is_load)
+	{
+	  rtx m_ops[] = {reg, mask, RVV_VUNDEF (mode), addr};
+	  emit_nonvlmax_masked_insn (code_for_pred_unit_strided_load (mode),
+				     RVV_UNOP_M, m_ops, len);
+	}
+      else
+	emit_insn (gen_pred_unit_strided_store (mode, mask, addr, reg, len,
+						get_avl_type_rtx (NONVLMAX)));
+    }
+}
+
 } // namespace riscv_vector
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 9dd611e254b..fc237ac330d 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1417,6 +1417,101 @@ 
   (V1DF "df") (V2DF "df") (V4DF "df") (V8DF "df") (V16DF "df") (V32DF "df") (V64DF "df") (V128DF "df") (V256DF "df") (V512DF "df")
 ])
 
+(define_mode_attr vsingle [
+  (RVVM1x8QI "rvvm1qi") (RVVMF2x8QI "rvvmf2qi") (RVVMF4x8QI "rvvmf4qi") (RVVMF8x8QI "rvvmf8qi")
+  (RVVM1x7QI "rvvm1qi") (RVVMF2x7QI "rvvmf2qi") (RVVMF4x7QI "rvvmf4qi") (RVVMF8x7QI "rvvmf8qi")
+  (RVVM1x6QI "rvvm1qi") (RVVMF2x6QI "rvvmf2qi") (RVVMF4x6QI "rvvmf4qi") (RVVMF8x6QI "rvvmf8qi")
+  (RVVM1x5QI "rvvm1qi") (RVVMF2x5QI "rvvmf2qi") (RVVMF4x5QI "rvvmf4qi") (RVVMF8x5QI "rvvmf8qi")
+  (RVVM2x4QI "rvvm2qi") (RVVM1x4QI "rvvm1qi") (RVVMF2x4QI "rvvmf2qi") (RVVMF4x4QI "rvvmf4qi") (RVVMF8x4QI "rvvmf8qi")
+  (RVVM2x3QI "rvvm2qi") (RVVM1x3QI "rvvm1qi") (RVVMF2x3QI "rvvmf2qi") (RVVMF4x3QI "rvvmf4qi") (RVVMF8x3QI "rvvmf8qi")
+  (RVVM4x2QI "rvvm4qi") (RVVM2x2QI "rvvm1qi") (RVVM1x2QI "rvvm1qi") (RVVMF2x2QI "rvvmf2qi") (RVVMF4x2QI "rvvmf4qi") (RVVMF8x2QI "rvvmf8qi")
+
+  (RVVM1x8HI "rvvm1hi") (RVVMF2x8HI "rvvmf2hi") (RVVMF4x8HI "rvvmf4hi")
+  (RVVM1x7HI "rvvm1hi") (RVVMF2x7HI "rvvmf2hi") (RVVMF4x7HI "rvvmf4hi")
+  (RVVM1x6HI "rvvm1hi") (RVVMF2x6HI "rvvmf2hi") (RVVMF4x6HI "rvvmf4hi")
+  (RVVM1x5HI "rvvm1hi") (RVVMF2x5HI "rvvmf2hi") (RVVMF4x5HI "rvvmf4hi")
+  (RVVM2x4HI "rvvm2hi") (RVVM1x4HI "rvvm1hi") (RVVMF2x4HI "rvvmf2hi") (RVVMF4x4HI "rvvmf4hi")
+  (RVVM2x3HI "rvvm2hi") (RVVM1x3HI "rvvm1hi") (RVVMF2x3HI "rvvmf2hi") (RVVMF4x3HI "rvvmf4hi")
+  (RVVM4x2HI "rvvm4hi") (RVVM2x2HI "rvvm2hi") (RVVM1x2HI "rvvm1hi") (RVVMF2x2HI "rvvmf2hi") (RVVMF4x2HI "rvvmf4hi")
+
+  (RVVM1x8HF "rvvm1hf")
+  (RVVMF2x8HF "rvvmf2hf")
+  (RVVMF4x8HF "rvvmf4hf")
+  (RVVM1x7HF "rvvm1hf")
+  (RVVMF2x7HF "rvvmf2hf")
+  (RVVMF4x7HF "rvvmf4hf")
+  (RVVM1x6HF "rvvm1hf")
+  (RVVMF2x6HF "rvvmf2hf")
+  (RVVMF4x6HF "rvvmf4hf")
+  (RVVM1x5HF "rvvm1hf")
+  (RVVMF2x5HF "rvvmf2hf")
+  (RVVMF4x5HF "rvvmf4hf")
+  (RVVM2x4HF "rvvm2hf")
+  (RVVM1x4HF "rvvm1hf")
+  (RVVMF2x4HF "rvvmf2hf")
+  (RVVMF4x4HF "rvvmf4hf")
+  (RVVM2x3HF "rvvm2hf")
+  (RVVM1x3HF "rvvm1hf")
+  (RVVMF2x3HF "rvvmf2hf")
+  (RVVMF4x3HF "rvvmf4hf")
+  (RVVM4x2HF "rvvm4hf")
+  (RVVM2x2HF "rvvm2hf")
+  (RVVM1x2HF "rvvm1hf")
+  (RVVMF2x2HF "rvvmf2hf")
+  (RVVMF4x2HF "rvvmf4hf")
+
+  (RVVM1x8SI "rvvm1si") (RVVMF2x8SI "rvvmf2si")
+  (RVVM1x7SI "rvvm1si") (RVVMF2x7SI "rvvmf2si")
+  (RVVM1x6SI "rvvm1si") (RVVMF2x6SI "rvvmf2si")
+  (RVVM1x5SI "rvvm1si") (RVVMF2x5SI "rvvmf2si")
+  (RVVM2x4SI "rvvm2si") (RVVM1x4SI "rvvm1si") (RVVMF2x4SI "rvvmf2si")
+  (RVVM2x3SI "rvvm2si") (RVVM1x3SI "rvvm1si") (RVVMF2x3SI "rvvmf2si")
+  (RVVM4x2SI "rvvm4si") (RVVM2x2SI "rvvm2si") (RVVM1x2SI "rvvm1si") (RVVMF2x2SI "rvvmf2si")
+
+  (RVVM1x8SF "rvvm1sf")
+  (RVVMF2x8SF "rvvmf2sf")
+  (RVVM1x7SF "rvvm1sf")
+  (RVVMF2x7SF "rvvmf2sf")
+  (RVVM1x6SF "rvvm1sf")
+  (RVVMF2x6SF "rvvmf2sf")
+  (RVVM1x5SF "rvvm1sf")
+  (RVVMF2x5SF "rvvmf2sf")
+  (RVVM2x4SF "rvvm2sf")
+  (RVVM1x4SF "rvvm1sf")
+  (RVVMF2x4SF "rvvmf2sf")
+  (RVVM2x3SF "rvvm2sf")
+  (RVVM1x3SF "rvvm1sf")
+  (RVVMF2x3SF "rvvmf2sf")
+  (RVVM4x2SF "rvvm4sf")
+  (RVVM2x2SF "rvvm2sf")
+  (RVVM1x2SF "rvvm1sf")
+  (RVVMF2x2SF "rvvmf2sf")
+
+  (RVVM1x8DI "rvvm1di")
+  (RVVM1x7DI "rvvm1di")
+  (RVVM1x6DI "rvvm1di")
+  (RVVM1x5DI "rvvm1di")
+  (RVVM2x4DI "rvvm2di")
+  (RVVM1x4DI "rvvm1di")
+  (RVVM2x3DI "rvvm2di")
+  (RVVM1x3DI "rvvm1di")
+  (RVVM4x2DI "rvvm4di")
+  (RVVM2x2DI "rvvm2di")
+  (RVVM1x2DI "rvvm1di")
+
+  (RVVM1x8DF "rvvm1df")
+  (RVVM1x7DF "rvvm1df")
+  (RVVM1x6DF "rvvm1df")
+  (RVVM1x5DF "rvvm1df")
+  (RVVM2x4DF "rvvm2df")
+  (RVVM1x4DF "rvvm1df")
+  (RVVM2x3DF "rvvm2df")
+  (RVVM1x3DF "rvvm1df")
+  (RVVM4x2DF "rvvm4df")
+  (RVVM2x2DF "rvvm2df")
+  (RVVM1x2DF "rvvm1df")
+])
+
 (define_mode_attr VSUBEL [
   (RVVM8HI "QI") (RVVM4HI "QI") (RVVM2HI "QI") (RVVM1HI "QI") (RVVMF2HI "QI") (RVVMF4HI "QI")
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c
index ee5f509b9ac..2c9e7dd14a8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c
@@ -40,6 +40,6 @@ 
 
 TEST_ALL (TEST_LOOP)
 
-/* { dg-final { scan-tree-dump-times " \.MASK_LEN_GATHER_LOAD" 46 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \.MASK_LEN_GATHER_LOAD" 33 "optimized" } } */
 /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "optimized" } } */
 /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c
index 0bce8361327..788e0450b47 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c
@@ -19,6 +19,7 @@  f (int8_t *restrict a, int8_t *restrict b, int n)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */
-/* { dg-final { scan-assembler {\tvid\.v} } } */
-/* { dg-final { scan-assembler {\tvand} } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {\tvand} { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c
index 1a35bba013b..b58e270eaa4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c
@@ -19,6 +19,7 @@  f (uint8_t *restrict a, uint8_t *restrict b, int n)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */
-/* { dg-final { scan-assembler {\tvid\.v} } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */
 /* { dg-final { scan-assembler-not {\tvmul} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c
index 2f2c3d11c2a..bccf3e6570a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c
@@ -29,6 +29,7 @@  f (uint8_t *restrict a, uint8_t *restrict b,
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 2 "optimized" } } */
-/* { dg-final { scan-assembler {\tvid\.v} } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 2 "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */
 /* { dg-final { scan-assembler-not {\tvmul} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c
index 72103314b1a..f00bece1414 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c
@@ -21,6 +21,7 @@  f (float *restrict a, float *restrict b,
     }
 }
 
-/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" } } */
-/* { dg-final { scan-assembler {\tvid\.v} } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */
 /* { dg-final { scan-assembler-not {\tvmul} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c
index 41ce0fc5767..67db75517c3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c
@@ -21,6 +21,6 @@  f (float *restrict a, float *restrict b,
     }
 }
 
-/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" } } */
-/* { dg-final { scan-assembler {\tvid\.v} } } */
+/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */
 /* { dg-final { scan-assembler-not {\tvmul} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c
index ac817451295..ad60b11d815 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
 
 #include <stdint-gcc.h>
 
@@ -19,4 +19,5 @@  f (int16_t *restrict a, int16_t *restrict b, int n)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c
index 73962055b03..088828f326f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c
@@ -19,4 +19,5 @@  f (int8_t *restrict a, int8_t *restrict b, int n)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c
index fa216fc8c40..d56feeb8fdf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
 
 #include <stdint-gcc.h>
 
@@ -19,4 +19,5 @@  f (int16_t *restrict a, int16_t *restrict b, int n)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c
index 899ed9e310b..d825a257ccd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c
@@ -19,4 +19,5 @@  f (int8_t *restrict a, int8_t *restrict b, int n)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c
index fb87cc00cea..160880c42b7 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */
 
 #include <stdint-gcc.h>
 
@@ -19,5 +19,6 @@  f (uint8_t *restrict a, uint8_t *restrict b, int n)
     }
 }
 
-/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */
+/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP.  */
+/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c
new file mode 100644
index 00000000000..e5dc10aea88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c
@@ -0,0 +1,42 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_2 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, intptr_t n)		\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      if (cond[i])						\
+	dest[i] = src[i * 2] + src[i * 2 + 1];			\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg2e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vlseg2e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg2e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg2e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c
new file mode 100644
index 00000000000..9d61a85267a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c
@@ -0,0 +1,44 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_3 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, intptr_t n)		\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      if (cond[i])						\
+	dest[i] = (src[i * 3]					\
+		   + src[i * 3 + 1]				\
+		   + src[i * 3 + 2]);				\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg3e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vlseg3e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg3e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg3e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c
new file mode 100644
index 00000000000..a686236793a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c
@@ -0,0 +1,45 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_4 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, intptr_t n)		\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      if (cond[i])						\
+	dest[i] = (src[i * 4]					\
+		   + src[i * 4 + 1]				\
+		   + src[i * 4 + 2]				\
+		   + src[i * 4 + 3]);				\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg4e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vlseg4e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg4e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg4e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c
new file mode 100644
index 00000000000..e3c48df5d3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c
@@ -0,0 +1,43 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)                             \
+  void __attribute__ ((noinline, noclone))                                     \
+  NAME##_5 (OUTTYPE *__restrict dest, INTYPE *__restrict src,                  \
+	    MASKTYPE *__restrict cond, intptr_t n)                             \
+  {                                                                            \
+    for (intptr_t i = 0; i < n; ++i)                                           \
+      if (cond[i])                                                             \
+	dest[i] = (src[i * 5] + src[i * 5 + 1] + src[i * 5 + 2]                \
+		   + src[i * 5 + 3] + src[i * 5 + 4]);                         \
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE)                                           \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t)                               \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t)                            \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float)                               \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE)                                                   \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t)                                           \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t)                                        \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t)                                         \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME)                                                             \
+  TEST1 (NAME##_i8, int8_t)                                                    \
+  TEST1 (NAME##_i16, uint16_t)                                                 \
+  TEST1 (NAME##_i32, int32_t)                                                  \
+  TEST1 (NAME##_i64, uint64_t)                                                 \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16)                                   \
+  TEST2 (NAME##_f32_f32, float, float)                                         \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg5e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vlseg5e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg5e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg5e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c
new file mode 100644
index 00000000000..81f1a7a5ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c
@@ -0,0 +1,43 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)                             \
+  void __attribute__ ((noinline, noclone))                                     \
+  NAME##_6 (OUTTYPE *__restrict dest, INTYPE *__restrict src,                  \
+	    MASKTYPE *__restrict cond, intptr_t n)                             \
+  {                                                                            \
+    for (intptr_t i = 0; i < n; ++i)                                           \
+      if (cond[i])                                                             \
+	dest[i] = (src[i * 6] + src[i * 6 + 1] + src[i * 6 + 2]                \
+		   + src[i * 6 + 3] + src[i * 6 + 4] + src[i * 6 + 5]);        \
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE)                                           \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t)                               \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t)                            \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float)                               \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE)                                                   \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t)                                           \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t)                                        \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t)                                         \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME)                                                             \
+  TEST1 (NAME##_i8, int8_t)                                                    \
+  TEST1 (NAME##_i16, uint16_t)                                                 \
+  TEST1 (NAME##_i32, int32_t)                                                  \
+  TEST1 (NAME##_i64, uint64_t)                                                 \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16)                                   \
+  TEST2 (NAME##_f32_f32, float, float)                                         \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg6e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vlseg6e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg6e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg6e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c
new file mode 100644
index 00000000000..911af2a853d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c
@@ -0,0 +1,44 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)                             \
+  void __attribute__ ((noinline, noclone))                                     \
+  NAME##_7 (OUTTYPE *__restrict dest, INTYPE *__restrict src,                  \
+	    MASKTYPE *__restrict cond, intptr_t n)                             \
+  {                                                                            \
+    for (intptr_t i = 0; i < n; ++i)                                           \
+      if (cond[i])                                                             \
+	dest[i]                                                                \
+	  = (src[i * 7] + src[i * 7 + 1] + src[i * 7 + 2] + src[i * 7 + 3]     \
+	     + src[i * 7 + 4] + src[i * 7 + 5] + src[i * 7 + 6]);              \
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE)                                           \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t)                               \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t)                            \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float)                               \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE)                                                   \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t)                                           \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t)                                        \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t)                                         \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME)                                                             \
+  TEST1 (NAME##_i8, int8_t)                                                    \
+  TEST1 (NAME##_i16, uint16_t)                                                 \
+  TEST1 (NAME##_i32, int32_t)                                                  \
+  TEST1 (NAME##_i64, uint64_t)                                                 \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16)                                   \
+  TEST2 (NAME##_f32_f32, float, float)                                         \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg7e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vlseg7e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg7e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg7e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c
new file mode 100644
index 00000000000..112facee5ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c
@@ -0,0 +1,44 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)                             \
+  void __attribute__ ((noinline, noclone))                                     \
+  NAME##_8 (OUTTYPE *__restrict dest, INTYPE *__restrict src,                  \
+	    MASKTYPE *__restrict cond, intptr_t n)                             \
+  {                                                                            \
+    for (intptr_t i = 0; i < n; ++i)                                           \
+      if (cond[i])                                                             \
+	dest[i] = (src[i * 8] + src[i * 8 + 1] + src[i * 8 + 2]                \
+		   + src[i * 8 + 3] + src[i * 8 + 4] + src[i * 8 + 5]          \
+		   + src[i * 8 + 6] + src[i * 8 + 7]);                         \
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE)                                           \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t)                               \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t)                            \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float)                               \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE)                                                   \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t)                                           \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t)                                        \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t)                                         \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME)                                                             \
+  TEST1 (NAME##_i8, int8_t)                                                    \
+  TEST1 (NAME##_i16, uint16_t)                                                 \
+  TEST1 (NAME##_i32, int32_t)                                                  \
+  TEST1 (NAME##_i64, uint64_t)                                                 \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16)                                   \
+  TEST2 (NAME##_f32_f32, float, float)                                         \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg8e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vlseg8e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg8e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vlseg8e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c
new file mode 100644
index 00000000000..232ebceb9fc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_load-1.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)	\
+  {							\
+    OUTTYPE out[N];					\
+    INTYPE in[N * 2];					\
+    MASKTYPE mask[N];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	mask[i] = i % 5 <= i % 3;			\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 2; ++i)			\
+      in[i] = i * 9 / 2;				\
+    NAME##_2 (out, in, mask, N);			\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	OUTTYPE if_true = in[i * 2] + in[i * 2 + 1];	\
+	OUTTYPE if_false = i * 7 / 2;			\
+	if (out[i] != (mask[i] ? if_true : if_false))	\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c
new file mode 100644
index 00000000000..309baf32bc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c
@@ -0,0 +1,40 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_load-2.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)	\
+  {							\
+    OUTTYPE out[N];					\
+    INTYPE in[N * 3];					\
+    MASKTYPE mask[N];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	mask[i] = i % 5 <= i % 3;			\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 3; ++i)			\
+      in[i] = i * 9 / 2;				\
+    NAME##_3 (out, in, mask, N);			\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	OUTTYPE if_true = (in[i * 3]			\
+			   + in[i * 3 + 1]		\
+			   + in[i * 3 + 2]);		\
+	OUTTYPE if_false = i * 7 / 2;			\
+	if (out[i] != (mask[i] ? if_true : if_false))	\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c
new file mode 100644
index 00000000000..2c818bbc117
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c
@@ -0,0 +1,41 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_load-3.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)	\
+  {							\
+    OUTTYPE out[N];					\
+    INTYPE in[N * 4];					\
+    MASKTYPE mask[N];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	mask[i] = i % 5 <= i % 3;			\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 4; ++i)			\
+      in[i] = i * 9 / 2;				\
+    NAME##_4 (out, in, mask, N);			\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	OUTTYPE if_true = (in[i * 4]			\
+			   + in[i * 4 + 1]		\
+			   + in[i * 4 + 2]		\
+			   + in[i * 4 + 3]);		\
+	OUTTYPE if_false = i * 7 / 2;			\
+	if (out[i] != (mask[i] ? if_true : if_false))	\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c
new file mode 100644
index 00000000000..c2135b8c452
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c
@@ -0,0 +1,42 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_load-4.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)	\
+  {							\
+    OUTTYPE out[N];					\
+    INTYPE in[N * 5];					\
+    MASKTYPE mask[N];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	mask[i] = i % 5 <= i % 3;			\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 5; ++i)			\
+      in[i] = i * 9 / 2;				\
+    NAME##_5 (out, in, mask, N);			\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	OUTTYPE if_true = (in[i * 5]			\
+			   + in[i * 5 + 1]		\
+			   + in[i * 5 + 2]		\
+			   + in[i * 5 + 3]		\
+         + in[i * 5 + 4]);		\
+	OUTTYPE if_false = i * 7 / 2;			\
+	if (out[i] != (mask[i] ? if_true : if_false))	\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c
new file mode 100644
index 00000000000..029769994aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c
@@ -0,0 +1,43 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_load-5.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)	\
+  {							\
+    OUTTYPE out[N];					\
+    INTYPE in[N * 6];					\
+    MASKTYPE mask[N];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	mask[i] = i % 5 <= i % 3;			\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 6; ++i)			\
+      in[i] = i * 9 / 2;				\
+    NAME##_6 (out, in, mask, N);			\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	OUTTYPE if_true = (in[i * 6]			\
+			   + in[i * 6 + 1]		\
+			   + in[i * 6 + 2]		\
+			   + in[i * 6 + 3]		\
+         + in[i * 6 + 4]		\
+         + in[i * 6 + 5]);		\
+	OUTTYPE if_false = i * 7 / 2;			\
+	if (out[i] != (mask[i] ? if_true : if_false))	\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c
new file mode 100644
index 00000000000..c24c6411d5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c
@@ -0,0 +1,44 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_load-6.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)	\
+  {							\
+    OUTTYPE out[N];					\
+    INTYPE in[N * 7];					\
+    MASKTYPE mask[N];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	mask[i] = i % 5 <= i % 3;			\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 7; ++i)			\
+      in[i] = i * 9 / 2;				\
+    NAME##_7 (out, in, mask, N);			\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	OUTTYPE if_true = (in[i * 7]			\
+			   + in[i * 7 + 1]		\
+			   + in[i * 7 + 2]		\
+			   + in[i * 7 + 3]		\
+         + in[i * 7 + 4]		\
+         + in[i * 7 + 5]		\
+         + in[i * 7 + 6]);		\
+	OUTTYPE if_false = i * 7 / 2;			\
+	if (out[i] != (mask[i] ? if_true : if_false))	\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c
new file mode 100644
index 00000000000..be65d948da5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_load-7.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)	\
+  {							\
+    OUTTYPE out[N];					\
+    INTYPE in[N * 8];					\
+    MASKTYPE mask[N];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	mask[i] = i % 5 <= i % 3;			\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 8; ++i)			\
+      in[i] = i * 9 / 2;				\
+    NAME##_8 (out, in, mask, N);			\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	OUTTYPE if_true = (in[i * 8]			\
+			   + in[i * 8 + 1]		\
+			   + in[i * 8 + 2]		\
+			   + in[i * 8 + 3]		\
+         + in[i * 8 + 4]		\
+         + in[i * 8 + 5]		\
+         + in[i * 8 + 6]		\
+         + in[i * 8 + 7]);		\
+	OUTTYPE if_false = i * 7 / 2;			\
+	if (out[i] != (mask[i] ? if_true : if_false))	\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c
new file mode 100644
index 00000000000..6df5f08dbc0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c
@@ -0,0 +1,48 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_2 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, INTYPE bias, intptr_t n)	\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      {								\
+	INTYPE value = src[i] + bias;				\
+	if (cond[i])						\
+	  {							\
+	    dest[i * 2] = value;				\
+	    dest[i * 2 + 1] = value;				\
+	  }							\
+      }								\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vsseg2e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vsseg2e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg2e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg2e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c
new file mode 100644
index 00000000000..532b4580b20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c
@@ -0,0 +1,49 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_3 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, INTYPE bias, intptr_t n)	\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      {								\
+	INTYPE value = src[i] + bias;				\
+	if (cond[i])						\
+	  {							\
+	    dest[i * 3] = value;				\
+	    dest[i * 3 + 1] = value;				\
+	    dest[i * 3 + 2] = value;				\
+	  }							\
+      }								\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vsseg3e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vsseg3e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg3e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg3e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c
new file mode 100644
index 00000000000..92ed2361e37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c
@@ -0,0 +1,50 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_4 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, INTYPE bias, intptr_t n)	\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      {								\
+	INTYPE value = src[i] + bias;				\
+	if (cond[i])						\
+	  {							\
+	    dest[i * 4] = value;				\
+	    dest[i * 4 + 1] = value;				\
+	    dest[i * 4 + 2] = value;				\
+	    dest[i * 4 + 3] = value;				\
+	  }							\
+      }								\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vsseg4e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vsseg4e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg4e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg4e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c
new file mode 100644
index 00000000000..4a4048f6921
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c
@@ -0,0 +1,51 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_5 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, INTYPE bias, intptr_t n)	\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      {								\
+	INTYPE value = src[i] + bias;				\
+	if (cond[i])						\
+	  {							\
+	    dest[i * 5] = value;				\
+	    dest[i * 5 + 1] = value;				\
+	    dest[i * 5 + 2] = value;				\
+	    dest[i * 5 + 3] = value;				\
+      dest[i * 5 + 4] = value;				\
+	  }							\
+      }								\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vsseg5e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vsseg5e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg5e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg5e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c
new file mode 100644
index 00000000000..eca8d5aa003
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c
@@ -0,0 +1,52 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_6 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, INTYPE bias, intptr_t n)	\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      {								\
+	INTYPE value = src[i] + bias;				\
+	if (cond[i])						\
+	  {							\
+	    dest[i * 6] = value;				\
+	    dest[i * 6 + 1] = value;				\
+	    dest[i * 6 + 2] = value;				\
+	    dest[i * 6 + 3] = value;				\
+      dest[i * 6 + 4] = value;				\
+      dest[i * 6 + 5] = value;				\
+	  }							\
+      }								\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vsseg6e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vsseg6e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg6e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg6e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c
new file mode 100644
index 00000000000..3cce1620930
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c
@@ -0,0 +1,53 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_7 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, INTYPE bias, intptr_t n)	\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      {								\
+	INTYPE value = src[i] + bias;				\
+	if (cond[i])						\
+	  {							\
+	    dest[i * 7] = value;				\
+	    dest[i * 7 + 1] = value;				\
+	    dest[i * 7 + 2] = value;				\
+	    dest[i * 7 + 3] = value;				\
+      dest[i * 7 + 4] = value;				\
+      dest[i * 7 + 5] = value;				\
+      dest[i * 7 + 6] = value;				\
+	  }							\
+      }								\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vsseg7e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vsseg7e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg7e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg7e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c
new file mode 100644
index 00000000000..9d0073bcf0e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c
@@ -0,0 +1,54 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  void __attribute__ ((noinline, noclone))			\
+  NAME##_8 (OUTTYPE *__restrict dest, INTYPE *__restrict src,	\
+	    MASKTYPE *__restrict cond, INTYPE bias, intptr_t n)	\
+  {								\
+    for (intptr_t i = 0; i < n; ++i)				\
+      {								\
+	INTYPE value = src[i] + bias;				\
+	if (cond[i])						\
+	  {							\
+	    dest[i * 8] = value;				\
+	    dest[i * 8 + 1] = value;				\
+	    dest[i * 8 + 2] = value;				\
+	    dest[i * 8 + 3] = value;				\
+      dest[i * 8 + 4] = value;				\
+      dest[i * 8 + 5] = value;				\
+      dest[i * 8 + 6] = value;				\
+      dest[i * 8 + 7] = value;				\
+	  }							\
+      }								\
+  }
+
+#define TEST2(NAME, OUTTYPE, INTYPE) \
+  TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \
+  TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \
+  TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \
+  TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double)
+
+#define TEST1(NAME, OUTTYPE) \
+  TEST2 (NAME##_i8, OUTTYPE, int8_t) \
+  TEST2 (NAME##_i16, OUTTYPE, uint16_t) \
+  TEST2 (NAME##_i32, OUTTYPE, int32_t) \
+  TEST2 (NAME##_i64, OUTTYPE, uint64_t)
+
+#define TEST(NAME) \
+  TEST1 (NAME##_i8, int8_t) \
+  TEST1 (NAME##_i16, uint16_t) \
+  TEST1 (NAME##_i32, int32_t) \
+  TEST1 (NAME##_i64, uint64_t) \
+  TEST2 (NAME##_f16_f16, _Float16, _Float16) \
+  TEST2 (NAME##_f32_f32, float, float) \
+  TEST2 (NAME##_f64_f64, double, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vsseg8e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vsseg8e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg8e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
+/* { dg-final { scan-assembler-times {vsseg8e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c
new file mode 100644
index 00000000000..1208ea7ad58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_store-1.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  {								\
+    OUTTYPE out[N * 2];						\
+    INTYPE in[N];						\
+    MASKTYPE mask[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	in[i] = i * 7 / 2;					\
+	mask[i] = i % 5 <= i % 3;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    for (int i = 0; i < N * 2; ++i)				\
+      out[i] = i * 9 / 2;					\
+    NAME##_2 (out, in, mask, 17, N);				\
+    for (int i = 0; i < N * 2; ++i)				\
+      {								\
+	OUTTYPE if_true = (INTYPE) (in[i / 2] + 17);		\
+	OUTTYPE if_false = i * 9 / 2;				\
+	if (out[i] != (mask[i / 2] ? if_true : if_false))	\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c
new file mode 100644
index 00000000000..199402f596f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_store-2.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  {								\
+    OUTTYPE out[N * 3];						\
+    INTYPE in[N];						\
+    MASKTYPE mask[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	in[i] = i * 7 / 2;					\
+	mask[i] = i % 5 <= i % 3;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    for (int i = 0; i < N * 3; ++i)				\
+      out[i] = i * 9 / 2;					\
+    NAME##_3 (out, in, mask, 11, N);				\
+    for (int i = 0; i < N * 3; ++i)				\
+      {								\
+	OUTTYPE if_true = (INTYPE) (in[i / 3] + 11);		\
+	OUTTYPE if_false = i * 9 / 2;				\
+	if (out[i] != (mask[i / 3] ? if_true : if_false))	\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c
new file mode 100644
index 00000000000..22fc0d5ac01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_store-3.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  {								\
+    OUTTYPE out[N * 4];						\
+    INTYPE in[N];						\
+    MASKTYPE mask[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	in[i] = i * 7 / 2;					\
+	mask[i] = i % 5 <= i % 3;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    for (int i = 0; i < N * 4; ++i)				\
+      out[i] = i * 9 / 2;					\
+    NAME##_4 (out, in, mask, 42, N);				\
+    for (int i = 0; i < N * 4; ++i)				\
+      {								\
+	OUTTYPE if_true = (INTYPE) (in[i / 4] + 42);		\
+	OUTTYPE if_false = i * 9 / 2;				\
+	if (out[i] != (mask[i / 4] ? if_true : if_false))	\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c
new file mode 100644
index 00000000000..807e06e552c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_store-4.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  {								\
+    OUTTYPE out[N * 5];						\
+    INTYPE in[N];						\
+    MASKTYPE mask[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	in[i] = i * 7 / 2;					\
+	mask[i] = i % 5 <= i % 3;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    for (int i = 0; i < N * 5; ++i)				\
+      out[i] = i * 9 / 2;					\
+    NAME##_5 (out, in, mask, 42, N);				\
+    for (int i = 0; i < N * 5; ++i)				\
+      {								\
+	OUTTYPE if_true = (INTYPE) (in[i / 5] + 42);		\
+	OUTTYPE if_false = i * 9 / 2;				\
+	if (out[i] != (mask[i / 5] ? if_true : if_false))	\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c
new file mode 100644
index 00000000000..3ce3774fcc5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_store-5.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  {								\
+    OUTTYPE out[N * 6];						\
+    INTYPE in[N];						\
+    MASKTYPE mask[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	in[i] = i * 7 / 2;					\
+	mask[i] = i % 5 <= i % 3;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    for (int i = 0; i < N * 6; ++i)				\
+      out[i] = i * 9 / 2;					\
+    NAME##_6 (out, in, mask, 42, N);				\
+    for (int i = 0; i < N * 6; ++i)				\
+      {								\
+	OUTTYPE if_true = (INTYPE) (in[i / 6] + 42);		\
+	OUTTYPE if_false = i * 9 / 2;				\
+	if (out[i] != (mask[i / 6] ? if_true : if_false))	\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c
new file mode 100644
index 00000000000..8a22844bbeb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_store-6.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  {								\
+    OUTTYPE out[N * 7];						\
+    INTYPE in[N];						\
+    MASKTYPE mask[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	in[i] = i * 7 / 2;					\
+	mask[i] = i % 5 <= i % 3;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    for (int i = 0; i < N * 7; ++i)				\
+      out[i] = i * 9 / 2;					\
+    NAME##_7 (out, in, mask, 42, N);				\
+    for (int i = 0; i < N * 7; ++i)				\
+      {								\
+	OUTTYPE if_true = (INTYPE) (in[i / 7] + 42);		\
+	OUTTYPE if_false = i * 9 / 2;				\
+	if (out[i] != (mask[i / 7] ? if_true : if_false))	\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c
new file mode 100644
index 00000000000..af80f30ec4c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "mask_struct_store-7.c"
+
+#define N 100
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE)		\
+  {								\
+    OUTTYPE out[N * 8];						\
+    INTYPE in[N];						\
+    MASKTYPE mask[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	in[i] = i * 8 / 2;					\
+	mask[i] = i % 5 <= i % 3;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    for (int i = 0; i < N * 8; ++i)				\
+      out[i] = i * 9 / 2;					\
+    NAME##_8 (out, in, mask, 42, N);				\
+    for (int i = 0; i < N * 8; ++i)				\
+      {								\
+	OUTTYPE if_true = (INTYPE) (in[i / 8] + 42);		\
+	OUTTYPE if_false = i * 9 / 2;				\
+	if (out[i] != (mask[i / 8] ? if_true : if_false))	\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c
new file mode 100644
index 00000000000..f49d92d7430
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c
@@ -0,0 +1,232 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include <stdint-gcc.h>
+#ifndef TYPE
+#define TYPE uint8_t
+#endif
+
+#ifndef NAME
+#define NAME(X) X
+#endif
+
+#ifndef N
+#define N 1024
+#endif
+
+void __attribute__ ((noinline, noclone))
+NAME(f2) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      a[i] = c[i * 2];
+      b[i] = c[i * 2 + 1];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(f3) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      a[i] = d[i * 3];
+      b[i] = d[i * 3 + 1];
+      c[i] = d[i * 3 + 2];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(f4) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      a[i] = e[i * 4];
+      b[i] = e[i * 4 + 1];
+      c[i] = e[i * 4 + 2];
+      d[i] = e[i * 4 + 3];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(f5) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      a[i] = f[i * 5];
+      b[i] = f[i * 5 + 1];
+      c[i] = f[i * 5 + 2];
+      d[i] = f[i * 5 + 3];
+      e[i] = f[i * 5 + 4];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(f6) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+	  TYPE *__restrict g)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      a[i] = g[i * 6];
+      b[i] = g[i * 6 + 1];
+      c[i] = g[i * 6 + 2];
+      d[i] = g[i * 6 + 3];
+      e[i] = g[i * 6 + 4];
+      f[i] = g[i * 6 + 5];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(f7) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+	  TYPE *__restrict g, TYPE *__restrict h)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      a[i] = h[i * 7];
+      b[i] = h[i * 7 + 1];
+      c[i] = h[i * 7 + 2];
+      d[i] = h[i * 7 + 3];
+      e[i] = h[i * 7 + 4];
+      f[i] = h[i * 7 + 5];
+      g[i] = h[i * 7 + 6];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(f8) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+	  TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      a[i] = j[i * 8];
+      b[i] = j[i * 8 + 1];
+      c[i] = j[i * 8 + 2];
+      d[i] = j[i * 8 + 3];
+      e[i] = j[i * 8 + 4];
+      f[i] = j[i * 8 + 5];
+      g[i] = j[i * 8 + 6];
+      h[i] = j[i * 8 + 7];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(g2) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      c[i * 2] = a[i];
+      c[i * 2 + 1] = b[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(g3) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      d[i * 3] = a[i];
+      d[i * 3 + 1] = b[i];
+      d[i * 3 + 2] = c[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(g4) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      e[i * 4] = a[i];
+      e[i * 4 + 1] = b[i];
+      e[i * 4 + 2] = c[i];
+      e[i * 4 + 3] = d[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(g5) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      f[i * 5] = a[i];
+      f[i * 5 + 1] = b[i];
+      f[i * 5 + 2] = c[i];
+      f[i * 5 + 3] = d[i];
+      f[i * 5 + 4] = e[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(g6) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+	  TYPE *__restrict g)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      g[i * 6] = a[i];
+      g[i * 6 + 1] = b[i];
+      g[i * 6 + 2] = c[i];
+      g[i * 6 + 3] = d[i];
+      g[i * 6 + 4] = e[i];
+      g[i * 6 + 5] = f[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(g7) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+	  TYPE *__restrict g, TYPE *__restrict h)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      h[i * 7] = a[i];
+      h[i * 7 + 1] = b[i];
+      h[i * 7 + 2] = c[i];
+      h[i * 7 + 3] = d[i];
+      h[i * 7 + 4] = e[i];
+      h[i * 7 + 5] = f[i];
+      h[i * 7 + 6] = g[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+NAME(g8) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+	  TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+	  TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      j[i * 8] = a[i];
+      j[i * 8 + 1] = b[i];
+      j[i * 8 + 2] = c[i];
+      j[i * 8 + 3] = d[i];
+      j[i * 8 + 4] = e[i];
+      j[i * 8 + 5] = f[i];
+      j[i * 8 + 6] = g[i];
+      j[i * 8 + 7] = h[i];
+    }
+}
+
+/* { dg-final { scan-assembler-times {vlseg2e8\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg3e8\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg4e8\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg5e8\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg6e8\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg7e8\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vlseg8e8\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg2e8\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg3e8\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg4e8\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg5e8\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg6e8\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg7e8\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg8e8\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*16,\s*e8,\s*m1,\s*t[au],\s*m[au]} 14 } } */
+/* { dg-final { scan-assembler-not {vsetvli} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c
new file mode 100644
index 00000000000..dc4d6512f23
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE _Float16
+#define ITYPE int16_t
+#include "struct_vect-6.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg5e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg6e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg7e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg8e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg2e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg3e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg4e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg5e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg6e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg7e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg8e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c
new file mode 100644
index 00000000000..36ade63dd9e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE float
+#define ITYPE int32_t
+#include "struct_vect-6.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg5e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg6e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg7e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg8e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg2e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg3e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg4e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg5e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg6e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg7e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg8e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c
new file mode 100644
index 00000000000..a2a93c432c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE double
+#define ITYPE int64_t
+#include "struct_vect-6.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg5e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg6e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg7e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg8e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg2e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg3e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg4e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg5e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg6e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg7e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg8e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c
new file mode 100644
index 00000000000..4da1c4148bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define N 2000
+
+#define TEST_LOOP(NAME, TYPE)					\
+  void __attribute__ ((noinline, noclone))			\
+  NAME (TYPE *restrict dest, TYPE *restrict src)		\
+  {								\
+    for (int i = 0; i < N; ++i)					\
+      dest[i] += src[i * 3];					\
+  }
+
+#define TEST(NAME) \
+  TEST_LOOP (NAME##_i8, int8_t) \
+  TEST_LOOP (NAME##_i16, uint16_t) \
+  TEST_LOOP (NAME##_f32, float) \
+  TEST_LOOP (NAME##_f64, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg3e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c
new file mode 100644
index 00000000000..f652a35bae4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, TYPE)					\
+  void __attribute__ ((noinline, noclone))			\
+  NAME (TYPE *restrict dest, TYPE *restrict src, int n)		\
+  {								\
+    for (int i = 0; i < n; ++i)					\
+      dest[i] += src[i * 3];					\
+  }
+
+#define TEST(NAME) \
+  TEST_LOOP (NAME##_i8, int8_t) \
+  TEST_LOOP (NAME##_i16, uint16_t) \
+  TEST_LOOP (NAME##_f32, float) \
+  TEST_LOOP (NAME##_f64, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg3e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c
new file mode 100644
index 00000000000..29d32ab29dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define N 2000
+
+#define TEST_LOOP(NAME, TYPE)					\
+  void __attribute__ ((noinline, noclone))			\
+  NAME (TYPE *restrict dest, TYPE *restrict src)		\
+  {								\
+    for (int i = 0; i < N; ++i)					\
+      dest[i] += src[i * 2];					\
+  }
+
+#define TEST(NAME) \
+  TEST_LOOP (NAME##_i8, int8_t) \
+  TEST_LOOP (NAME##_i16, uint16_t) \
+  TEST_LOOP (NAME##_f32, float) \
+  TEST_LOOP (NAME##_f64, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg2e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c
new file mode 100644
index 00000000000..15de93ec66f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, TYPE)					\
+  void __attribute__ ((noinline, noclone))			\
+  NAME (TYPE *restrict dest, TYPE *restrict src, int n)		\
+  {								\
+    for (int i = 0; i < n; ++i)					\
+      dest[i] += src[i * 2];					\
+  }
+
+#define TEST(NAME) \
+  TEST_LOOP (NAME##_i8, int8_t) \
+  TEST_LOOP (NAME##_i16, uint16_t) \
+  TEST_LOOP (NAME##_f32, float) \
+  TEST_LOOP (NAME##_f64, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg2e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c
new file mode 100644
index 00000000000..44eb0725a8e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define N 2000
+
+#define TEST_LOOP(NAME, TYPE)					\
+  void __attribute__ ((noinline, noclone))			\
+  NAME (TYPE *restrict dest, TYPE *restrict src)		\
+  {								\
+    for (int i = 0; i < N; ++i)					\
+      dest[i] += src[i * 4];					\
+  }
+
+#define TEST(NAME) \
+  TEST_LOOP (NAME##_i8, int8_t) \
+  TEST_LOOP (NAME##_i16, uint16_t) \
+  TEST_LOOP (NAME##_f32, float) \
+  TEST_LOOP (NAME##_f64, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg4e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c
new file mode 100644
index 00000000000..f6f559e4c2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define TEST_LOOP(NAME, TYPE)					\
+  void __attribute__ ((noinline, noclone))			\
+  NAME (TYPE *restrict dest, TYPE *restrict src, int n)		\
+  {								\
+    for (int i = 0; i < n; ++i)					\
+      dest[i] += src[i * 4];					\
+  }
+
+#define TEST(NAME) \
+  TEST_LOOP (NAME##_i8, int8_t) \
+  TEST_LOOP (NAME##_i16, uint16_t) \
+  TEST_LOOP (NAME##_f32, float) \
+  TEST_LOOP (NAME##_f64, double)
+
+TEST (test)
+
+/* { dg-final { scan-assembler-times {vlseg4e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c
new file mode 100644
index 00000000000..2a61a79c620
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE uint16_t
+#include "struct_vect-1.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e16\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg3e16\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg4e16\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg5e16\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg6e16\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vlseg7e16\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vlseg8e16\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg2e16\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg3e16\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg4e16\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg5e16\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg6e16\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg7e16\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vsseg8e16\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*8,\s*e16,\s*m1,\s*t[au],\s*m[au]} 14 } } */
+/* { dg-final { scan-assembler-not {vsetvli} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c
new file mode 100644
index 00000000000..3d818dad10f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE uint32_t
+#include "struct_vect-1.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg3e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg4e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg5e32\.v} 6 } } */
+/* { dg-final { scan-assembler-times {vlseg6e32\.v} 6 } } */
+/* { dg-final { scan-assembler-times {vlseg7e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vlseg8e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg2e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg3e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg4e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg5e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg6e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg7e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg8e32\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*4,\s*e32,\s*m1,\s*t[au],\s*m[au]} 14 } } */
+/* { dg-final { scan-assembler-not {vsetvli} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c
new file mode 100644
index 00000000000..b5ad45e8f82
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE uint64_t
+#include "struct_vect-1.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e64\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg3e64\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg4e64\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg5e64\.v} 7 } } */
+/* { dg-final { scan-assembler-times {vlseg6e64\.v} 7 } } */
+/* { dg-final { scan-assembler-times {vlseg7e64\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vlseg8e64\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg2e64\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg3e64\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg4e64\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg5e64\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg6e64\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg7e64\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg8e64\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*2,\s*e64,\s*m1,\s*t[au],\s*m[au]} 14 } } */
+/* { dg-final { scan-assembler-not {vsetvli} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c
new file mode 100644
index 00000000000..63b83dfab2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE float
+#include "struct_vect-1.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg3e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg4e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vlseg5e32\.v} 6 } } */
+/* { dg-final { scan-assembler-times {vlseg6e32\.v} 6 } } */
+/* { dg-final { scan-assembler-times {vlseg7e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vlseg8e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg2e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg3e32\.v} 8 } } */
+/* { dg-final { scan-assembler-times {vsseg4e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg5e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg6e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg7e32\.v} 4 } } */
+/* { dg-final { scan-assembler-times {vsseg8e32\.v} 2 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*4,\s*e32,\s*m1,\s*t[au],\s*m[au]} 14 } } */
+/* { dg-final { scan-assembler-not {vsetvli} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c
new file mode 100644
index 00000000000..2494744d8b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c
@@ -0,0 +1,225 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#ifndef TYPE
+#define TYPE uint8_t
+#define ITYPE int8_t
+#endif
+
+void __attribute__ ((noinline, noclone))
+f2 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      a[i] = c[i * 2];
+      b[i] = c[i * 2 + 1];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+f3 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      a[i] = d[i * 3];
+      b[i] = d[i * 3 + 1];
+      c[i] = d[i * 3 + 2];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+f4 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      a[i] = e[i * 4];
+      b[i] = e[i * 4 + 1];
+      c[i] = e[i * 4 + 2];
+      d[i] = e[i * 4 + 3];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+f5 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      a[i] = f[i * 5];
+      b[i] = f[i * 5 + 1];
+      c[i] = f[i * 5 + 2];
+      d[i] = f[i * 5 + 3];
+      e[i] = f[i * 5 + 4];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+f6 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+    TYPE *__restrict g, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      a[i] = g[i * 6];
+      b[i] = g[i * 6 + 1];
+      c[i] = g[i * 6 + 2];
+      d[i] = g[i * 6 + 3];
+      e[i] = g[i * 6 + 4];
+      f[i] = g[i * 6 + 5];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+f7 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+    TYPE *__restrict g, TYPE *__restrict h, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      a[i] = h[i * 7];
+      b[i] = h[i * 7 + 1];
+      c[i] = h[i * 7 + 2];
+      d[i] = h[i * 7 + 3];
+      e[i] = h[i * 7 + 4];
+      f[i] = h[i * 7 + 5];
+      g[i] = h[i * 7 + 6];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+f8 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+    TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      a[i] = j[i * 8];
+      b[i] = j[i * 8 + 1];
+      c[i] = j[i * 8 + 2];
+      d[i] = j[i * 8 + 3];
+      e[i] = j[i * 8 + 4];
+      f[i] = j[i * 8 + 5];
+      g[i] = j[i * 8 + 6];
+      h[i] = j[i * 8 + 7];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+g2 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      c[i * 2] = a[i];
+      c[i * 2 + 1] = b[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+g3 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      d[i * 3] = a[i];
+      d[i * 3 + 1] = b[i];
+      d[i * 3 + 2] = c[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+g4 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      e[i * 4] = a[i];
+      e[i * 4 + 1] = b[i];
+      e[i * 4 + 2] = c[i];
+      e[i * 4 + 3] = d[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+g5 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      f[i * 5] = a[i];
+      f[i * 5 + 1] = b[i];
+      f[i * 5 + 2] = c[i];
+      f[i * 5 + 3] = d[i];
+      f[i * 5 + 4] = e[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+g6 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+    TYPE *__restrict g, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      g[i * 6] = a[i];
+      g[i * 6 + 1] = b[i];
+      g[i * 6 + 2] = c[i];
+      g[i * 6 + 3] = d[i];
+      g[i * 6 + 4] = e[i];
+      g[i * 6 + 5] = f[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+g7 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+    TYPE *__restrict g, TYPE *__restrict h, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      h[i * 7] = a[i];
+      h[i * 7 + 1] = b[i];
+      h[i * 7 + 2] = c[i];
+      h[i * 7 + 3] = d[i];
+      h[i * 7 + 4] = e[i];
+      h[i * 7 + 5] = f[i];
+      h[i * 7 + 6] = g[i];
+    }
+}
+
+void __attribute__ ((noinline, noclone))
+g8 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c,
+    TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f,
+    TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j, ITYPE n)
+{
+  for (ITYPE i = 0; i < n; ++i)
+    {
+      j[i * 8] = a[i];
+      j[i * 8 + 1] = b[i];
+      j[i * 8 + 2] = c[i];
+      j[i * 8 + 3] = d[i];
+      j[i * 8 + 4] = e[i];
+      j[i * 8 + 5] = f[i];
+      j[i * 8 + 6] = g[i];
+      j[i * 8 + 7] = h[i];
+    }
+}
+
+/* { dg-final { scan-assembler-times {vlseg2e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg5e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg6e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg7e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg8e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg2e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg3e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg4e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg5e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg6e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg7e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg8e8\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c
new file mode 100644
index 00000000000..dd01769d98d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE uint16_t
+#define ITYPE int16_t
+#include "struct_vect-6.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg5e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg6e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg7e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg8e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg2e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg3e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg4e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg5e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg6e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg7e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg8e16\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c
new file mode 100644
index 00000000000..bedf17a6ee0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE uint32_t
+#define ITYPE int32_t
+#include "struct_vect-6.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg5e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg6e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg7e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg8e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg2e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg3e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg4e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg5e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg6e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg7e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg8e32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c
new file mode 100644
index 00000000000..8b608224a4f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE uint64_t
+#define ITYPE int64_t
+#include "struct_vect-6.c"
+
+/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg5e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg6e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg7e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vlseg8e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg2e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg3e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg4e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg5e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg6e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg7e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsseg8e64\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c
new file mode 100644
index 00000000000..4807bebdd7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c
@@ -0,0 +1,139 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include "struct_vect-1.c"
+
+TYPE a[N], b[N], c[N], d[N], a2[N], b2[N], c2[N], d2[N], e[N * 8];
+
+void __attribute__ ((noinline, noclone))
+init_array (TYPE *array, int n, TYPE base, TYPE step)
+{
+  for (int i = 0; i < n; ++i)
+    array[i] = base + step * i;
+}
+
+void __attribute__ ((noinline, noclone))
+check_array (TYPE *array, int n, TYPE base, TYPE step)
+{
+  for (int i = 0; i < n; ++i)
+    if (array[i] != (TYPE) (base + step * i))
+      __builtin_abort ();
+}
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  init_array (e, 2 * N, 11, 5);
+  f2 (a, b, e);
+  check_array (a, N, 11, 10);
+  check_array (b, N, 16, 10);
+
+  init_array (e, 3 * N, 7, 6);
+  f3 (a, b, c, e);
+  check_array (a, N, 7, 18);
+  check_array (b, N, 13, 18);
+  check_array (c, N, 19, 18);
+
+  init_array (e, 4 * N, 4, 11);
+  f4 (a, b, c, d, e);
+  check_array (a, N, 4, 44);
+  check_array (b, N, 15, 44);
+  check_array (c, N, 26, 44);
+  check_array (d, N, 37, 44);
+
+  init_array (e, 5 * N, 3, 9);
+  f5 (a, b, c, d, a2, e);
+  check_array (a, N, 3, 45);
+  check_array (b, N, 12, 45);
+  check_array (c, N, 21, 45);
+  check_array (d, N, 30, 45);
+  check_array (a2, N, 39, 45);
+
+  init_array (e, 6 * N, 5, 5);
+  f6 (a, b, c, d, a2, b2, e);
+  check_array (a, N, 5, 30);
+  check_array (b, N, 10, 30);
+  check_array (c, N, 15, 30);
+  check_array (d, N, 20, 30);
+  check_array (a2, N, 25, 30);
+  check_array (b2, N, 30, 30);
+
+  init_array (e, 7 * N, 7, 3);
+  f7 (a, b, c, d, a2, b2, c2, e);
+  check_array (a, N, 7, 21);
+  check_array (b, N, 10, 21);
+  check_array (c, N, 13, 21);
+  check_array (d, N, 16, 21);
+  check_array (a2, N, 19, 21);
+  check_array (b2, N, 22, 21);
+  check_array (c2, N, 25, 21);
+
+  init_array (e, 8 * N, 5, 8);
+  f8 (a, b, c, d, a2, b2, c2, d2, e);
+  check_array (a, N, 5, 64);
+  check_array (b, N, 13, 64);
+  check_array (c, N, 21, 64);
+  check_array (d, N, 29, 64);
+  check_array (a2, N, 37, 64);
+  check_array (b2, N, 45, 64);
+  check_array (c2, N, 53, 64);
+  check_array (d2, N, 61, 64);
+
+  init_array (a, N, 2, 8);
+  init_array (b, N, 6, 8);
+  g2 (a, b, e);
+  check_array (e, 2 * N, 2, 4);
+
+  init_array (a, N, 4, 15);
+  init_array (b, N, 9, 15);
+  init_array (c, N, 14, 15);
+  g3 (a, b, c, e);
+  check_array (e, 3 * N, 4, 5);
+
+  init_array (a, N, 14, 36);
+  init_array (b, N, 23, 36);
+  init_array (c, N, 32, 36);
+  init_array (d, N, 41, 36);
+  g4 (a, b, c, d, e);
+  check_array (e, 4 * N, 14, 9);
+
+  init_array (a, N, 3, 45);
+  init_array (b, N, 12, 45);
+  init_array (c, N, 21, 45);
+  init_array (d, N, 30, 45);
+  init_array (a2, N, 39, 45);
+  g5 (a, b, c, d, a2, e);
+  check_array (e, 5 * N, 3, 9);
+
+  init_array (a, N, 5, 30);
+  init_array (b, N, 10, 30);
+  init_array (c, N, 15, 30);
+  init_array (d, N, 20, 30);
+  init_array (a2, N, 25, 30);
+  init_array (b2, N, 30, 30);
+  g6 (a, b, c, d, a2, b2, e);
+  check_array (e, 6 * N, 5, 5);
+
+  init_array (a, N, 7, 21);
+  init_array (b, N, 10, 21);
+  init_array (c, N, 13, 21);
+  init_array (d, N, 16, 21);
+  init_array (a2, N, 19, 21);
+  init_array (b2, N, 22, 21);
+  init_array (c2, N, 25, 21);
+  g7 (a, b, c, d, a2, b2, c2, e);
+  check_array (e, 7 * N, 7, 3);
+
+  init_array (a, N, 5, 64);
+  init_array (b, N, 13, 64);
+  init_array (c, N, 21, 64);
+  init_array (d, N, 29, 64);
+  init_array (a2, N, 37, 64);
+  init_array (b2, N, 45, 64);
+  init_array (c2, N, 53, 64);
+  init_array (d2, N, 61, 64);
+  g8 (a, b, c, d, a2, b2, c2, d2, e);
+  check_array (e, 8 * N, 5, 8);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c
new file mode 100644
index 00000000000..afebde162d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c
@@ -0,0 +1,6 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE _Float16
+#define ITYPE int16_t
+#include "struct_vect_run-6.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c
new file mode 100644
index 00000000000..8d311b45eb4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c
@@ -0,0 +1,6 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE float
+#define ITYPE int32_t
+#include "struct_vect_run-6.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c
new file mode 100644
index 00000000000..763aa9e6f58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c
@@ -0,0 +1,6 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE double
+#define ITYPE int64_t
+#include "struct_vect_run-6.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c
new file mode 100644
index 00000000000..e1824e912bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "struct_vect-13.c"
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, TYPE)				\
+  {							\
+    TYPE out[N];					\
+    TYPE in[N * 3];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 3; ++i)			\
+      {							\
+	in[i] = i * 9 / 2;				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    NAME (out, in);					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	TYPE expected = i * 7 / 2 + in[i * 3];		\
+	if (out[i] != expected)				\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c
new file mode 100644
index 00000000000..6b23023a918
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "struct_vect-14.c"
+
+#define N 1000
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, TYPE)			\
+  {						\
+    TYPE out[N];				\
+    TYPE in[N * 3];				\
+    int counts[] = { 0, 1, N - 1 };		\
+    for (int j = 0; j < 3; ++j)			\
+      {						\
+	int count = counts[j];			\
+	for (int i = 0; i < N; ++i)		\
+	  {					\
+	    out[i] = i * 7 / 2;			\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+	for (int i = 0; i < N * 3; ++i)		\
+	  {					\
+	    in[i] = i * 9 / 2;			\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+	NAME (out, in, count);			\
+	for (int i = 0; i < N; ++i)		\
+	  {					\
+	    TYPE expected = i * 7 / 2;		\
+	    if (i < count)			\
+	      expected += in[i * 3];		\
+	    if (out[i] != expected)		\
+	      __builtin_abort ();		\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+      }						\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c
new file mode 100644
index 00000000000..92eadd6fd45
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "struct_vect-15.c"
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, TYPE)				\
+  {							\
+    TYPE out[N];					\
+    TYPE in[N * 2];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 2; ++i)			\
+      {							\
+	in[i] = i * 9 / 2;				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    NAME (out, in);					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	TYPE expected = i * 7 / 2 + in[i * 2];		\
+	if (out[i] != expected)				\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c
new file mode 100644
index 00000000000..f43e06c46fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "struct_vect-16.c"
+
+#define N 1000
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, TYPE)			\
+  {						\
+    TYPE out[N];				\
+    TYPE in[N * 2];				\
+    int counts[] = { 0, 1, N - 1 };		\
+    for (int j = 0; j < 3; ++j)			\
+      {						\
+	int count = counts[j];			\
+	for (int i = 0; i < N; ++i)		\
+	  {					\
+	    out[i] = i * 7 / 2;			\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+	for (int i = 0; i < N * 2; ++i)		\
+	  {					\
+	    in[i] = i * 9 / 2;			\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+	NAME (out, in, count);			\
+	for (int i = 0; i < N; ++i)		\
+	  {					\
+	    TYPE expected = i * 7 / 2;		\
+	    if (i < count)			\
+	      expected += in[i * 2];		\
+	    if (out[i] != expected)		\
+	      __builtin_abort ();		\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+      }						\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c
new file mode 100644
index 00000000000..b0bafb1cece
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c
@@ -0,0 +1,36 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "struct_vect-17.c"
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, TYPE)				\
+  {							\
+    TYPE out[N];					\
+    TYPE in[N * 4];					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	out[i] = i * 7 / 2;				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    for (int i = 0; i < N * 4; ++i)			\
+      {							\
+	in[i] = i * 9 / 2;				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+    NAME (out, in);					\
+    for (int i = 0; i < N; ++i)				\
+      {							\
+	TYPE expected = i * 7 / 2 + in[i * 4];		\
+	if (out[i] != expected)				\
+	  __builtin_abort ();				\
+	asm volatile ("" ::: "memory");			\
+      }							\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c
new file mode 100644
index 00000000000..169974cc0a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "struct_vect-18.c"
+
+#define N 1000
+
+#undef TEST_LOOP
+#define TEST_LOOP(NAME, TYPE)			\
+  {						\
+    TYPE out[N];				\
+    TYPE in[N * 4];				\
+    int counts[] = { 0, 1, N - 1 };		\
+    for (int j = 0; j < 3; ++j)			\
+      {						\
+	int count = counts[j];			\
+	for (int i = 0; i < N; ++i)		\
+	  {					\
+	    out[i] = i * 7 / 2;			\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+	for (int i = 0; i < N * 4; ++i)		\
+	  {					\
+	    in[i] = i * 9 / 2;			\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+	NAME (out, in, count);			\
+	for (int i = 0; i < N; ++i)		\
+	  {					\
+	    TYPE expected = i * 7 / 2;		\
+	    if (i < count)			\
+	      expected += in[i * 4];		\
+	    if (out[i] != expected)		\
+	      __builtin_abort ();		\
+	    asm volatile ("" ::: "memory");	\
+	  }					\
+      }						\
+  }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  TEST (test);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c
new file mode 100644
index 00000000000..ab26245241c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c
@@ -0,0 +1,5 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE uint16_t
+#include "struct_vect_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c
new file mode 100644
index 00000000000..a2b2e818327
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c
@@ -0,0 +1,5 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE uint32_t
+#include "struct_vect_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c
new file mode 100644
index 00000000000..4e4ddb3b39f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c
@@ -0,0 +1,5 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE uint64_t
+#include "struct_vect_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c
new file mode 100644
index 00000000000..2fa48f1ce3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c
@@ -0,0 +1,5 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */
+
+#define TYPE float
+#include "struct_vect_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c
new file mode 100644
index 00000000000..7146042c404
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c
@@ -0,0 +1,141 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "struct_vect-6.c"
+
+#define N 93
+
+TYPE a[N], b[N], c[N], d[N], a2[N], b2[N], c2[N], d2[N], e[N * 8];
+
+void __attribute__ ((noinline, noclone))
+init_array (TYPE *array, int n, TYPE base, TYPE step)
+{
+  for (int i = 0; i < n; ++i)
+    array[i] = base + step * i;
+}
+
+void __attribute__ ((noinline, noclone))
+check_array (TYPE *array, int n, TYPE base, TYPE step)
+{
+  for (int i = 0; i < n; ++i)
+    if (array[i] != (TYPE) (base + step * i))
+      __builtin_abort ();
+}
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+  init_array (e, 2 * N, 11, 5);
+  f2 (a, b, e, N);
+  check_array (a, N, 11, 10);
+  check_array (b, N, 16, 10);
+
+  init_array (e, 3 * N, 7, 6);
+  f3 (a, b, c, e, N);
+  check_array (a, N, 7, 18);
+  check_array (b, N, 13, 18);
+  check_array (c, N, 19, 18);
+
+  init_array (e, 4 * N, 4, 11);
+  f4 (a, b, c, d, e, N);
+  check_array (a, N, 4, 44);
+  check_array (b, N, 15, 44);
+  check_array (c, N, 26, 44);
+  check_array (d, N, 37, 44);
+
+  init_array (e, 5 * N, 3, 9);
+  f5 (a, b, c, d, a2, e, N);
+  check_array (a, N, 3, 45);
+  check_array (b, N, 12, 45);
+  check_array (c, N, 21, 45);
+  check_array (d, N, 30, 45);
+  check_array (a2, N, 39, 45);
+
+  init_array (e, 6 * N, 5, 5);
+  f6 (a, b, c, d, a2, b2, e, N);
+  check_array (a, N, 5, 30);
+  check_array (b, N, 10, 30);
+  check_array (c, N, 15, 30);
+  check_array (d, N, 20, 30);
+  check_array (a2, N, 25, 30);
+  check_array (b2, N, 30, 30);
+
+  init_array (e, 7 * N, 7, 3);
+  f7 (a, b, c, d, a2, b2, c2, e, N);
+  check_array (a, N, 7, 21);
+  check_array (b, N, 10, 21);
+  check_array (c, N, 13, 21);
+  check_array (d, N, 16, 21);
+  check_array (a2, N, 19, 21);
+  check_array (b2, N, 22, 21);
+  check_array (c2, N, 25, 21);
+
+  init_array (e, 8 * N, 5, 8);
+  f8 (a, b, c, d, a2, b2, c2, d2, e, N);
+  check_array (a, N, 5, 64);
+  check_array (b, N, 13, 64);
+  check_array (c, N, 21, 64);
+  check_array (d, N, 29, 64);
+  check_array (a2, N, 37, 64);
+  check_array (b2, N, 45, 64);
+  check_array (c2, N, 53, 64);
+  check_array (d2, N, 61, 64);
+
+  init_array (a, N, 2, 8);
+  init_array (b, N, 6, 8);
+  g2 (a, b, e, N);
+  check_array (e, 2 * N, 2, 4);
+
+  init_array (a, N, 4, 15);
+  init_array (b, N, 9, 15);
+  init_array (c, N, 14, 15);
+  g3 (a, b, c, e, N);
+  check_array (e, 3 * N, 4, 5);
+
+  init_array (a, N, 14, 36);
+  init_array (b, N, 23, 36);
+  init_array (c, N, 32, 36);
+  init_array (d, N, 41, 36);
+  g4 (a, b, c, d, e, N);
+  check_array (e, 4 * N, 14, 9);
+
+  init_array (a, N, 3, 45);
+  init_array (b, N, 12, 45);
+  init_array (c, N, 21, 45);
+  init_array (d, N, 30, 45);
+  init_array (a2, N, 39, 45);
+  g5 (a, b, c, d, a2, e, N);
+  check_array (e, 5 * N, 3, 9);
+
+  init_array (a, N, 5, 30);
+  init_array (b, N, 10, 30);
+  init_array (c, N, 15, 30);
+  init_array (d, N, 20, 30);
+  init_array (a2, N, 25, 30);
+  init_array (b2, N, 30, 30);
+  g6 (a, b, c, d, a2, b2, e, N);
+  check_array (e, 6 * N, 5, 5);
+
+  init_array (a, N, 7, 21);
+  init_array (b, N, 10, 21);
+  init_array (c, N, 13, 21);
+  init_array (d, N, 16, 21);
+  init_array (a2, N, 19, 21);
+  init_array (b2, N, 22, 21);
+  init_array (c2, N, 25, 21);
+  g7 (a, b, c, d, a2, b2, c2, e, N);
+  check_array (e, 7 * N, 7, 3);
+
+  init_array (a, N, 5, 64);
+  init_array (b, N, 13, 64);
+  init_array (c, N, 21, 64);
+  init_array (d, N, 29, 64);
+  init_array (a2, N, 37, 64);
+  init_array (b2, N, 45, 64);
+  init_array (c2, N, 53, 64);
+  init_array (d2, N, 61, 64);
+  g8 (a, b, c, d, a2, b2, c2, d2, e, N);
+  check_array (e, 8 * N, 5, 8);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c
new file mode 100644
index 00000000000..73e74493bd2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c
@@ -0,0 +1,6 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE uint16_t
+#define ITYPE int16_t
+#include "struct_vect_run-6.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c
new file mode 100644
index 00000000000..383a6c68621
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c
@@ -0,0 +1,6 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE uint32_t
+#define ITYPE int32_t
+#include "struct_vect_run-6.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c
new file mode 100644
index 00000000000..79b5df73559
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c
@@ -0,0 +1,6 @@ 
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define TYPE uint64_t
+#define ITYPE int64_t
+#include "struct_vect_run-6.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
index 1bc53cef891..ff76e17d0e6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
@@ -50,6 +50,8 @@  dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/*.\[cS\]]] \
 	"-O3 -ftree-vectorize" $CFLAGS
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/vls/*.\[cS\]]] \
 	"-O3 -ftree-vectorize --param riscv-autovec-preference=scalable" $CFLAGS
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/struct/*.\[cS\]]] \
+	"" "-O3 -ftree-vectorize"
 
 set AUTOVEC_TEST_OPTS [list \
   {-ftree-vectorize -O3 --param riscv-autovec-lmul=m1} \