diff mbox series

RISC-V: Support VLS modes reduction[PR111153]

Message ID 20230917020549.973008-1-juzhe.zhong@rivai.ai
State New
Headers show
Series RISC-V: Support VLS modes reduction[PR111153] | expand

Commit Message

juzhe.zhong@rivai.ai Sept. 17, 2023, 2:05 a.m. UTC
This patch supports VLS reduction vectorization.

It can optimize the current reduction vectorization codegen with current COST model.

#define DEF_REDUC_PLUS(TYPE)			\
TYPE __attribute__ ((noinline, noclone))	\
reduc_plus_##TYPE (TYPE * __restrict a, int n)		\
{						\
  TYPE r = 0;					\
  for (int i = 0; i < n; ++i)			\
    r += a[i];					\
  return r;					\
}

#define TEST_PLUS(T)				\
  T (int32_t)					\

TEST_PLUS (DEF_REDUC_PLUS)


Before this patch:

        vle32.v v2,0(a5)
        addi    a5,a5,16
        vadd.vv v1,v1,v2
        bne     a5,a4,.L4
        lui     a4,%hi(.LC0)
        lui     a5,%hi(.LC1)
        addi    a4,a4,%lo(.LC0)
        vlm.v   v0,0(a4)
        addi    a5,a5,%lo(.LC1)
        andi    a1,a1,-4
        vmv1r.v v2,v3
        vlm.v   v4,0(a5)
        vcompress.vm    v2,v1,v0
        vmv1r.v v0,v4
        vadd.vv v1,v2,v1
        vcompress.vm    v3,v1,v0
        vadd.vv v3,v3,v1
        vmv.x.s a0,v3
        sext.w  a0,a0
        beq     a3,a1,.L12

After this patch:

	vle32.v	v2,0(a5)
	addi	a5,a5,16
	vadd.vv	v1,v1,v2
	bne	a5,a4,.L4
	li	a5,0
	andi	a1,a1,-4
	vmv.s.x	v2,a5
	vredsum.vs	v1,v1,v2
	vmv.x.s	a0,v1
	beq	a3,a1,.L12

gcc/ChangeLog:

	* config/riscv/autovec.md: Add VLS modes.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/autovec/vls/def.h: Add VLS mode reduction case.
	* gcc.target/riscv/rvv/autovec/vls/reduc-1.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-10.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-11.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-12.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-13.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-14.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-15.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-16.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-17.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-18.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-19.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-2.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-20.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-21.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-3.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-4.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-5.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-6.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-7.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-8.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/reduc-9.c: New test.

---
 gcc/config/riscv/autovec.md                   |  2 +-
 .../gcc.target/riscv/rvv/autovec/vls/def.h    | 30 +++++++
 .../riscv/rvv/autovec/vls/reduc-1.c           | 31 +++++++
 .../riscv/rvv/autovec/vls/reduc-10.c          | 50 ++++++++++++
 .../riscv/rvv/autovec/vls/reduc-11.c          | 46 +++++++++++
 .../riscv/rvv/autovec/vls/reduc-12.c          | 30 +++++++
 .../riscv/rvv/autovec/vls/reduc-13.c          | 28 +++++++
 .../riscv/rvv/autovec/vls/reduc-14.c          | 26 ++++++
 .../riscv/rvv/autovec/vls/reduc-15.c          | 81 +++++++++++++++++++
 .../riscv/rvv/autovec/vls/reduc-16.c          | 75 +++++++++++++++++
 .../riscv/rvv/autovec/vls/reduc-17.c          | 69 ++++++++++++++++
 .../riscv/rvv/autovec/vls/reduc-18.c          | 63 +++++++++++++++
 .../riscv/rvv/autovec/vls/reduc-19.c          | 18 +++++
 .../riscv/rvv/autovec/vls/reduc-2.c           | 29 +++++++
 .../riscv/rvv/autovec/vls/reduc-20.c          | 17 ++++
 .../riscv/rvv/autovec/vls/reduc-21.c          | 16 ++++
 .../riscv/rvv/autovec/vls/reduc-3.c           | 27 +++++++
 .../riscv/rvv/autovec/vls/reduc-4.c           | 25 ++++++
 .../riscv/rvv/autovec/vls/reduc-5.c           | 18 +++++
 .../riscv/rvv/autovec/vls/reduc-6.c           | 17 ++++
 .../riscv/rvv/autovec/vls/reduc-7.c           | 16 ++++
 .../riscv/rvv/autovec/vls/reduc-8.c           | 58 +++++++++++++
 .../riscv/rvv/autovec/vls/reduc-9.c           | 54 +++++++++++++
 23 files changed, 825 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c

Comments

Kito Cheng Sept. 18, 2023, 8:19 a.m. UTC | #1
LGTM

On Sun, Sep 17, 2023 at 10:07 AM Juzhe-Zhong <juzhe.zhong@rivai.ai> wrote:
>
> This patch supports VLS reduction vectorization.
>
> It can optimize the current reduction vectorization codegen with current COST model.
>
> #define DEF_REDUC_PLUS(TYPE)                    \
> TYPE __attribute__ ((noinline, noclone))        \
> reduc_plus_##TYPE (TYPE * __restrict a, int n)          \
> {                                               \
>   TYPE r = 0;                                   \
>   for (int i = 0; i < n; ++i)                   \
>     r += a[i];                                  \
>   return r;                                     \
> }
>
> #define TEST_PLUS(T)                            \
>   T (int32_t)                                   \
>
> TEST_PLUS (DEF_REDUC_PLUS)
>
>
> Before this patch:
>
>         vle32.v v2,0(a5)
>         addi    a5,a5,16
>         vadd.vv v1,v1,v2
>         bne     a5,a4,.L4
>         lui     a4,%hi(.LC0)
>         lui     a5,%hi(.LC1)
>         addi    a4,a4,%lo(.LC0)
>         vlm.v   v0,0(a4)
>         addi    a5,a5,%lo(.LC1)
>         andi    a1,a1,-4
>         vmv1r.v v2,v3
>         vlm.v   v4,0(a5)
>         vcompress.vm    v2,v1,v0
>         vmv1r.v v0,v4
>         vadd.vv v1,v2,v1
>         vcompress.vm    v3,v1,v0
>         vadd.vv v3,v3,v1
>         vmv.x.s a0,v3
>         sext.w  a0,a0
>         beq     a3,a1,.L12
>
> After this patch:
>
>         vle32.v v2,0(a5)
>         addi    a5,a5,16
>         vadd.vv v1,v1,v2
>         bne     a5,a4,.L4
>         li      a5,0
>         andi    a1,a1,-4
>         vmv.s.x v2,a5
>         vredsum.vs      v1,v1,v2
>         vmv.x.s a0,v1
>         beq     a3,a1,.L12
>
> gcc/ChangeLog:
>
>         * config/riscv/autovec.md: Add VLS modes.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/autovec/vls/def.h: Add VLS mode reduction case.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-1.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-10.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-11.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-12.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-13.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-14.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-15.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-16.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-17.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-18.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-19.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-2.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-20.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-21.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-3.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-4.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-5.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-6.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-7.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-8.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-9.c: New test.
>
> ---
>  gcc/config/riscv/autovec.md                   |  2 +-
>  .../gcc.target/riscv/rvv/autovec/vls/def.h    | 30 +++++++
>  .../riscv/rvv/autovec/vls/reduc-1.c           | 31 +++++++
>  .../riscv/rvv/autovec/vls/reduc-10.c          | 50 ++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-11.c          | 46 +++++++++++
>  .../riscv/rvv/autovec/vls/reduc-12.c          | 30 +++++++
>  .../riscv/rvv/autovec/vls/reduc-13.c          | 28 +++++++
>  .../riscv/rvv/autovec/vls/reduc-14.c          | 26 ++++++
>  .../riscv/rvv/autovec/vls/reduc-15.c          | 81 +++++++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-16.c          | 75 +++++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-17.c          | 69 ++++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-18.c          | 63 +++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-19.c          | 18 +++++
>  .../riscv/rvv/autovec/vls/reduc-2.c           | 29 +++++++
>  .../riscv/rvv/autovec/vls/reduc-20.c          | 17 ++++
>  .../riscv/rvv/autovec/vls/reduc-21.c          | 16 ++++
>  .../riscv/rvv/autovec/vls/reduc-3.c           | 27 +++++++
>  .../riscv/rvv/autovec/vls/reduc-4.c           | 25 ++++++
>  .../riscv/rvv/autovec/vls/reduc-5.c           | 18 +++++
>  .../riscv/rvv/autovec/vls/reduc-6.c           | 17 ++++
>  .../riscv/rvv/autovec/vls/reduc-7.c           | 16 ++++
>  .../riscv/rvv/autovec/vls/reduc-8.c           | 58 +++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-9.c           | 54 +++++++++++++
>  23 files changed, 825 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
>
> diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
> index 479d89939ec..8d3ad9f3add 100644
> --- a/gcc/config/riscv/autovec.md
> +++ b/gcc/config/riscv/autovec.md
> @@ -2241,7 +2241,7 @@
>  (define_insn_and_split "fold_left_plus_<mode>"
>    [(set (match_operand:<VEL> 0 "register_operand")
>          (unspec:<VEL> [
> -             (match_operand:VF 2 "register_operand")
> +             (match_operand:V_VLSF 2 "register_operand")
>               (match_operand:<VEL> 1 "register_operand")
>          ] UNSPEC_REDUC_SUM_ORDERED))]
>    "TARGET_VECTOR && can_create_pseudo_p ()"
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
> index 81c4570836b..9ede7affd11 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
> @@ -266,3 +266,33 @@ typedef double v512df __attribute__ ((vector_size (4096)));
>      for (int i = 0; i < NUM; ++i)                                              \
>        a[i] = b[i] * CALL (1.0, c[i]);                                          \
>    }
> +
> +#define DEF_REDUC_PLUS(TYPE, NUM)                                              \
> +  TYPE __attribute__ ((noinline, noclone))                                     \
> +  reduc_plus_##TYPE##NUM (TYPE *__restrict a)                                  \
> +  {                                                                            \
> +    TYPE r = 0;                                                                \
> +    for (int i = 0; i < NUM; ++i)                                              \
> +      r += a[i];                                                               \
> +    return r;                                                                  \
> +  }
> +
> +#define DEF_REDUC_MAXMIN(TYPE, NAME, CMP_OP, NUM)                              \
> +  TYPE __attribute__ ((noinline, noclone))                                     \
> +  reduc_##NAME##_##TYPE##_##NUM (TYPE *a)                                      \
> +  {                                                                            \
> +    TYPE r = 13;                                                               \
> +    for (int i = 0; i < NUM; ++i)                                              \
> +      r = a[i] CMP_OP r ? a[i] : r;                                            \
> +    return r;                                                                  \
> +  }
> +
> +#define DEF_REDUC_BITWISE(TYPE, NAME, BIT_OP, NUM)                             \
> +  TYPE __attribute__ ((noinline, noclone))                                     \
> +  reduc_##NAME##_##TYPE##_##NUM (TYPE *a)                                      \
> +  {                                                                            \
> +    TYPE r = 13;                                                               \
> +    for (int i = 0; i < NUM; ++i)                                              \
> +      r BIT_OP a[i];                                                           \
> +    return r;                                                                  \
> +  }
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
> new file mode 100644
> index 00000000000..2db25a2b05d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
> @@ -0,0 +1,31 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int8_t, 4)
> +DEF_REDUC_PLUS (int8_t, 8)
> +DEF_REDUC_PLUS (int8_t, 16)
> +DEF_REDUC_PLUS (int8_t, 32)
> +DEF_REDUC_PLUS (int8_t, 64)
> +DEF_REDUC_PLUS (int8_t, 128)
> +DEF_REDUC_PLUS (int8_t, 256)
> +DEF_REDUC_PLUS (int8_t, 512)
> +DEF_REDUC_PLUS (int8_t, 1024)
> +DEF_REDUC_PLUS (int8_t, 2048)
> +DEF_REDUC_PLUS (int8_t, 4096)
> +
> +DEF_REDUC_PLUS (uint8_t, 4)
> +DEF_REDUC_PLUS (uint8_t, 8)
> +DEF_REDUC_PLUS (uint8_t, 16)
> +DEF_REDUC_PLUS (uint8_t, 32)
> +DEF_REDUC_PLUS (uint8_t, 64)
> +DEF_REDUC_PLUS (uint8_t, 128)
> +DEF_REDUC_PLUS (uint8_t, 256)
> +DEF_REDUC_PLUS (uint8_t, 512)
> +DEF_REDUC_PLUS (uint8_t, 1024)
> +DEF_REDUC_PLUS (uint8_t, 2048)
> +DEF_REDUC_PLUS (uint8_t, 4096)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 22 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
> new file mode 100644
> index 00000000000..cdbbe11f611
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
> @@ -0,0 +1,50 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int32_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 512)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 1024)
> +
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 512)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 1024)
> +
> +DEF_REDUC_MAXMIN (int32_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 512)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 1024)
> +
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 512)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 1024)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
> new file mode 100644
> index 00000000000..d2040315d32
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
> @@ -0,0 +1,46 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int64_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 512)
> +
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 512)
> +
> +DEF_REDUC_MAXMIN (int64_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 512)
> +
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 512)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
> new file mode 100644
> index 00000000000..97660d223f7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (_Float16, max, >, 4)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 8)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 16)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 32)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 64)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 128)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 256)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 512)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 1024)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 2048)
> +
> +DEF_REDUC_MAXMIN (_Float16, min, <, 4)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 8)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 16)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 32)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 64)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 128)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 256)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 512)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 1024)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 2048)
> +
> +/* { dg-final { scan-assembler-times {vfredmax\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vfredmin\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
> new file mode 100644
> index 00000000000..e4bc95cc326
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (float, max, >, 4)
> +DEF_REDUC_MAXMIN (float, max, >, 8)
> +DEF_REDUC_MAXMIN (float, max, >, 16)
> +DEF_REDUC_MAXMIN (float, max, >, 32)
> +DEF_REDUC_MAXMIN (float, max, >, 64)
> +DEF_REDUC_MAXMIN (float, max, >, 128)
> +DEF_REDUC_MAXMIN (float, max, >, 256)
> +DEF_REDUC_MAXMIN (float, max, >, 512)
> +DEF_REDUC_MAXMIN (float, max, >, 1024)
> +
> +DEF_REDUC_MAXMIN (float, min, <, 4)
> +DEF_REDUC_MAXMIN (float, min, <, 8)
> +DEF_REDUC_MAXMIN (float, min, <, 16)
> +DEF_REDUC_MAXMIN (float, min, <, 32)
> +DEF_REDUC_MAXMIN (float, min, <, 64)
> +DEF_REDUC_MAXMIN (float, min, <, 128)
> +DEF_REDUC_MAXMIN (float, min, <, 256)
> +DEF_REDUC_MAXMIN (float, min, <, 512)
> +DEF_REDUC_MAXMIN (float, min, <, 1024)
> +
> +/* { dg-final { scan-assembler-times {vfredmax\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vfredmin\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
> new file mode 100644
> index 00000000000..c90e9266280
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (double, max, >, 4)
> +DEF_REDUC_MAXMIN (double, max, >, 8)
> +DEF_REDUC_MAXMIN (double, max, >, 16)
> +DEF_REDUC_MAXMIN (double, max, >, 32)
> +DEF_REDUC_MAXMIN (double, max, >, 64)
> +DEF_REDUC_MAXMIN (double, max, >, 128)
> +DEF_REDUC_MAXMIN (double, max, >, 256)
> +DEF_REDUC_MAXMIN (double, max, >, 512)
> +
> +DEF_REDUC_MAXMIN (double, min, <, 4)
> +DEF_REDUC_MAXMIN (double, min, <, 8)
> +DEF_REDUC_MAXMIN (double, min, <, 16)
> +DEF_REDUC_MAXMIN (double, min, <, 32)
> +DEF_REDUC_MAXMIN (double, min, <, 64)
> +DEF_REDUC_MAXMIN (double, min, <, 128)
> +DEF_REDUC_MAXMIN (double, min, <, 256)
> +DEF_REDUC_MAXMIN (double, min, <, 512)
> +
> +/* { dg-final { scan-assembler-times {vfredmax\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vfredmin\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
> new file mode 100644
> index 00000000000..65863f7e5fe
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
> @@ -0,0 +1,81 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int8_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 512)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 2048)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 4096)
> +
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 512)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 2048)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 4096)
> +
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 2048)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 4096)
> +
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 2048)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 4096)
> +
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 2048)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 4096)
> +
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 2048)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 4096)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 22 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 22 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 22 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
> new file mode 100644
> index 00000000000..c6c57146ecd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int16_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 512)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 2048)
> +
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 512)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 2048)
> +
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 2048)
> +
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 2048)
> +
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 2048)
> +
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 2048)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 20 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 20 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 20 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
> new file mode 100644
> index 00000000000..75983076ace
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int32_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 512)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 1024)
> +
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 512)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 1024)
> +
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 1024)
> +
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 1024)
> +
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 1024)
> +
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 1024)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 18 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 18 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 18 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
> new file mode 100644
> index 00000000000..30dfad6708c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
> @@ -0,0 +1,63 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int64_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 512)
> +
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 512)
> +
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 512)
> +
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 512)
> +
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 512)
> +
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 512)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 16 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 16 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 16 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
> new file mode 100644
> index 00000000000..a2de4d10d4e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (_Float16, 4)
> +DEF_REDUC_PLUS (_Float16, 8)
> +DEF_REDUC_PLUS (_Float16, 16)
> +DEF_REDUC_PLUS (_Float16, 32)
> +DEF_REDUC_PLUS (_Float16, 64)
> +DEF_REDUC_PLUS (_Float16, 128)
> +DEF_REDUC_PLUS (_Float16, 256)
> +DEF_REDUC_PLUS (_Float16, 512)
> +DEF_REDUC_PLUS (_Float16, 1024)
> +DEF_REDUC_PLUS (_Float16, 2048)
> +
> +/* { dg-final { scan-assembler-times {vfredosum\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
> new file mode 100644
> index 00000000000..9ffdec94865
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int16_t, 4)
> +DEF_REDUC_PLUS (int16_t, 8)
> +DEF_REDUC_PLUS (int16_t, 16)
> +DEF_REDUC_PLUS (int16_t, 32)
> +DEF_REDUC_PLUS (int16_t, 64)
> +DEF_REDUC_PLUS (int16_t, 128)
> +DEF_REDUC_PLUS (int16_t, 256)
> +DEF_REDUC_PLUS (int16_t, 512)
> +DEF_REDUC_PLUS (int16_t, 1024)
> +DEF_REDUC_PLUS (int16_t, 2048)
> +
> +DEF_REDUC_PLUS (uint16_t, 4)
> +DEF_REDUC_PLUS (uint16_t, 8)
> +DEF_REDUC_PLUS (uint16_t, 16)
> +DEF_REDUC_PLUS (uint16_t, 32)
> +DEF_REDUC_PLUS (uint16_t, 64)
> +DEF_REDUC_PLUS (uint16_t, 128)
> +DEF_REDUC_PLUS (uint16_t, 256)
> +DEF_REDUC_PLUS (uint16_t, 512)
> +DEF_REDUC_PLUS (uint16_t, 1024)
> +DEF_REDUC_PLUS (uint16_t, 2048)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 20 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
> new file mode 100644
> index 00000000000..8e1164a6dc2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (float, 4)
> +DEF_REDUC_PLUS (float, 8)
> +DEF_REDUC_PLUS (float, 16)
> +DEF_REDUC_PLUS (float, 32)
> +DEF_REDUC_PLUS (float, 64)
> +DEF_REDUC_PLUS (float, 128)
> +DEF_REDUC_PLUS (float, 256)
> +DEF_REDUC_PLUS (float, 512)
> +DEF_REDUC_PLUS (float, 1024)
> +
> +/* { dg-final { scan-assembler-times {vfredosum\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
> new file mode 100644
> index 00000000000..727cf85224d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (float, 4)
> +DEF_REDUC_PLUS (float, 8)
> +DEF_REDUC_PLUS (float, 16)
> +DEF_REDUC_PLUS (float, 32)
> +DEF_REDUC_PLUS (float, 64)
> +DEF_REDUC_PLUS (float, 128)
> +DEF_REDUC_PLUS (float, 256)
> +DEF_REDUC_PLUS (float, 512)
> +
> +/* { dg-final { scan-assembler-times {vfredosum\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
> new file mode 100644
> index 00000000000..63f9697e245
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int32_t, 4)
> +DEF_REDUC_PLUS (int32_t, 8)
> +DEF_REDUC_PLUS (int32_t, 16)
> +DEF_REDUC_PLUS (int32_t, 32)
> +DEF_REDUC_PLUS (int32_t, 64)
> +DEF_REDUC_PLUS (int32_t, 128)
> +DEF_REDUC_PLUS (int32_t, 256)
> +DEF_REDUC_PLUS (int32_t, 512)
> +DEF_REDUC_PLUS (int32_t, 1024)
> +
> +DEF_REDUC_PLUS (uint32_t, 4)
> +DEF_REDUC_PLUS (uint32_t, 8)
> +DEF_REDUC_PLUS (uint32_t, 16)
> +DEF_REDUC_PLUS (uint32_t, 32)
> +DEF_REDUC_PLUS (uint32_t, 64)
> +DEF_REDUC_PLUS (uint32_t, 128)
> +DEF_REDUC_PLUS (uint32_t, 256)
> +DEF_REDUC_PLUS (uint32_t, 512)
> +DEF_REDUC_PLUS (uint32_t, 1024)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 18 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
> new file mode 100644
> index 00000000000..8cd2728d236
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int64_t, 4)
> +DEF_REDUC_PLUS (int64_t, 8)
> +DEF_REDUC_PLUS (int64_t, 16)
> +DEF_REDUC_PLUS (int64_t, 32)
> +DEF_REDUC_PLUS (int64_t, 64)
> +DEF_REDUC_PLUS (int64_t, 128)
> +DEF_REDUC_PLUS (int64_t, 256)
> +DEF_REDUC_PLUS (int64_t, 512)
> +
> +DEF_REDUC_PLUS (uint64_t, 4)
> +DEF_REDUC_PLUS (uint64_t, 8)
> +DEF_REDUC_PLUS (uint64_t, 16)
> +DEF_REDUC_PLUS (uint64_t, 32)
> +DEF_REDUC_PLUS (uint64_t, 64)
> +DEF_REDUC_PLUS (uint64_t, 128)
> +DEF_REDUC_PLUS (uint64_t, 256)
> +DEF_REDUC_PLUS (uint64_t, 512)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 16 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
> new file mode 100644
> index 00000000000..09b69fc92db
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (_Float16, 4)
> +DEF_REDUC_PLUS (_Float16, 8)
> +DEF_REDUC_PLUS (_Float16, 16)
> +DEF_REDUC_PLUS (_Float16, 32)
> +DEF_REDUC_PLUS (_Float16, 64)
> +DEF_REDUC_PLUS (_Float16, 128)
> +DEF_REDUC_PLUS (_Float16, 256)
> +DEF_REDUC_PLUS (_Float16, 512)
> +DEF_REDUC_PLUS (_Float16, 1024)
> +DEF_REDUC_PLUS (_Float16, 2048)
> +
> +/* { dg-final { scan-assembler-times {vfredusum\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
> new file mode 100644
> index 00000000000..56b13dc221e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (float, 4)
> +DEF_REDUC_PLUS (float, 8)
> +DEF_REDUC_PLUS (float, 16)
> +DEF_REDUC_PLUS (float, 32)
> +DEF_REDUC_PLUS (float, 64)
> +DEF_REDUC_PLUS (float, 128)
> +DEF_REDUC_PLUS (float, 256)
> +DEF_REDUC_PLUS (float, 512)
> +DEF_REDUC_PLUS (float, 1024)
> +
> +/* { dg-final { scan-assembler-times {vfredusum\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
> new file mode 100644
> index 00000000000..eb5de35df12
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (double, 4)
> +DEF_REDUC_PLUS (double, 8)
> +DEF_REDUC_PLUS (double, 16)
> +DEF_REDUC_PLUS (double, 32)
> +DEF_REDUC_PLUS (double, 64)
> +DEF_REDUC_PLUS (double, 128)
> +DEF_REDUC_PLUS (double, 256)
> +DEF_REDUC_PLUS (double, 512)
> +
> +/* { dg-final { scan-assembler-times {vfredusum\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
> new file mode 100644
> index 00000000000..cf4f9cc9f2a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
> @@ -0,0 +1,58 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int8_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 512)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 2048)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 4096)
> +
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 512)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 2048)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 4096)
> +
> +DEF_REDUC_MAXMIN (int8_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 512)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 2048)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 4096)
> +
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 512)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 2048)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 4096)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 11 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 11 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 11 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 11 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
> new file mode 100644
> index 00000000000..64164586ef6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
> @@ -0,0 +1,54 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int16_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 512)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 2048)
> +
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 512)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 2048)
> +
> +DEF_REDUC_MAXMIN (int16_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 512)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 2048)
> +
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 512)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 2048)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> --
> 2.36.3
>
Li, Pan2 via Gcc-patches Sept. 18, 2023, 8:25 a.m. UTC | #2
Committed, thanks Kito.

Pan

-----Original Message-----
From: Gcc-patches <gcc-patches-bounces+pan2.li=intel.com@gcc.gnu.org> On Behalf Of Kito Cheng via Gcc-patches
Sent: Monday, September 18, 2023 4:20 PM
To: Juzhe-Zhong <juzhe.zhong@rivai.ai>
Cc: gcc-patches@gcc.gnu.org; kito.cheng@sifive.com; jeffreyalaw@gmail.com; rdapp.gcc@gmail.com
Subject: Re: [PATCH] RISC-V: Support VLS modes reduction[PR111153]

LGTM

On Sun, Sep 17, 2023 at 10:07 AM Juzhe-Zhong <juzhe.zhong@rivai.ai> wrote:
>
> This patch supports VLS reduction vectorization.
>
> It can optimize the current reduction vectorization codegen with current COST model.
>
> #define DEF_REDUC_PLUS(TYPE)                    \
> TYPE __attribute__ ((noinline, noclone))        \
> reduc_plus_##TYPE (TYPE * __restrict a, int n)          \
> {                                               \
>   TYPE r = 0;                                   \
>   for (int i = 0; i < n; ++i)                   \
>     r += a[i];                                  \
>   return r;                                     \
> }
>
> #define TEST_PLUS(T)                            \
>   T (int32_t)                                   \
>
> TEST_PLUS (DEF_REDUC_PLUS)
>
>
> Before this patch:
>
>         vle32.v v2,0(a5)
>         addi    a5,a5,16
>         vadd.vv v1,v1,v2
>         bne     a5,a4,.L4
>         lui     a4,%hi(.LC0)
>         lui     a5,%hi(.LC1)
>         addi    a4,a4,%lo(.LC0)
>         vlm.v   v0,0(a4)
>         addi    a5,a5,%lo(.LC1)
>         andi    a1,a1,-4
>         vmv1r.v v2,v3
>         vlm.v   v4,0(a5)
>         vcompress.vm    v2,v1,v0
>         vmv1r.v v0,v4
>         vadd.vv v1,v2,v1
>         vcompress.vm    v3,v1,v0
>         vadd.vv v3,v3,v1
>         vmv.x.s a0,v3
>         sext.w  a0,a0
>         beq     a3,a1,.L12
>
> After this patch:
>
>         vle32.v v2,0(a5)
>         addi    a5,a5,16
>         vadd.vv v1,v1,v2
>         bne     a5,a4,.L4
>         li      a5,0
>         andi    a1,a1,-4
>         vmv.s.x v2,a5
>         vredsum.vs      v1,v1,v2
>         vmv.x.s a0,v1
>         beq     a3,a1,.L12
>
> gcc/ChangeLog:
>
>         * config/riscv/autovec.md: Add VLS modes.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/autovec/vls/def.h: Add VLS mode reduction case.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-1.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-10.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-11.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-12.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-13.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-14.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-15.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-16.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-17.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-18.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-19.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-2.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-20.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-21.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-3.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-4.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-5.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-6.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-7.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-8.c: New test.
>         * gcc.target/riscv/rvv/autovec/vls/reduc-9.c: New test.
>
> ---
>  gcc/config/riscv/autovec.md                   |  2 +-
>  .../gcc.target/riscv/rvv/autovec/vls/def.h    | 30 +++++++
>  .../riscv/rvv/autovec/vls/reduc-1.c           | 31 +++++++
>  .../riscv/rvv/autovec/vls/reduc-10.c          | 50 ++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-11.c          | 46 +++++++++++
>  .../riscv/rvv/autovec/vls/reduc-12.c          | 30 +++++++
>  .../riscv/rvv/autovec/vls/reduc-13.c          | 28 +++++++
>  .../riscv/rvv/autovec/vls/reduc-14.c          | 26 ++++++
>  .../riscv/rvv/autovec/vls/reduc-15.c          | 81 +++++++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-16.c          | 75 +++++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-17.c          | 69 ++++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-18.c          | 63 +++++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-19.c          | 18 +++++
>  .../riscv/rvv/autovec/vls/reduc-2.c           | 29 +++++++
>  .../riscv/rvv/autovec/vls/reduc-20.c          | 17 ++++
>  .../riscv/rvv/autovec/vls/reduc-21.c          | 16 ++++
>  .../riscv/rvv/autovec/vls/reduc-3.c           | 27 +++++++
>  .../riscv/rvv/autovec/vls/reduc-4.c           | 25 ++++++
>  .../riscv/rvv/autovec/vls/reduc-5.c           | 18 +++++
>  .../riscv/rvv/autovec/vls/reduc-6.c           | 17 ++++
>  .../riscv/rvv/autovec/vls/reduc-7.c           | 16 ++++
>  .../riscv/rvv/autovec/vls/reduc-8.c           | 58 +++++++++++++
>  .../riscv/rvv/autovec/vls/reduc-9.c           | 54 +++++++++++++
>  23 files changed, 825 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
>
> diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
> index 479d89939ec..8d3ad9f3add 100644
> --- a/gcc/config/riscv/autovec.md
> +++ b/gcc/config/riscv/autovec.md
> @@ -2241,7 +2241,7 @@
>  (define_insn_and_split "fold_left_plus_<mode>"
>    [(set (match_operand:<VEL> 0 "register_operand")
>          (unspec:<VEL> [
> -             (match_operand:VF 2 "register_operand")
> +             (match_operand:V_VLSF 2 "register_operand")
>               (match_operand:<VEL> 1 "register_operand")
>          ] UNSPEC_REDUC_SUM_ORDERED))]
>    "TARGET_VECTOR && can_create_pseudo_p ()"
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
> index 81c4570836b..9ede7affd11 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
> @@ -266,3 +266,33 @@ typedef double v512df __attribute__ ((vector_size (4096)));
>      for (int i = 0; i < NUM; ++i)                                              \
>        a[i] = b[i] * CALL (1.0, c[i]);                                          \
>    }
> +
> +#define DEF_REDUC_PLUS(TYPE, NUM)                                              \
> +  TYPE __attribute__ ((noinline, noclone))                                     \
> +  reduc_plus_##TYPE##NUM (TYPE *__restrict a)                                  \
> +  {                                                                            \
> +    TYPE r = 0;                                                                \
> +    for (int i = 0; i < NUM; ++i)                                              \
> +      r += a[i];                                                               \
> +    return r;                                                                  \
> +  }
> +
> +#define DEF_REDUC_MAXMIN(TYPE, NAME, CMP_OP, NUM)                              \
> +  TYPE __attribute__ ((noinline, noclone))                                     \
> +  reduc_##NAME##_##TYPE##_##NUM (TYPE *a)                                      \
> +  {                                                                            \
> +    TYPE r = 13;                                                               \
> +    for (int i = 0; i < NUM; ++i)                                              \
> +      r = a[i] CMP_OP r ? a[i] : r;                                            \
> +    return r;                                                                  \
> +  }
> +
> +#define DEF_REDUC_BITWISE(TYPE, NAME, BIT_OP, NUM)                             \
> +  TYPE __attribute__ ((noinline, noclone))                                     \
> +  reduc_##NAME##_##TYPE##_##NUM (TYPE *a)                                      \
> +  {                                                                            \
> +    TYPE r = 13;                                                               \
> +    for (int i = 0; i < NUM; ++i)                                              \
> +      r BIT_OP a[i];                                                           \
> +    return r;                                                                  \
> +  }
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
> new file mode 100644
> index 00000000000..2db25a2b05d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
> @@ -0,0 +1,31 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int8_t, 4)
> +DEF_REDUC_PLUS (int8_t, 8)
> +DEF_REDUC_PLUS (int8_t, 16)
> +DEF_REDUC_PLUS (int8_t, 32)
> +DEF_REDUC_PLUS (int8_t, 64)
> +DEF_REDUC_PLUS (int8_t, 128)
> +DEF_REDUC_PLUS (int8_t, 256)
> +DEF_REDUC_PLUS (int8_t, 512)
> +DEF_REDUC_PLUS (int8_t, 1024)
> +DEF_REDUC_PLUS (int8_t, 2048)
> +DEF_REDUC_PLUS (int8_t, 4096)
> +
> +DEF_REDUC_PLUS (uint8_t, 4)
> +DEF_REDUC_PLUS (uint8_t, 8)
> +DEF_REDUC_PLUS (uint8_t, 16)
> +DEF_REDUC_PLUS (uint8_t, 32)
> +DEF_REDUC_PLUS (uint8_t, 64)
> +DEF_REDUC_PLUS (uint8_t, 128)
> +DEF_REDUC_PLUS (uint8_t, 256)
> +DEF_REDUC_PLUS (uint8_t, 512)
> +DEF_REDUC_PLUS (uint8_t, 1024)
> +DEF_REDUC_PLUS (uint8_t, 2048)
> +DEF_REDUC_PLUS (uint8_t, 4096)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 22 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
> new file mode 100644
> index 00000000000..cdbbe11f611
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
> @@ -0,0 +1,50 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int32_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 512)
> +DEF_REDUC_MAXMIN (int32_t, max, >, 1024)
> +
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 512)
> +DEF_REDUC_MAXMIN (uint32_t, max, >, 1024)
> +
> +DEF_REDUC_MAXMIN (int32_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 512)
> +DEF_REDUC_MAXMIN (int32_t, min, <, 1024)
> +
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 512)
> +DEF_REDUC_MAXMIN (uint32_t, min, <, 1024)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
> new file mode 100644
> index 00000000000..d2040315d32
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
> @@ -0,0 +1,46 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int64_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int64_t, max, >, 512)
> +
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint64_t, max, >, 512)
> +
> +DEF_REDUC_MAXMIN (int64_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int64_t, min, <, 512)
> +
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint64_t, min, <, 512)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
> new file mode 100644
> index 00000000000..97660d223f7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (_Float16, max, >, 4)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 8)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 16)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 32)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 64)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 128)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 256)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 512)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 1024)
> +DEF_REDUC_MAXMIN (_Float16, max, >, 2048)
> +
> +DEF_REDUC_MAXMIN (_Float16, min, <, 4)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 8)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 16)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 32)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 64)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 128)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 256)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 512)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 1024)
> +DEF_REDUC_MAXMIN (_Float16, min, <, 2048)
> +
> +/* { dg-final { scan-assembler-times {vfredmax\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vfredmin\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
> new file mode 100644
> index 00000000000..e4bc95cc326
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
> @@ -0,0 +1,28 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (float, max, >, 4)
> +DEF_REDUC_MAXMIN (float, max, >, 8)
> +DEF_REDUC_MAXMIN (float, max, >, 16)
> +DEF_REDUC_MAXMIN (float, max, >, 32)
> +DEF_REDUC_MAXMIN (float, max, >, 64)
> +DEF_REDUC_MAXMIN (float, max, >, 128)
> +DEF_REDUC_MAXMIN (float, max, >, 256)
> +DEF_REDUC_MAXMIN (float, max, >, 512)
> +DEF_REDUC_MAXMIN (float, max, >, 1024)
> +
> +DEF_REDUC_MAXMIN (float, min, <, 4)
> +DEF_REDUC_MAXMIN (float, min, <, 8)
> +DEF_REDUC_MAXMIN (float, min, <, 16)
> +DEF_REDUC_MAXMIN (float, min, <, 32)
> +DEF_REDUC_MAXMIN (float, min, <, 64)
> +DEF_REDUC_MAXMIN (float, min, <, 128)
> +DEF_REDUC_MAXMIN (float, min, <, 256)
> +DEF_REDUC_MAXMIN (float, min, <, 512)
> +DEF_REDUC_MAXMIN (float, min, <, 1024)
> +
> +/* { dg-final { scan-assembler-times {vfredmax\.vs} 9 } } */
> +/* { dg-final { scan-assembler-times {vfredmin\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
> new file mode 100644
> index 00000000000..c90e9266280
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (double, max, >, 4)
> +DEF_REDUC_MAXMIN (double, max, >, 8)
> +DEF_REDUC_MAXMIN (double, max, >, 16)
> +DEF_REDUC_MAXMIN (double, max, >, 32)
> +DEF_REDUC_MAXMIN (double, max, >, 64)
> +DEF_REDUC_MAXMIN (double, max, >, 128)
> +DEF_REDUC_MAXMIN (double, max, >, 256)
> +DEF_REDUC_MAXMIN (double, max, >, 512)
> +
> +DEF_REDUC_MAXMIN (double, min, <, 4)
> +DEF_REDUC_MAXMIN (double, min, <, 8)
> +DEF_REDUC_MAXMIN (double, min, <, 16)
> +DEF_REDUC_MAXMIN (double, min, <, 32)
> +DEF_REDUC_MAXMIN (double, min, <, 64)
> +DEF_REDUC_MAXMIN (double, min, <, 128)
> +DEF_REDUC_MAXMIN (double, min, <, 256)
> +DEF_REDUC_MAXMIN (double, min, <, 512)
> +
> +/* { dg-final { scan-assembler-times {vfredmax\.vs} 8 } } */
> +/* { dg-final { scan-assembler-times {vfredmin\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
> new file mode 100644
> index 00000000000..65863f7e5fe
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
> @@ -0,0 +1,81 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int8_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 512)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 2048)
> +DEF_REDUC_BITWISE (int8_t, and, &=, 4096)
> +
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 512)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 2048)
> +DEF_REDUC_BITWISE (uint8_t, and, &=, 4096)
> +
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 2048)
> +DEF_REDUC_BITWISE (int8_t, ior, |=, 4096)
> +
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 2048)
> +DEF_REDUC_BITWISE (uint8_t, ior, |=, 4096)
> +
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 2048)
> +DEF_REDUC_BITWISE (int8_t, xor, ^=, 4096)
> +
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 2048)
> +DEF_REDUC_BITWISE (uint8_t, xor, ^=, 4096)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 22 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 22 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 22 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
> new file mode 100644
> index 00000000000..c6c57146ecd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int16_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 512)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (int16_t, and, &=, 2048)
> +
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 512)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 1024)
> +DEF_REDUC_BITWISE (uint16_t, and, &=, 2048)
> +
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (int16_t, ior, |=, 2048)
> +
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 1024)
> +DEF_REDUC_BITWISE (uint16_t, ior, |=, 2048)
> +
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (int16_t, xor, ^=, 2048)
> +
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 1024)
> +DEF_REDUC_BITWISE (uint16_t, xor, ^=, 2048)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 20 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 20 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 20 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
> new file mode 100644
> index 00000000000..75983076ace
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int32_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 512)
> +DEF_REDUC_BITWISE (int32_t, and, &=, 1024)
> +
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 512)
> +DEF_REDUC_BITWISE (uint32_t, and, &=, 1024)
> +
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (int32_t, ior, |=, 1024)
> +
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 512)
> +DEF_REDUC_BITWISE (uint32_t, ior, |=, 1024)
> +
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (int32_t, xor, ^=, 1024)
> +
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 512)
> +DEF_REDUC_BITWISE (uint32_t, xor, ^=, 1024)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 18 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 18 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 18 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
> new file mode 100644
> index 00000000000..30dfad6708c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
> @@ -0,0 +1,63 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_BITWISE (int64_t, and, &=, 4)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 8)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 16)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 32)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 64)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 128)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 256)
> +DEF_REDUC_BITWISE (int64_t, and, &=, 512)
> +
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 4)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 8)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 16)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 32)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 64)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 128)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 256)
> +DEF_REDUC_BITWISE (uint64_t, and, &=, 512)
> +
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (int64_t, ior, |=, 512)
> +
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 4)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 8)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 16)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 32)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 64)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 128)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 256)
> +DEF_REDUC_BITWISE (uint64_t, ior, |=, 512)
> +
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (int64_t, xor, ^=, 512)
> +
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 4)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 8)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 16)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 32)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 64)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 128)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 256)
> +DEF_REDUC_BITWISE (uint64_t, xor, ^=, 512)
> +
> +/* { dg-final { scan-assembler-times {vredand\.vs} 16 } } */
> +/* { dg-final { scan-assembler-times {vredor\.vs} 16 } } */
> +/* { dg-final { scan-assembler-times {vredxor\.vs} 16 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
> new file mode 100644
> index 00000000000..a2de4d10d4e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (_Float16, 4)
> +DEF_REDUC_PLUS (_Float16, 8)
> +DEF_REDUC_PLUS (_Float16, 16)
> +DEF_REDUC_PLUS (_Float16, 32)
> +DEF_REDUC_PLUS (_Float16, 64)
> +DEF_REDUC_PLUS (_Float16, 128)
> +DEF_REDUC_PLUS (_Float16, 256)
> +DEF_REDUC_PLUS (_Float16, 512)
> +DEF_REDUC_PLUS (_Float16, 1024)
> +DEF_REDUC_PLUS (_Float16, 2048)
> +
> +/* { dg-final { scan-assembler-times {vfredosum\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
> new file mode 100644
> index 00000000000..9ffdec94865
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
> @@ -0,0 +1,29 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int16_t, 4)
> +DEF_REDUC_PLUS (int16_t, 8)
> +DEF_REDUC_PLUS (int16_t, 16)
> +DEF_REDUC_PLUS (int16_t, 32)
> +DEF_REDUC_PLUS (int16_t, 64)
> +DEF_REDUC_PLUS (int16_t, 128)
> +DEF_REDUC_PLUS (int16_t, 256)
> +DEF_REDUC_PLUS (int16_t, 512)
> +DEF_REDUC_PLUS (int16_t, 1024)
> +DEF_REDUC_PLUS (int16_t, 2048)
> +
> +DEF_REDUC_PLUS (uint16_t, 4)
> +DEF_REDUC_PLUS (uint16_t, 8)
> +DEF_REDUC_PLUS (uint16_t, 16)
> +DEF_REDUC_PLUS (uint16_t, 32)
> +DEF_REDUC_PLUS (uint16_t, 64)
> +DEF_REDUC_PLUS (uint16_t, 128)
> +DEF_REDUC_PLUS (uint16_t, 256)
> +DEF_REDUC_PLUS (uint16_t, 512)
> +DEF_REDUC_PLUS (uint16_t, 1024)
> +DEF_REDUC_PLUS (uint16_t, 2048)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 20 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
> new file mode 100644
> index 00000000000..8e1164a6dc2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (float, 4)
> +DEF_REDUC_PLUS (float, 8)
> +DEF_REDUC_PLUS (float, 16)
> +DEF_REDUC_PLUS (float, 32)
> +DEF_REDUC_PLUS (float, 64)
> +DEF_REDUC_PLUS (float, 128)
> +DEF_REDUC_PLUS (float, 256)
> +DEF_REDUC_PLUS (float, 512)
> +DEF_REDUC_PLUS (float, 1024)
> +
> +/* { dg-final { scan-assembler-times {vfredosum\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
> new file mode 100644
> index 00000000000..727cf85224d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (float, 4)
> +DEF_REDUC_PLUS (float, 8)
> +DEF_REDUC_PLUS (float, 16)
> +DEF_REDUC_PLUS (float, 32)
> +DEF_REDUC_PLUS (float, 64)
> +DEF_REDUC_PLUS (float, 128)
> +DEF_REDUC_PLUS (float, 256)
> +DEF_REDUC_PLUS (float, 512)
> +
> +/* { dg-final { scan-assembler-times {vfredosum\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
> new file mode 100644
> index 00000000000..63f9697e245
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int32_t, 4)
> +DEF_REDUC_PLUS (int32_t, 8)
> +DEF_REDUC_PLUS (int32_t, 16)
> +DEF_REDUC_PLUS (int32_t, 32)
> +DEF_REDUC_PLUS (int32_t, 64)
> +DEF_REDUC_PLUS (int32_t, 128)
> +DEF_REDUC_PLUS (int32_t, 256)
> +DEF_REDUC_PLUS (int32_t, 512)
> +DEF_REDUC_PLUS (int32_t, 1024)
> +
> +DEF_REDUC_PLUS (uint32_t, 4)
> +DEF_REDUC_PLUS (uint32_t, 8)
> +DEF_REDUC_PLUS (uint32_t, 16)
> +DEF_REDUC_PLUS (uint32_t, 32)
> +DEF_REDUC_PLUS (uint32_t, 64)
> +DEF_REDUC_PLUS (uint32_t, 128)
> +DEF_REDUC_PLUS (uint32_t, 256)
> +DEF_REDUC_PLUS (uint32_t, 512)
> +DEF_REDUC_PLUS (uint32_t, 1024)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 18 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
> new file mode 100644
> index 00000000000..8cd2728d236
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (int64_t, 4)
> +DEF_REDUC_PLUS (int64_t, 8)
> +DEF_REDUC_PLUS (int64_t, 16)
> +DEF_REDUC_PLUS (int64_t, 32)
> +DEF_REDUC_PLUS (int64_t, 64)
> +DEF_REDUC_PLUS (int64_t, 128)
> +DEF_REDUC_PLUS (int64_t, 256)
> +DEF_REDUC_PLUS (int64_t, 512)
> +
> +DEF_REDUC_PLUS (uint64_t, 4)
> +DEF_REDUC_PLUS (uint64_t, 8)
> +DEF_REDUC_PLUS (uint64_t, 16)
> +DEF_REDUC_PLUS (uint64_t, 32)
> +DEF_REDUC_PLUS (uint64_t, 64)
> +DEF_REDUC_PLUS (uint64_t, 128)
> +DEF_REDUC_PLUS (uint64_t, 256)
> +DEF_REDUC_PLUS (uint64_t, 512)
> +
> +/* { dg-final { scan-assembler-times {vredsum\.vs} 16 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
> new file mode 100644
> index 00000000000..09b69fc92db
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (_Float16, 4)
> +DEF_REDUC_PLUS (_Float16, 8)
> +DEF_REDUC_PLUS (_Float16, 16)
> +DEF_REDUC_PLUS (_Float16, 32)
> +DEF_REDUC_PLUS (_Float16, 64)
> +DEF_REDUC_PLUS (_Float16, 128)
> +DEF_REDUC_PLUS (_Float16, 256)
> +DEF_REDUC_PLUS (_Float16, 512)
> +DEF_REDUC_PLUS (_Float16, 1024)
> +DEF_REDUC_PLUS (_Float16, 2048)
> +
> +/* { dg-final { scan-assembler-times {vfredusum\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
> new file mode 100644
> index 00000000000..56b13dc221e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (float, 4)
> +DEF_REDUC_PLUS (float, 8)
> +DEF_REDUC_PLUS (float, 16)
> +DEF_REDUC_PLUS (float, 32)
> +DEF_REDUC_PLUS (float, 64)
> +DEF_REDUC_PLUS (float, 128)
> +DEF_REDUC_PLUS (float, 256)
> +DEF_REDUC_PLUS (float, 512)
> +DEF_REDUC_PLUS (float, 1024)
> +
> +/* { dg-final { scan-assembler-times {vfredusum\.vs} 9 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
> new file mode 100644
> index 00000000000..eb5de35df12
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_PLUS (double, 4)
> +DEF_REDUC_PLUS (double, 8)
> +DEF_REDUC_PLUS (double, 16)
> +DEF_REDUC_PLUS (double, 32)
> +DEF_REDUC_PLUS (double, 64)
> +DEF_REDUC_PLUS (double, 128)
> +DEF_REDUC_PLUS (double, 256)
> +DEF_REDUC_PLUS (double, 512)
> +
> +/* { dg-final { scan-assembler-times {vfredusum\.vs} 8 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
> new file mode 100644
> index 00000000000..cf4f9cc9f2a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
> @@ -0,0 +1,58 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int8_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 512)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 2048)
> +DEF_REDUC_MAXMIN (int8_t, max, >, 4096)
> +
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 512)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 2048)
> +DEF_REDUC_MAXMIN (uint8_t, max, >, 4096)
> +
> +DEF_REDUC_MAXMIN (int8_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 512)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 2048)
> +DEF_REDUC_MAXMIN (int8_t, min, <, 4096)
> +
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 512)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 2048)
> +DEF_REDUC_MAXMIN (uint8_t, min, <, 4096)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 11 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 11 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 11 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 11 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
> new file mode 100644
> index 00000000000..64164586ef6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
> @@ -0,0 +1,54 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
> +
> +#include "def.h"
> +
> +DEF_REDUC_MAXMIN (int16_t, max, >, 4)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 8)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 16)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 32)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 64)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 128)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 256)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 512)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (int16_t, max, >, 2048)
> +
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 4)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 8)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 16)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 32)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 64)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 128)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 256)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 512)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 1024)
> +DEF_REDUC_MAXMIN (uint16_t, max, >, 2048)
> +
> +DEF_REDUC_MAXMIN (int16_t, min, <, 4)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 8)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 16)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 32)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 64)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 128)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 256)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 512)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (int16_t, min, <, 2048)
> +
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 4)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 8)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 16)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 32)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 64)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 128)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 256)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 512)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 1024)
> +DEF_REDUC_MAXMIN (uint16_t, min, <, 2048)
> +
> +/* { dg-final { scan-assembler-times {vredmax\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vredmaxu\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vredmin\.vs} 10 } } */
> +/* { dg-final { scan-assembler-times {vredminu\.vs} 10 } } */
> +/* { dg-final { scan-assembler-not {csrr} } } */
> --
> 2.36.3
>
diff mbox series

Patch

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 479d89939ec..8d3ad9f3add 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -2241,7 +2241,7 @@ 
 (define_insn_and_split "fold_left_plus_<mode>"
   [(set (match_operand:<VEL> 0 "register_operand")
         (unspec:<VEL> [
-             (match_operand:VF 2 "register_operand")
+             (match_operand:V_VLSF 2 "register_operand")
              (match_operand:<VEL> 1 "register_operand")
         ] UNSPEC_REDUC_SUM_ORDERED))]
   "TARGET_VECTOR && can_create_pseudo_p ()"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
index 81c4570836b..9ede7affd11 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/def.h
@@ -266,3 +266,33 @@  typedef double v512df __attribute__ ((vector_size (4096)));
     for (int i = 0; i < NUM; ++i)                                              \
       a[i] = b[i] * CALL (1.0, c[i]);                                          \
   }
+
+#define DEF_REDUC_PLUS(TYPE, NUM)                                              \
+  TYPE __attribute__ ((noinline, noclone))                                     \
+  reduc_plus_##TYPE##NUM (TYPE *__restrict a)                                  \
+  {                                                                            \
+    TYPE r = 0;                                                                \
+    for (int i = 0; i < NUM; ++i)                                              \
+      r += a[i];                                                               \
+    return r;                                                                  \
+  }
+
+#define DEF_REDUC_MAXMIN(TYPE, NAME, CMP_OP, NUM)                              \
+  TYPE __attribute__ ((noinline, noclone))                                     \
+  reduc_##NAME##_##TYPE##_##NUM (TYPE *a)                                      \
+  {                                                                            \
+    TYPE r = 13;                                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      r = a[i] CMP_OP r ? a[i] : r;                                            \
+    return r;                                                                  \
+  }
+
+#define DEF_REDUC_BITWISE(TYPE, NAME, BIT_OP, NUM)                             \
+  TYPE __attribute__ ((noinline, noclone))                                     \
+  reduc_##NAME##_##TYPE##_##NUM (TYPE *a)                                      \
+  {                                                                            \
+    TYPE r = 13;                                                               \
+    for (int i = 0; i < NUM; ++i)                                              \
+      r BIT_OP a[i];                                                           \
+    return r;                                                                  \
+  }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
new file mode 100644
index 00000000000..2db25a2b05d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-1.c
@@ -0,0 +1,31 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (int8_t, 4)
+DEF_REDUC_PLUS (int8_t, 8)
+DEF_REDUC_PLUS (int8_t, 16)
+DEF_REDUC_PLUS (int8_t, 32)
+DEF_REDUC_PLUS (int8_t, 64)
+DEF_REDUC_PLUS (int8_t, 128)
+DEF_REDUC_PLUS (int8_t, 256)
+DEF_REDUC_PLUS (int8_t, 512)
+DEF_REDUC_PLUS (int8_t, 1024)
+DEF_REDUC_PLUS (int8_t, 2048)
+DEF_REDUC_PLUS (int8_t, 4096)
+
+DEF_REDUC_PLUS (uint8_t, 4)
+DEF_REDUC_PLUS (uint8_t, 8)
+DEF_REDUC_PLUS (uint8_t, 16)
+DEF_REDUC_PLUS (uint8_t, 32)
+DEF_REDUC_PLUS (uint8_t, 64)
+DEF_REDUC_PLUS (uint8_t, 128)
+DEF_REDUC_PLUS (uint8_t, 256)
+DEF_REDUC_PLUS (uint8_t, 512)
+DEF_REDUC_PLUS (uint8_t, 1024)
+DEF_REDUC_PLUS (uint8_t, 2048)
+DEF_REDUC_PLUS (uint8_t, 4096)
+
+/* { dg-final { scan-assembler-times {vredsum\.vs} 22 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
new file mode 100644
index 00000000000..cdbbe11f611
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-10.c
@@ -0,0 +1,50 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_MAXMIN (int32_t, max, >, 4)
+DEF_REDUC_MAXMIN (int32_t, max, >, 8)
+DEF_REDUC_MAXMIN (int32_t, max, >, 16)
+DEF_REDUC_MAXMIN (int32_t, max, >, 32)
+DEF_REDUC_MAXMIN (int32_t, max, >, 64)
+DEF_REDUC_MAXMIN (int32_t, max, >, 128)
+DEF_REDUC_MAXMIN (int32_t, max, >, 256)
+DEF_REDUC_MAXMIN (int32_t, max, >, 512)
+DEF_REDUC_MAXMIN (int32_t, max, >, 1024)
+
+DEF_REDUC_MAXMIN (uint32_t, max, >, 4)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 8)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 16)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 32)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 64)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 128)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 256)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 512)
+DEF_REDUC_MAXMIN (uint32_t, max, >, 1024)
+
+DEF_REDUC_MAXMIN (int32_t, min, <, 4)
+DEF_REDUC_MAXMIN (int32_t, min, <, 8)
+DEF_REDUC_MAXMIN (int32_t, min, <, 16)
+DEF_REDUC_MAXMIN (int32_t, min, <, 32)
+DEF_REDUC_MAXMIN (int32_t, min, <, 64)
+DEF_REDUC_MAXMIN (int32_t, min, <, 128)
+DEF_REDUC_MAXMIN (int32_t, min, <, 256)
+DEF_REDUC_MAXMIN (int32_t, min, <, 512)
+DEF_REDUC_MAXMIN (int32_t, min, <, 1024)
+
+DEF_REDUC_MAXMIN (uint32_t, min, <, 4)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 8)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 16)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 32)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 64)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 128)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 256)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 512)
+DEF_REDUC_MAXMIN (uint32_t, min, <, 1024)
+
+/* { dg-final { scan-assembler-times {vredmax\.vs} 9 } } */
+/* { dg-final { scan-assembler-times {vredmaxu\.vs} 9 } } */
+/* { dg-final { scan-assembler-times {vredmin\.vs} 9 } } */
+/* { dg-final { scan-assembler-times {vredminu\.vs} 9 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
new file mode 100644
index 00000000000..d2040315d32
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-11.c
@@ -0,0 +1,46 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_MAXMIN (int64_t, max, >, 4)
+DEF_REDUC_MAXMIN (int64_t, max, >, 8)
+DEF_REDUC_MAXMIN (int64_t, max, >, 16)
+DEF_REDUC_MAXMIN (int64_t, max, >, 32)
+DEF_REDUC_MAXMIN (int64_t, max, >, 64)
+DEF_REDUC_MAXMIN (int64_t, max, >, 128)
+DEF_REDUC_MAXMIN (int64_t, max, >, 256)
+DEF_REDUC_MAXMIN (int64_t, max, >, 512)
+
+DEF_REDUC_MAXMIN (uint64_t, max, >, 4)
+DEF_REDUC_MAXMIN (uint64_t, max, >, 8)
+DEF_REDUC_MAXMIN (uint64_t, max, >, 16)
+DEF_REDUC_MAXMIN (uint64_t, max, >, 32)
+DEF_REDUC_MAXMIN (uint64_t, max, >, 64)
+DEF_REDUC_MAXMIN (uint64_t, max, >, 128)
+DEF_REDUC_MAXMIN (uint64_t, max, >, 256)
+DEF_REDUC_MAXMIN (uint64_t, max, >, 512)
+
+DEF_REDUC_MAXMIN (int64_t, min, <, 4)
+DEF_REDUC_MAXMIN (int64_t, min, <, 8)
+DEF_REDUC_MAXMIN (int64_t, min, <, 16)
+DEF_REDUC_MAXMIN (int64_t, min, <, 32)
+DEF_REDUC_MAXMIN (int64_t, min, <, 64)
+DEF_REDUC_MAXMIN (int64_t, min, <, 128)
+DEF_REDUC_MAXMIN (int64_t, min, <, 256)
+DEF_REDUC_MAXMIN (int64_t, min, <, 512)
+
+DEF_REDUC_MAXMIN (uint64_t, min, <, 4)
+DEF_REDUC_MAXMIN (uint64_t, min, <, 8)
+DEF_REDUC_MAXMIN (uint64_t, min, <, 16)
+DEF_REDUC_MAXMIN (uint64_t, min, <, 32)
+DEF_REDUC_MAXMIN (uint64_t, min, <, 64)
+DEF_REDUC_MAXMIN (uint64_t, min, <, 128)
+DEF_REDUC_MAXMIN (uint64_t, min, <, 256)
+DEF_REDUC_MAXMIN (uint64_t, min, <, 512)
+
+/* { dg-final { scan-assembler-times {vredmax\.vs} 8 } } */
+/* { dg-final { scan-assembler-times {vredmaxu\.vs} 8 } } */
+/* { dg-final { scan-assembler-times {vredmin\.vs} 8 } } */
+/* { dg-final { scan-assembler-times {vredminu\.vs} 8 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
new file mode 100644
index 00000000000..97660d223f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-12.c
@@ -0,0 +1,30 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
+
+#include "def.h"
+
+DEF_REDUC_MAXMIN (_Float16, max, >, 4)
+DEF_REDUC_MAXMIN (_Float16, max, >, 8)
+DEF_REDUC_MAXMIN (_Float16, max, >, 16)
+DEF_REDUC_MAXMIN (_Float16, max, >, 32)
+DEF_REDUC_MAXMIN (_Float16, max, >, 64)
+DEF_REDUC_MAXMIN (_Float16, max, >, 128)
+DEF_REDUC_MAXMIN (_Float16, max, >, 256)
+DEF_REDUC_MAXMIN (_Float16, max, >, 512)
+DEF_REDUC_MAXMIN (_Float16, max, >, 1024)
+DEF_REDUC_MAXMIN (_Float16, max, >, 2048)
+
+DEF_REDUC_MAXMIN (_Float16, min, <, 4)
+DEF_REDUC_MAXMIN (_Float16, min, <, 8)
+DEF_REDUC_MAXMIN (_Float16, min, <, 16)
+DEF_REDUC_MAXMIN (_Float16, min, <, 32)
+DEF_REDUC_MAXMIN (_Float16, min, <, 64)
+DEF_REDUC_MAXMIN (_Float16, min, <, 128)
+DEF_REDUC_MAXMIN (_Float16, min, <, 256)
+DEF_REDUC_MAXMIN (_Float16, min, <, 512)
+DEF_REDUC_MAXMIN (_Float16, min, <, 1024)
+DEF_REDUC_MAXMIN (_Float16, min, <, 2048)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs} 10 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs} 10 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
new file mode 100644
index 00000000000..e4bc95cc326
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-13.c
@@ -0,0 +1,28 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
+
+#include "def.h"
+
+DEF_REDUC_MAXMIN (float, max, >, 4)
+DEF_REDUC_MAXMIN (float, max, >, 8)
+DEF_REDUC_MAXMIN (float, max, >, 16)
+DEF_REDUC_MAXMIN (float, max, >, 32)
+DEF_REDUC_MAXMIN (float, max, >, 64)
+DEF_REDUC_MAXMIN (float, max, >, 128)
+DEF_REDUC_MAXMIN (float, max, >, 256)
+DEF_REDUC_MAXMIN (float, max, >, 512)
+DEF_REDUC_MAXMIN (float, max, >, 1024)
+
+DEF_REDUC_MAXMIN (float, min, <, 4)
+DEF_REDUC_MAXMIN (float, min, <, 8)
+DEF_REDUC_MAXMIN (float, min, <, 16)
+DEF_REDUC_MAXMIN (float, min, <, 32)
+DEF_REDUC_MAXMIN (float, min, <, 64)
+DEF_REDUC_MAXMIN (float, min, <, 128)
+DEF_REDUC_MAXMIN (float, min, <, 256)
+DEF_REDUC_MAXMIN (float, min, <, 512)
+DEF_REDUC_MAXMIN (float, min, <, 1024)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs} 9 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs} 9 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
new file mode 100644
index 00000000000..c90e9266280
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-14.c
@@ -0,0 +1,26 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
+
+#include "def.h"
+
+DEF_REDUC_MAXMIN (double, max, >, 4)
+DEF_REDUC_MAXMIN (double, max, >, 8)
+DEF_REDUC_MAXMIN (double, max, >, 16)
+DEF_REDUC_MAXMIN (double, max, >, 32)
+DEF_REDUC_MAXMIN (double, max, >, 64)
+DEF_REDUC_MAXMIN (double, max, >, 128)
+DEF_REDUC_MAXMIN (double, max, >, 256)
+DEF_REDUC_MAXMIN (double, max, >, 512)
+
+DEF_REDUC_MAXMIN (double, min, <, 4)
+DEF_REDUC_MAXMIN (double, min, <, 8)
+DEF_REDUC_MAXMIN (double, min, <, 16)
+DEF_REDUC_MAXMIN (double, min, <, 32)
+DEF_REDUC_MAXMIN (double, min, <, 64)
+DEF_REDUC_MAXMIN (double, min, <, 128)
+DEF_REDUC_MAXMIN (double, min, <, 256)
+DEF_REDUC_MAXMIN (double, min, <, 512)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs} 8 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs} 8 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
new file mode 100644
index 00000000000..65863f7e5fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-15.c
@@ -0,0 +1,81 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_BITWISE (int8_t, and, &=, 4)
+DEF_REDUC_BITWISE (int8_t, and, &=, 8)
+DEF_REDUC_BITWISE (int8_t, and, &=, 16)
+DEF_REDUC_BITWISE (int8_t, and, &=, 32)
+DEF_REDUC_BITWISE (int8_t, and, &=, 64)
+DEF_REDUC_BITWISE (int8_t, and, &=, 128)
+DEF_REDUC_BITWISE (int8_t, and, &=, 256)
+DEF_REDUC_BITWISE (int8_t, and, &=, 512)
+DEF_REDUC_BITWISE (int8_t, and, &=, 1024)
+DEF_REDUC_BITWISE (int8_t, and, &=, 2048)
+DEF_REDUC_BITWISE (int8_t, and, &=, 4096)
+
+DEF_REDUC_BITWISE (uint8_t, and, &=, 4)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 8)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 16)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 32)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 64)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 128)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 256)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 512)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 1024)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 2048)
+DEF_REDUC_BITWISE (uint8_t, and, &=, 4096)
+
+DEF_REDUC_BITWISE (int8_t, ior, |=, 4)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 8)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 16)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 32)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 64)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 128)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 256)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 512)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 1024)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 2048)
+DEF_REDUC_BITWISE (int8_t, ior, |=, 4096)
+
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 4)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 8)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 16)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 32)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 64)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 128)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 256)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 512)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 1024)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 2048)
+DEF_REDUC_BITWISE (uint8_t, ior, |=, 4096)
+
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 512)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 1024)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 2048)
+DEF_REDUC_BITWISE (int8_t, xor, ^=, 4096)
+
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 512)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 1024)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 2048)
+DEF_REDUC_BITWISE (uint8_t, xor, ^=, 4096)
+
+/* { dg-final { scan-assembler-times {vredand\.vs} 22 } } */
+/* { dg-final { scan-assembler-times {vredor\.vs} 22 } } */
+/* { dg-final { scan-assembler-times {vredxor\.vs} 22 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
new file mode 100644
index 00000000000..c6c57146ecd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-16.c
@@ -0,0 +1,75 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_BITWISE (int16_t, and, &=, 4)
+DEF_REDUC_BITWISE (int16_t, and, &=, 8)
+DEF_REDUC_BITWISE (int16_t, and, &=, 16)
+DEF_REDUC_BITWISE (int16_t, and, &=, 32)
+DEF_REDUC_BITWISE (int16_t, and, &=, 64)
+DEF_REDUC_BITWISE (int16_t, and, &=, 128)
+DEF_REDUC_BITWISE (int16_t, and, &=, 256)
+DEF_REDUC_BITWISE (int16_t, and, &=, 512)
+DEF_REDUC_BITWISE (int16_t, and, &=, 1024)
+DEF_REDUC_BITWISE (int16_t, and, &=, 2048)
+
+DEF_REDUC_BITWISE (uint16_t, and, &=, 4)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 8)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 16)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 32)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 64)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 128)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 256)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 512)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 1024)
+DEF_REDUC_BITWISE (uint16_t, and, &=, 2048)
+
+DEF_REDUC_BITWISE (int16_t, ior, |=, 4)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 8)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 16)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 32)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 64)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 128)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 256)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 512)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 1024)
+DEF_REDUC_BITWISE (int16_t, ior, |=, 2048)
+
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 4)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 8)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 16)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 32)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 64)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 128)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 256)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 512)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 1024)
+DEF_REDUC_BITWISE (uint16_t, ior, |=, 2048)
+
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 512)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 1024)
+DEF_REDUC_BITWISE (int16_t, xor, ^=, 2048)
+
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 512)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 1024)
+DEF_REDUC_BITWISE (uint16_t, xor, ^=, 2048)
+
+/* { dg-final { scan-assembler-times {vredand\.vs} 20 } } */
+/* { dg-final { scan-assembler-times {vredor\.vs} 20 } } */
+/* { dg-final { scan-assembler-times {vredxor\.vs} 20 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
new file mode 100644
index 00000000000..75983076ace
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-17.c
@@ -0,0 +1,69 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_BITWISE (int32_t, and, &=, 4)
+DEF_REDUC_BITWISE (int32_t, and, &=, 8)
+DEF_REDUC_BITWISE (int32_t, and, &=, 16)
+DEF_REDUC_BITWISE (int32_t, and, &=, 32)
+DEF_REDUC_BITWISE (int32_t, and, &=, 64)
+DEF_REDUC_BITWISE (int32_t, and, &=, 128)
+DEF_REDUC_BITWISE (int32_t, and, &=, 256)
+DEF_REDUC_BITWISE (int32_t, and, &=, 512)
+DEF_REDUC_BITWISE (int32_t, and, &=, 1024)
+
+DEF_REDUC_BITWISE (uint32_t, and, &=, 4)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 8)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 16)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 32)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 64)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 128)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 256)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 512)
+DEF_REDUC_BITWISE (uint32_t, and, &=, 1024)
+
+DEF_REDUC_BITWISE (int32_t, ior, |=, 4)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 8)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 16)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 32)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 64)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 128)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 256)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 512)
+DEF_REDUC_BITWISE (int32_t, ior, |=, 1024)
+
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 4)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 8)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 16)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 32)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 64)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 128)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 256)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 512)
+DEF_REDUC_BITWISE (uint32_t, ior, |=, 1024)
+
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 512)
+DEF_REDUC_BITWISE (int32_t, xor, ^=, 1024)
+
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 512)
+DEF_REDUC_BITWISE (uint32_t, xor, ^=, 1024)
+
+/* { dg-final { scan-assembler-times {vredand\.vs} 18 } } */
+/* { dg-final { scan-assembler-times {vredor\.vs} 18 } } */
+/* { dg-final { scan-assembler-times {vredxor\.vs} 18 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
new file mode 100644
index 00000000000..30dfad6708c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-18.c
@@ -0,0 +1,63 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_BITWISE (int64_t, and, &=, 4)
+DEF_REDUC_BITWISE (int64_t, and, &=, 8)
+DEF_REDUC_BITWISE (int64_t, and, &=, 16)
+DEF_REDUC_BITWISE (int64_t, and, &=, 32)
+DEF_REDUC_BITWISE (int64_t, and, &=, 64)
+DEF_REDUC_BITWISE (int64_t, and, &=, 128)
+DEF_REDUC_BITWISE (int64_t, and, &=, 256)
+DEF_REDUC_BITWISE (int64_t, and, &=, 512)
+
+DEF_REDUC_BITWISE (uint64_t, and, &=, 4)
+DEF_REDUC_BITWISE (uint64_t, and, &=, 8)
+DEF_REDUC_BITWISE (uint64_t, and, &=, 16)
+DEF_REDUC_BITWISE (uint64_t, and, &=, 32)
+DEF_REDUC_BITWISE (uint64_t, and, &=, 64)
+DEF_REDUC_BITWISE (uint64_t, and, &=, 128)
+DEF_REDUC_BITWISE (uint64_t, and, &=, 256)
+DEF_REDUC_BITWISE (uint64_t, and, &=, 512)
+
+DEF_REDUC_BITWISE (int64_t, ior, |=, 4)
+DEF_REDUC_BITWISE (int64_t, ior, |=, 8)
+DEF_REDUC_BITWISE (int64_t, ior, |=, 16)
+DEF_REDUC_BITWISE (int64_t, ior, |=, 32)
+DEF_REDUC_BITWISE (int64_t, ior, |=, 64)
+DEF_REDUC_BITWISE (int64_t, ior, |=, 128)
+DEF_REDUC_BITWISE (int64_t, ior, |=, 256)
+DEF_REDUC_BITWISE (int64_t, ior, |=, 512)
+
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 4)
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 8)
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 16)
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 32)
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 64)
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 128)
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 256)
+DEF_REDUC_BITWISE (uint64_t, ior, |=, 512)
+
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (int64_t, xor, ^=, 512)
+
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 4)
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 8)
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 16)
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 32)
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 64)
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 128)
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 256)
+DEF_REDUC_BITWISE (uint64_t, xor, ^=, 512)
+
+/* { dg-final { scan-assembler-times {vredand\.vs} 16 } } */
+/* { dg-final { scan-assembler-times {vredor\.vs} 16 } } */
+/* { dg-final { scan-assembler-times {vredxor\.vs} 16 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
new file mode 100644
index 00000000000..a2de4d10d4e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-19.c
@@ -0,0 +1,18 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (_Float16, 4)
+DEF_REDUC_PLUS (_Float16, 8)
+DEF_REDUC_PLUS (_Float16, 16)
+DEF_REDUC_PLUS (_Float16, 32)
+DEF_REDUC_PLUS (_Float16, 64)
+DEF_REDUC_PLUS (_Float16, 128)
+DEF_REDUC_PLUS (_Float16, 256)
+DEF_REDUC_PLUS (_Float16, 512)
+DEF_REDUC_PLUS (_Float16, 1024)
+DEF_REDUC_PLUS (_Float16, 2048)
+
+/* { dg-final { scan-assembler-times {vfredosum\.vs} 10 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
new file mode 100644
index 00000000000..9ffdec94865
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-2.c
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (int16_t, 4)
+DEF_REDUC_PLUS (int16_t, 8)
+DEF_REDUC_PLUS (int16_t, 16)
+DEF_REDUC_PLUS (int16_t, 32)
+DEF_REDUC_PLUS (int16_t, 64)
+DEF_REDUC_PLUS (int16_t, 128)
+DEF_REDUC_PLUS (int16_t, 256)
+DEF_REDUC_PLUS (int16_t, 512)
+DEF_REDUC_PLUS (int16_t, 1024)
+DEF_REDUC_PLUS (int16_t, 2048)
+
+DEF_REDUC_PLUS (uint16_t, 4)
+DEF_REDUC_PLUS (uint16_t, 8)
+DEF_REDUC_PLUS (uint16_t, 16)
+DEF_REDUC_PLUS (uint16_t, 32)
+DEF_REDUC_PLUS (uint16_t, 64)
+DEF_REDUC_PLUS (uint16_t, 128)
+DEF_REDUC_PLUS (uint16_t, 256)
+DEF_REDUC_PLUS (uint16_t, 512)
+DEF_REDUC_PLUS (uint16_t, 1024)
+DEF_REDUC_PLUS (uint16_t, 2048)
+
+/* { dg-final { scan-assembler-times {vredsum\.vs} 20 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
new file mode 100644
index 00000000000..8e1164a6dc2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-20.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (float, 4)
+DEF_REDUC_PLUS (float, 8)
+DEF_REDUC_PLUS (float, 16)
+DEF_REDUC_PLUS (float, 32)
+DEF_REDUC_PLUS (float, 64)
+DEF_REDUC_PLUS (float, 128)
+DEF_REDUC_PLUS (float, 256)
+DEF_REDUC_PLUS (float, 512)
+DEF_REDUC_PLUS (float, 1024)
+
+/* { dg-final { scan-assembler-times {vfredosum\.vs} 9 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
new file mode 100644
index 00000000000..727cf85224d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-21.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (float, 4)
+DEF_REDUC_PLUS (float, 8)
+DEF_REDUC_PLUS (float, 16)
+DEF_REDUC_PLUS (float, 32)
+DEF_REDUC_PLUS (float, 64)
+DEF_REDUC_PLUS (float, 128)
+DEF_REDUC_PLUS (float, 256)
+DEF_REDUC_PLUS (float, 512)
+
+/* { dg-final { scan-assembler-times {vfredosum\.vs} 8 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
new file mode 100644
index 00000000000..63f9697e245
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-3.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (int32_t, 4)
+DEF_REDUC_PLUS (int32_t, 8)
+DEF_REDUC_PLUS (int32_t, 16)
+DEF_REDUC_PLUS (int32_t, 32)
+DEF_REDUC_PLUS (int32_t, 64)
+DEF_REDUC_PLUS (int32_t, 128)
+DEF_REDUC_PLUS (int32_t, 256)
+DEF_REDUC_PLUS (int32_t, 512)
+DEF_REDUC_PLUS (int32_t, 1024)
+
+DEF_REDUC_PLUS (uint32_t, 4)
+DEF_REDUC_PLUS (uint32_t, 8)
+DEF_REDUC_PLUS (uint32_t, 16)
+DEF_REDUC_PLUS (uint32_t, 32)
+DEF_REDUC_PLUS (uint32_t, 64)
+DEF_REDUC_PLUS (uint32_t, 128)
+DEF_REDUC_PLUS (uint32_t, 256)
+DEF_REDUC_PLUS (uint32_t, 512)
+DEF_REDUC_PLUS (uint32_t, 1024)
+
+/* { dg-final { scan-assembler-times {vredsum\.vs} 18 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
new file mode 100644
index 00000000000..8cd2728d236
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-4.c
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (int64_t, 4)
+DEF_REDUC_PLUS (int64_t, 8)
+DEF_REDUC_PLUS (int64_t, 16)
+DEF_REDUC_PLUS (int64_t, 32)
+DEF_REDUC_PLUS (int64_t, 64)
+DEF_REDUC_PLUS (int64_t, 128)
+DEF_REDUC_PLUS (int64_t, 256)
+DEF_REDUC_PLUS (int64_t, 512)
+
+DEF_REDUC_PLUS (uint64_t, 4)
+DEF_REDUC_PLUS (uint64_t, 8)
+DEF_REDUC_PLUS (uint64_t, 16)
+DEF_REDUC_PLUS (uint64_t, 32)
+DEF_REDUC_PLUS (uint64_t, 64)
+DEF_REDUC_PLUS (uint64_t, 128)
+DEF_REDUC_PLUS (uint64_t, 256)
+DEF_REDUC_PLUS (uint64_t, 512)
+
+/* { dg-final { scan-assembler-times {vredsum\.vs} 16 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
new file mode 100644
index 00000000000..09b69fc92db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-5.c
@@ -0,0 +1,18 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (_Float16, 4)
+DEF_REDUC_PLUS (_Float16, 8)
+DEF_REDUC_PLUS (_Float16, 16)
+DEF_REDUC_PLUS (_Float16, 32)
+DEF_REDUC_PLUS (_Float16, 64)
+DEF_REDUC_PLUS (_Float16, 128)
+DEF_REDUC_PLUS (_Float16, 256)
+DEF_REDUC_PLUS (_Float16, 512)
+DEF_REDUC_PLUS (_Float16, 1024)
+DEF_REDUC_PLUS (_Float16, 2048)
+
+/* { dg-final { scan-assembler-times {vfredusum\.vs} 10 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
new file mode 100644
index 00000000000..56b13dc221e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-6.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (float, 4)
+DEF_REDUC_PLUS (float, 8)
+DEF_REDUC_PLUS (float, 16)
+DEF_REDUC_PLUS (float, 32)
+DEF_REDUC_PLUS (float, 64)
+DEF_REDUC_PLUS (float, 128)
+DEF_REDUC_PLUS (float, 256)
+DEF_REDUC_PLUS (float, 512)
+DEF_REDUC_PLUS (float, 1024)
+
+/* { dg-final { scan-assembler-times {vfredusum\.vs} 9 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
new file mode 100644
index 00000000000..eb5de35df12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-7.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8 -ffast-math" } */
+
+#include "def.h"
+
+DEF_REDUC_PLUS (double, 4)
+DEF_REDUC_PLUS (double, 8)
+DEF_REDUC_PLUS (double, 16)
+DEF_REDUC_PLUS (double, 32)
+DEF_REDUC_PLUS (double, 64)
+DEF_REDUC_PLUS (double, 128)
+DEF_REDUC_PLUS (double, 256)
+DEF_REDUC_PLUS (double, 512)
+
+/* { dg-final { scan-assembler-times {vfredusum\.vs} 8 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
new file mode 100644
index 00000000000..cf4f9cc9f2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-8.c
@@ -0,0 +1,58 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_MAXMIN (int8_t, max, >, 4)
+DEF_REDUC_MAXMIN (int8_t, max, >, 8)
+DEF_REDUC_MAXMIN (int8_t, max, >, 16)
+DEF_REDUC_MAXMIN (int8_t, max, >, 32)
+DEF_REDUC_MAXMIN (int8_t, max, >, 64)
+DEF_REDUC_MAXMIN (int8_t, max, >, 128)
+DEF_REDUC_MAXMIN (int8_t, max, >, 256)
+DEF_REDUC_MAXMIN (int8_t, max, >, 512)
+DEF_REDUC_MAXMIN (int8_t, max, >, 1024)
+DEF_REDUC_MAXMIN (int8_t, max, >, 2048)
+DEF_REDUC_MAXMIN (int8_t, max, >, 4096)
+
+DEF_REDUC_MAXMIN (uint8_t, max, >, 4)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 8)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 16)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 32)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 64)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 128)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 256)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 512)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 1024)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 2048)
+DEF_REDUC_MAXMIN (uint8_t, max, >, 4096)
+
+DEF_REDUC_MAXMIN (int8_t, min, <, 4)
+DEF_REDUC_MAXMIN (int8_t, min, <, 8)
+DEF_REDUC_MAXMIN (int8_t, min, <, 16)
+DEF_REDUC_MAXMIN (int8_t, min, <, 32)
+DEF_REDUC_MAXMIN (int8_t, min, <, 64)
+DEF_REDUC_MAXMIN (int8_t, min, <, 128)
+DEF_REDUC_MAXMIN (int8_t, min, <, 256)
+DEF_REDUC_MAXMIN (int8_t, min, <, 512)
+DEF_REDUC_MAXMIN (int8_t, min, <, 1024)
+DEF_REDUC_MAXMIN (int8_t, min, <, 2048)
+DEF_REDUC_MAXMIN (int8_t, min, <, 4096)
+
+DEF_REDUC_MAXMIN (uint8_t, min, <, 4)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 8)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 16)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 32)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 64)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 128)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 256)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 512)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 1024)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 2048)
+DEF_REDUC_MAXMIN (uint8_t, min, <, 4096)
+
+/* { dg-final { scan-assembler-times {vredmax\.vs} 11 } } */
+/* { dg-final { scan-assembler-times {vredmaxu\.vs} 11 } } */
+/* { dg-final { scan-assembler-times {vredmin\.vs} 11 } } */
+/* { dg-final { scan-assembler-times {vredminu\.vs} 11 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
new file mode 100644
index 00000000000..64164586ef6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/reduc-9.c
@@ -0,0 +1,54 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param=riscv-autovec-lmul=m8" } */
+
+#include "def.h"
+
+DEF_REDUC_MAXMIN (int16_t, max, >, 4)
+DEF_REDUC_MAXMIN (int16_t, max, >, 8)
+DEF_REDUC_MAXMIN (int16_t, max, >, 16)
+DEF_REDUC_MAXMIN (int16_t, max, >, 32)
+DEF_REDUC_MAXMIN (int16_t, max, >, 64)
+DEF_REDUC_MAXMIN (int16_t, max, >, 128)
+DEF_REDUC_MAXMIN (int16_t, max, >, 256)
+DEF_REDUC_MAXMIN (int16_t, max, >, 512)
+DEF_REDUC_MAXMIN (int16_t, max, >, 1024)
+DEF_REDUC_MAXMIN (int16_t, max, >, 2048)
+
+DEF_REDUC_MAXMIN (uint16_t, max, >, 4)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 8)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 16)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 32)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 64)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 128)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 256)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 512)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 1024)
+DEF_REDUC_MAXMIN (uint16_t, max, >, 2048)
+
+DEF_REDUC_MAXMIN (int16_t, min, <, 4)
+DEF_REDUC_MAXMIN (int16_t, min, <, 8)
+DEF_REDUC_MAXMIN (int16_t, min, <, 16)
+DEF_REDUC_MAXMIN (int16_t, min, <, 32)
+DEF_REDUC_MAXMIN (int16_t, min, <, 64)
+DEF_REDUC_MAXMIN (int16_t, min, <, 128)
+DEF_REDUC_MAXMIN (int16_t, min, <, 256)
+DEF_REDUC_MAXMIN (int16_t, min, <, 512)
+DEF_REDUC_MAXMIN (int16_t, min, <, 1024)
+DEF_REDUC_MAXMIN (int16_t, min, <, 2048)
+
+DEF_REDUC_MAXMIN (uint16_t, min, <, 4)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 8)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 16)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 32)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 64)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 128)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 256)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 512)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 1024)
+DEF_REDUC_MAXMIN (uint16_t, min, <, 2048)
+
+/* { dg-final { scan-assembler-times {vredmax\.vs} 10 } } */
+/* { dg-final { scan-assembler-times {vredmaxu\.vs} 10 } } */
+/* { dg-final { scan-assembler-times {vredmin\.vs} 10 } } */
+/* { dg-final { scan-assembler-times {vredminu\.vs} 10 } } */
+/* { dg-final { scan-assembler-not {csrr} } } */