public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH V2] RISC-V: Support CALL conditional autovec patterns
@ 2023-08-03  1:58 Juzhe-Zhong
  2023-08-03 11:03 ` Robin Dapp
  0 siblings, 1 reply; 4+ messages in thread
From: Juzhe-Zhong @ 2023-08-03  1:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: kito.cheng, kito.cheng, jeffreyalaw, rdapp.gcc, Juzhe-Zhong

This patch is depending on middle-end patch on vectorizable_call.

Consider this following case:
void foo (float * __restrict a, float * __restrict b, int * __restrict cond, int n)
{
  for (int i = 0; i < n; i++)
    if (cond[i])
      a[i] = b[i] + a[i];
}

Before this patch (**NO** -ffast-math):
<source>:5:21: missed: couldn't vectorize loop
<source>:5:21: missed: not vectorized: control flow in loop.

After this patch:
foo:
	ble	a3,zero,.L5
	mv	a6,a0
.L3:
	vsetvli	a5,a3,e8,mf4,ta,ma
	vle32.v	v0,0(a2)
	vsetvli	a7,zero,e32,m1,ta,ma
	slli	a4,a5,2
	vmsne.vi	v0,v0,0
	sub	a3,a3,a5
	vsetvli	zero,a5,e32,m1,tu,mu    ------> must be TUMU
	vle32.v	v2,0(a0),v0.t
	vle32.v	v1,0(a1),v0.t
	vfadd.vv	v1,v1,v2,v0.t   ------> generated by COND_LEN_ADD with real mask and len.
	vse32.v	v1,0(a6),v0.t
	add	a2,a2,a4
	add	a1,a1,a4
	add	a0,a0,a4
	add	a6,a6,a4
	bne	a3,zero,.L3
.L5:
	ret

gcc/ChangeLog:

        * config/riscv/autovec.md (cond_<optab><mode>): New pattern.
        (cond_len_<optab><mode>): Ditto.
        (cond_fma<mode>): Ditto.
        (cond_len_fma<mode>): Ditto.
        (cond_fnma<mode>): Ditto.
        (cond_len_fnma<mode>): Ditto.
        (cond_fms<mode>): Ditto.
        (cond_len_fms<mode>): Ditto.
        (cond_fnms<mode>): Ditto. 
        (cond_len_fnms<mode>): Ditto.
        * config/riscv/riscv-protos.h (riscv_get_v_regno_alignment): Export global.
        (enum insn_type): Add new enum type.
        (prepare_ternary_operands): New function.
        * config/riscv/riscv-v.cc (emit_vlmax_masked_fp_mu_insn): Ditto.
        (emit_nonvlmax_tumu_insn): Ditto.
        (emit_nonvlmax_fp_tumu_insn): Ditto.
        (expand_cond_len_binop): Add condtional operations.
        (expand_cond_len_ternop): Ditto.
        (prepare_ternary_operands): New function.
        * config/riscv/riscv.cc (riscv_memmodel_needs_amo_release): Export riscv_get_v_regno_alignment as global scope.
        * config/riscv/vector.md: Fix ternary bugs.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/rvv.exp: Add condition tests.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith-9.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-7.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-8.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_arith_run-9.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-7.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-8.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_logical_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-1.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-2.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-3.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-4.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-5.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-6.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-7.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-8.c: New test.
        * gcc.target/riscv/rvv/autovec/cond/cond_shift_run-9.c: New test.
        * gcc.target/riscv/rvv/autovec/reduc/reduc_call-1.c: New test.
        * gcc.target/riscv/rvv/autovec/reduc/reduc_call-2.c: New test.
        * gcc.target/riscv/rvv/autovec/reduc/reduc_call-3.c: New test.
        * gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c: New test.
        * gcc.target/riscv/rvv/autovec/reduc/reduc_call-5.c: New test.

---
 gcc/config/riscv/autovec.md                   | 279 +++++++++++
 gcc/config/riscv/riscv-protos.h               |   5 +
 gcc/config/riscv/riscv-v.cc                   | 152 +++++-
 gcc/config/riscv/riscv.cc                     |   2 +-
 gcc/config/riscv/vector.md                    | 440 ++++++------------
 .../riscv/rvv/autovec/cond/cond_arith-1.c     |  48 ++
 .../riscv/rvv/autovec/cond/cond_arith-2.c     |  27 ++
 .../riscv/rvv/autovec/cond/cond_arith-3.c     |  55 +++
 .../riscv/rvv/autovec/cond/cond_arith-4.c     |  21 +
 .../riscv/rvv/autovec/cond/cond_arith-5.c     |  48 ++
 .../riscv/rvv/autovec/cond/cond_arith-6.c     |  27 ++
 .../riscv/rvv/autovec/cond/cond_arith-7.c     |  50 ++
 .../riscv/rvv/autovec/cond/cond_arith-8.c     |  64 +++
 .../riscv/rvv/autovec/cond/cond_arith-9.c     |  34 ++
 .../riscv/rvv/autovec/cond/cond_arith_run-1.c |  33 ++
 .../riscv/rvv/autovec/cond/cond_arith_run-2.c |   4 +
 .../riscv/rvv/autovec/cond/cond_arith_run-3.c |  34 ++
 .../riscv/rvv/autovec/cond/cond_arith_run-4.c |   4 +
 .../riscv/rvv/autovec/cond/cond_arith_run-5.c |  34 ++
 .../riscv/rvv/autovec/cond/cond_arith_run-6.c |   4 +
 .../riscv/rvv/autovec/cond/cond_arith_run-7.c |  32 ++
 .../riscv/rvv/autovec/cond/cond_arith_run-8.c |  35 ++
 .../riscv/rvv/autovec/cond/cond_arith_run-9.c |  33 ++
 .../riscv/rvv/autovec/cond/cond_fadd-1.c      |  33 ++
 .../riscv/rvv/autovec/cond/cond_fadd-2.c      |  32 ++
 .../riscv/rvv/autovec/cond/cond_fadd-3.c      |  33 ++
 .../riscv/rvv/autovec/cond/cond_fadd-4.c      |  33 ++
 .../riscv/rvv/autovec/cond/cond_fadd_run-1.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fadd_run-2.c  |  31 ++
 .../riscv/rvv/autovec/cond/cond_fadd_run-3.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fadd_run-4.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-1.c  |  35 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-2.c  |  35 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-3.c  |  35 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-4.c  |  35 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-5.c  |  35 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-6.c  |  35 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-7.c  |  35 ++
 .../riscv/rvv/autovec/cond/cond_fma_fnma-8.c  |  35 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-1.c    |  35 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-2.c    |  36 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-3.c    |  35 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-4.c    |  36 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-5.c    |  35 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-6.c    |  35 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-7.c    |  34 ++
 .../rvv/autovec/cond/cond_fma_fnma_run-8.c    |  34 ++
 .../riscv/rvv/autovec/cond/cond_fmax-1.c      |  33 ++
 .../riscv/rvv/autovec/cond/cond_fmax-2.c      |  32 ++
 .../riscv/rvv/autovec/cond/cond_fmax-3.c      |  33 ++
 .../riscv/rvv/autovec/cond/cond_fmax-4.c      |  33 ++
 .../riscv/rvv/autovec/cond/cond_fmax_run-1.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fmax_run-2.c  |  31 ++
 .../riscv/rvv/autovec/cond/cond_fmax_run-3.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fmax_run-4.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fmin-1.c      |  10 +
 .../riscv/rvv/autovec/cond/cond_fmin-2.c      |   9 +
 .../riscv/rvv/autovec/cond/cond_fmin-3.c      |   9 +
 .../riscv/rvv/autovec/cond/cond_fmin-4.c      |   9 +
 .../riscv/rvv/autovec/cond/cond_fmin_run-1.c  |   5 +
 .../riscv/rvv/autovec/cond/cond_fmin_run-2.c  |   5 +
 .../riscv/rvv/autovec/cond/cond_fmin_run-3.c  |   5 +
 .../riscv/rvv/autovec/cond/cond_fmin_run-4.c  |   5 +
 .../riscv/rvv/autovec/cond/cond_fms_fnms-1.c  |  29 ++
 .../riscv/rvv/autovec/cond/cond_fms_fnms-2.c  |  29 ++
 .../riscv/rvv/autovec/cond/cond_fms_fnms-3.c  |  29 ++
 .../riscv/rvv/autovec/cond/cond_fms_fnms-4.c  |  29 ++
 .../riscv/rvv/autovec/cond/cond_fms_fnms-5.c  |  29 ++
 .../riscv/rvv/autovec/cond/cond_fms_fnms-6.c  |  29 ++
 .../rvv/autovec/cond/cond_fms_fnms_run-1.c    |  35 ++
 .../rvv/autovec/cond/cond_fms_fnms_run-2.c    |  36 ++
 .../rvv/autovec/cond/cond_fms_fnms_run-3.c    |  35 ++
 .../rvv/autovec/cond/cond_fms_fnms_run-4.c    |  36 ++
 .../rvv/autovec/cond/cond_fms_fnms_run-5.c    |  35 ++
 .../rvv/autovec/cond/cond_fms_fnms_run-6.c    |  35 ++
 .../riscv/rvv/autovec/cond/cond_fmul-1.c      |  29 ++
 .../riscv/rvv/autovec/cond/cond_fmul-2.c      |  28 ++
 .../riscv/rvv/autovec/cond/cond_fmul-3.c      |  29 ++
 .../riscv/rvv/autovec/cond/cond_fmul-4.c      |  29 ++
 .../riscv/rvv/autovec/cond/cond_fmul_run-1.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fmul_run-2.c  |  31 ++
 .../riscv/rvv/autovec/cond/cond_fmul_run-3.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_fmul_run-4.c  |  32 ++
 .../riscv/rvv/autovec/cond/cond_logical-1.c   |  43 ++
 .../riscv/rvv/autovec/cond/cond_logical-2.c   |  43 ++
 .../riscv/rvv/autovec/cond/cond_logical-3.c   |  43 ++
 .../riscv/rvv/autovec/cond/cond_logical-4.c   |  43 ++
 .../riscv/rvv/autovec/cond/cond_logical-5.c   |  43 ++
 .../rvv/autovec/cond/cond_logical_run-1.c     |  33 ++
 .../rvv/autovec/cond/cond_logical_run-2.c     |  33 ++
 .../rvv/autovec/cond/cond_logical_run-3.c     |  33 ++
 .../rvv/autovec/cond/cond_logical_run-4.c     |  33 ++
 .../rvv/autovec/cond/cond_logical_run-5.c     |  33 ++
 .../riscv/rvv/autovec/cond/cond_shift-1.c     |  33 ++
 .../riscv/rvv/autovec/cond/cond_shift-2.c     |  33 ++
 .../riscv/rvv/autovec/cond/cond_shift-3.c     |  33 ++
 .../riscv/rvv/autovec/cond/cond_shift-4.c     |  33 ++
 .../riscv/rvv/autovec/cond/cond_shift-5.c     |  29 ++
 .../riscv/rvv/autovec/cond/cond_shift-6.c     |  27 ++
 .../riscv/rvv/autovec/cond/cond_shift-7.c     |  29 ++
 .../riscv/rvv/autovec/cond/cond_shift-8.c     |  29 ++
 .../riscv/rvv/autovec/cond/cond_shift-9.c     |  29 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-1.c |  27 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-2.c |  28 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-3.c |  27 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-4.c |  27 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-5.c |  28 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-6.c |  28 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-7.c |  28 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-8.c |  28 ++
 .../riscv/rvv/autovec/cond/cond_shift_run-9.c |  28 ++
 .../riscv/rvv/autovec/reduc/reduc_call-1.c    |  12 +
 .../riscv/rvv/autovec/reduc/reduc_call-2.c    |   6 +
 .../riscv/rvv/autovec/reduc/reduc_call-3.c    |   6 +
 .../riscv/rvv/autovec/reduc/reduc_call-4.c    |   6 +
 .../riscv/rvv/autovec/reduc/reduc_call-5.c    |  16 +
 gcc/testsuite/gcc.target/riscv/rvv/rvv.exp    |   2 +
 117 files changed, 3869 insertions(+), 309 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-5.c

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index fd7ec911e87..5e97ccba3b3 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1448,6 +1448,45 @@
   DONE;
 })
 
+;; -------------------------------------------------------------------------
+;; ---- [INT] Conditional binary operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vsra/vsrl/vsll
+;; -------------------------------------------------------------------------
+
+(define_expand "cond_<optab><mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (any_shift:VI
+     (match_operand:VI 2 "register_operand")
+     (match_operand:VI 3 "vector_shift_operand"))
+   (match_operand:VI 4 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_<optab><mode> (operands[0], operands[1], operands[2],
+					 operands[3], operands[4],
+					 gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+					 const0_rtx));
+  DONE;
+})
+
+(define_expand "cond_len_<optab><mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (any_shift:VI
+     (match_operand:VI 2 "register_operand")
+     (match_operand:VI 3 "vector_shift_operand"))
+   (match_operand:VI 4 "register_operand")
+   (match_operand 5 "autovec_length_operand")
+   (match_operand 6 "const_0_operand")]
+  "TARGET_VECTOR"
+{
+  riscv_vector::expand_cond_len_binop (<CODE>, operands);
+  DONE;
+})
+
 ;; -------------------------------------------------------------------------
 ;; ---- [INT] Conditional binary operations
 ;; -------------------------------------------------------------------------
@@ -1456,6 +1495,23 @@
 ;; - vadd.vi/vsub.vi/...
 ;; -------------------------------------------------------------------------
 
+(define_expand "cond_<optab><mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (any_int_binop_no_shift:VI
+     (match_operand:VI 2 "<binop_rhs1_predicate>")
+     (match_operand:VI 3 "<binop_rhs2_predicate>"))
+   (match_operand:VI 4 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_<optab><mode> (operands[0], operands[1], operands[2],
+					 operands[3], operands[4],
+					 gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+					 const0_rtx));
+  DONE;
+})
+
 (define_expand "cond_len_<optab><mode>"
   [(match_operand:VI 0 "register_operand")
    (match_operand:<VM> 1 "vector_mask_operand")
@@ -1479,6 +1535,23 @@
 ;; - vfadd.vf/vfsub.vf/...
 ;; -------------------------------------------------------------------------
 
+(define_expand "cond_<optab><mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (any_float_binop:VF
+     (match_operand:VF 2 "register_operand")
+     (match_operand:VF 3 "register_operand"))
+   (match_operand:VF 4 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_<optab><mode> (operands[0], operands[1], operands[2],
+					 operands[3], operands[4],
+					 gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+					 const0_rtx));
+  DONE;
+})
+
 (define_expand "cond_len_<optab><mode>"
   [(match_operand:VF 0 "register_operand")
    (match_operand:<VM> 1 "vector_mask_operand")
@@ -1500,6 +1573,23 @@
 ;; - vfmin.vf/vfmax.vf
 ;; -------------------------------------------------------------------------
 
+(define_expand "cond_<optab><mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (any_float_binop_nofrm:VF
+     (match_operand:VF 2 "register_operand")
+     (match_operand:VF 3 "register_operand"))
+   (match_operand:VF 4 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_<optab><mode> (operands[0], operands[1], operands[2],
+					 operands[3], operands[4],
+					 gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+					 const0_rtx));
+  DONE;
+})
+
 (define_expand "cond_len_<optab><mode>"
   [(match_operand:VF 0 "register_operand")
    (match_operand:<VM> 1 "vector_mask_operand")
@@ -1515,6 +1605,79 @@
   DONE;
 })
 
+;; -------------------------------------------------------------------------
+;; ---- [INT] Conditional ternary operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vmacc/...
+;; -------------------------------------------------------------------------
+
+(define_expand "cond_fma<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VI 2 "register_operand")
+   (match_operand:VI 3 "register_operand")
+   (match_operand:VI 4 "register_operand")
+   (match_operand:VI 5 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_fma<mode> (operands[0], operands[1], operands[2],
+				     operands[3], operands[4], operands[5],
+				     gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+				     const0_rtx));
+  DONE;
+})
+
+(define_expand "cond_len_fma<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VI 2 "register_operand")
+   (match_operand:VI 3 "register_operand")
+   (match_operand:VI 4 "register_operand")
+   (match_operand:VI 5 "register_operand")
+   (match_operand 6 "autovec_length_operand")
+   (match_operand 7 "const_0_operand")]
+  "TARGET_VECTOR"
+{
+  insn_code icode = code_for_pred_mul_plus (<MODE>mode);
+  riscv_vector::expand_cond_len_ternop (icode, operands);
+  DONE;
+})
+
+(define_expand "cond_fnma<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VI 2 "register_operand")
+   (match_operand:VI 3 "register_operand")
+   (match_operand:VI 4 "register_operand")
+   (match_operand:VI 5 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_fnma<mode> (operands[0], operands[1], operands[2],
+				      operands[3], operands[4], operands[5],
+				      gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+				      const0_rtx));
+  DONE;
+})
+
+(define_expand "cond_len_fnma<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VI 2 "register_operand")
+   (match_operand:VI 3 "register_operand")
+   (match_operand:VI 4 "register_operand")
+   (match_operand:VI 5 "register_operand")
+   (match_operand 6 "autovec_length_operand")
+   (match_operand 7 "const_0_operand")]
+  "TARGET_VECTOR"
+{
+  insn_code icode = code_for_pred_minus_mul (<MODE>mode);
+  riscv_vector::expand_cond_len_ternop (icode, operands);
+  DONE;
+})
+
 ;; -------------------------------------------------------------------------
 ;; ---- [FP] Conditional ternary operations
 ;; -------------------------------------------------------------------------
@@ -1522,6 +1685,23 @@
 ;; - vfmacc/...
 ;; -------------------------------------------------------------------------
 
+(define_expand "cond_fma<mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VF 2 "register_operand")
+   (match_operand:VF 3 "register_operand")
+   (match_operand:VF 4 "register_operand")
+   (match_operand:VF 5 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_fma<mode> (operands[0], operands[1], operands[2],
+				     operands[3], operands[4], operands[5],
+				     gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+				     const0_rtx));
+  DONE;
+})
+
 (define_expand "cond_len_fma<mode>"
   [(match_operand:VF 0 "register_operand")
    (match_operand:<VM> 1 "vector_mask_operand")
@@ -1538,6 +1718,105 @@
   DONE;
 })
 
+(define_expand "cond_fnma<mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VF 2 "register_operand")
+   (match_operand:VF 3 "register_operand")
+   (match_operand:VF 4 "register_operand")
+   (match_operand:VF 5 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_fnma<mode> (operands[0], operands[1], operands[2],
+				      operands[3], operands[4], operands[5],
+				      gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+				      const0_rtx));
+  DONE;
+})
+
+(define_expand "cond_len_fnma<mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VF 2 "register_operand")
+   (match_operand:VF 3 "register_operand")
+   (match_operand:VF 4 "register_operand")
+   (match_operand:VF 5 "register_operand")
+   (match_operand 6 "autovec_length_operand")
+   (match_operand 7 "const_0_operand")]
+  "TARGET_VECTOR"
+{
+  insn_code icode = code_for_pred_mul_neg (PLUS, <MODE>mode);
+  riscv_vector::expand_cond_len_ternop (icode, operands);
+  DONE;
+})
+
+(define_expand "cond_fms<mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VF 2 "register_operand")
+   (match_operand:VF 3 "register_operand")
+   (match_operand:VF 4 "register_operand")
+   (match_operand:VF 5 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_fms<mode> (operands[0], operands[1], operands[2],
+				     operands[3], operands[4], operands[5],
+				     gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+				     const0_rtx));
+  DONE;
+})
+
+(define_expand "cond_len_fms<mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VF 2 "register_operand")
+   (match_operand:VF 3 "register_operand")
+   (match_operand:VF 4 "register_operand")
+   (match_operand:VF 5 "register_operand")
+   (match_operand 6 "autovec_length_operand")
+   (match_operand 7 "const_0_operand")]
+  "TARGET_VECTOR"
+{
+  insn_code icode = code_for_pred_mul (MINUS, <MODE>mode);
+  riscv_vector::expand_cond_len_ternop (icode, operands);
+  DONE;
+})
+
+(define_expand "cond_fnms<mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VF 2 "register_operand")
+   (match_operand:VF 3 "register_operand")
+   (match_operand:VF 4 "register_operand")
+   (match_operand:VF 5 "register_operand")]
+  "TARGET_VECTOR"
+{
+  /* Normalize into cond_len_* operations.  */
+  emit_insn (gen_cond_len_fnms<mode> (operands[0], operands[1], operands[2],
+				      operands[3], operands[4], operands[5],
+				      gen_int_mode (GET_MODE_NUNITS (<MODE>mode), Pmode),
+				      const0_rtx));
+  DONE;
+})
+
+(define_expand "cond_len_fnms<mode>"
+  [(match_operand:VF 0 "register_operand")
+   (match_operand:<VM> 1 "vector_mask_operand")
+   (match_operand:VF 2 "register_operand")
+   (match_operand:VF 3 "register_operand")
+   (match_operand:VF 4 "register_operand")
+   (match_operand:VF 5 "register_operand")
+   (match_operand 6 "autovec_length_operand")
+   (match_operand 7 "const_0_operand")]
+  "TARGET_VECTOR"
+{
+  insn_code icode = code_for_pred_mul_neg (MINUS, <MODE>mode);
+  riscv_vector::expand_cond_len_ternop (icode, operands);
+  DONE;
+})
+
 ;; =========================================================================
 ;; == Reductions
 ;; =========================================================================
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 324991e2619..3f47bf04de0 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -128,6 +128,7 @@ extern poly_uint64 riscv_regmode_natural_size (machine_mode);
 extern bool riscv_v_ext_vector_mode_p (machine_mode);
 extern bool riscv_v_ext_tuple_mode_p (machine_mode);
 extern bool riscv_v_ext_vls_mode_p (machine_mode);
+extern int riscv_get_v_regno_alignment (machine_mode);
 extern bool riscv_shamt_matches_mask_p (int, HOST_WIDE_INT);
 extern void riscv_subword_address (rtx, rtx *, rtx *, rtx *, rtx *);
 extern void riscv_lshift_subword (machine_mode, rtx, rtx, rtx *);
@@ -186,13 +187,16 @@ enum insn_type
   RVV_BINOP = 3,
   RVV_BINOP_MU = RVV_BINOP + 2,
   RVV_BINOP_TU = RVV_BINOP + 2,
+  RVV_BINOP_TUMU = RVV_BINOP + 2,
   RVV_MERGE_OP = 4,
   RVV_CMP_OP = 4,
   RVV_CMP_MU_OP = RVV_CMP_OP + 2, /* +2 means mask and maskoff operand.  */
   RVV_UNOP_MU = RVV_UNOP + 2,	  /* Likewise.  */
   RVV_UNOP_M = RVV_UNOP + 2,	  /* Likewise.  */
   RVV_TERNOP = 5,
+  RVV_TERNOP_MU = RVV_TERNOP + 1,
   RVV_TERNOP_TU = RVV_TERNOP + 1,
+  RVV_TERNOP_TUMU = RVV_TERNOP + 1,
   RVV_WIDEN_TERNOP = 4,
   RVV_SCALAR_MOV_OP = 4, /* +1 for VUNDEF according to vector.md.  */
   RVV_SLIDE_OP = 4,      /* Dest, VUNDEF, source and offset.  */
@@ -320,6 +324,7 @@ void expand_select_vl (rtx *);
 void expand_load_store (rtx *, bool);
 void expand_gather_scatter (rtx *, bool);
 void expand_cond_len_ternop (unsigned, rtx *);
+void prepare_ternary_operands (rtx *, bool = false);
 
 /* Rounding mode bitfield for fixed point VXRM.  */
 enum fixed_point_rounding_mode
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 278452b9e05..a91ddfcc150 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -991,6 +991,25 @@ emit_vlmax_masked_mu_insn (unsigned icode, int op_num, rtx *ops)
   e.emit_insn ((enum insn_code) icode, ops);
 }
 
+/* This function emits a masked instruction.  */
+static void
+emit_vlmax_masked_fp_mu_insn (unsigned icode, int op_num, rtx *ops)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode);
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+					  /*HAS_DEST_P*/ true,
+					  /*FULLY_UNMASKED_P*/ false,
+					  /*USE_REAL_MERGE_P*/ true,
+					  /*HAS_AVL_P*/ true,
+					  /*VLMAX_P*/ true, dest_mode,
+					  mask_mode);
+  e.set_policy (TAIL_ANY);
+  e.set_policy (MASK_UNDISTURBED);
+  e.set_rounding_mode (FRM_DYN);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
 /* This function emits a TU instruction.  */
 static void
 emit_nonvlmax_tu_insn (unsigned icode, int op_num, rtx *ops, rtx avl)
@@ -1030,6 +1049,45 @@ emit_nonvlmax_fp_tu_insn (unsigned icode, int op_num, rtx *ops, rtx avl)
   e.emit_insn ((enum insn_code) icode, ops);
 }
 
+/* This function emits a TUMU instruction.  */
+static void
+emit_nonvlmax_tumu_insn (unsigned icode, int op_num, rtx *ops, rtx avl)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode);
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+					  /*HAS_DEST_P*/ true,
+					  /*FULLY_UNMASKED_P*/ false,
+					  /*USE_REAL_MERGE_P*/ true,
+					  /*HAS_AVL_P*/ true,
+					  /*VLMAX_P*/ false, dest_mode,
+					  mask_mode);
+  e.set_policy (TAIL_UNDISTURBED);
+  e.set_policy (MASK_UNDISTURBED);
+  e.set_vl (avl);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
+/* This function emits a TUMU instruction.  */
+static void
+emit_nonvlmax_fp_tumu_insn (unsigned icode, int op_num, rtx *ops, rtx avl)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode);
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (/*OP_NUM*/ op_num,
+					  /*HAS_DEST_P*/ true,
+					  /*FULLY_UNMASKED_P*/ false,
+					  /*USE_REAL_MERGE_P*/ true,
+					  /*HAS_AVL_P*/ true,
+					  /*VLMAX_P*/ false, dest_mode,
+					  mask_mode);
+  e.set_policy (TAIL_UNDISTURBED);
+  e.set_policy (MASK_UNDISTURBED);
+  e.set_rounding_mode (FRM_DYN);
+  e.set_vl (avl);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
 /* Emit vmv.s.x instruction.  */
 
 void
@@ -3285,22 +3343,40 @@ expand_cond_len_binop (rtx_code code, rtx *ops)
   machine_mode mode = GET_MODE (dest);
   machine_mode mask_mode = GET_MODE (mask);
 
-  poly_uint64 value;
+  poly_int64 value;
   bool is_dummy_mask = rtx_equal_p (mask, CONSTM1_RTX (mask_mode));
+  bool is_vlmax_len
+    = poly_int_rtx_p (len, &value) && known_eq (value, GET_MODE_NUNITS (mode));
+  rtx cond_ops[] = {dest, mask, merge, src1, src2};
+  insn_code icode = code_for_pred (code, mode);
 
   if (is_dummy_mask)
     {
       /* Use TU, MASK ANY policy.  */
-      rtx ops[] = {dest, mask, merge, src1, src2};
-      insn_code icode = code_for_pred (code, mode);
       if (needs_fp_rounding (code, mode))
-	emit_nonvlmax_fp_tu_insn (icode, RVV_BINOP_TU, ops, len);
+	emit_nonvlmax_fp_tu_insn (icode, RVV_BINOP_TU, cond_ops, len);
       else
-	emit_nonvlmax_tu_insn (icode, RVV_BINOP_TU, ops, len);
+	emit_nonvlmax_tu_insn (icode, RVV_BINOP_TU, cond_ops, len);
     }
   else
-    /* FIXME: Enable this case when we support it in the middle-end.  */
-    gcc_unreachable ();
+    {
+      if (is_vlmax_len)
+	{
+	  /* Use TAIL ANY, MU policy.  */
+	  if (needs_fp_rounding (code, mode))
+	    emit_vlmax_masked_fp_mu_insn (icode, RVV_BINOP_MU, cond_ops);
+	  else
+	    emit_vlmax_masked_mu_insn (icode, RVV_BINOP_MU, cond_ops);
+	}
+      else
+	{
+	  /* Use TU, MU policy.  */
+	  if (needs_fp_rounding (code, mode))
+	    emit_nonvlmax_fp_tumu_insn (icode, RVV_BINOP_TUMU, cond_ops, len);
+	  else
+	    emit_nonvlmax_tumu_insn (icode, RVV_BINOP_TUMU, cond_ops, len);
+	}
+    }
 }
 
 /* Prepare insn_code for gather_load/scatter_store according to
@@ -3470,8 +3546,10 @@ expand_cond_len_ternop (unsigned icode, rtx *ops)
   machine_mode mode = GET_MODE (dest);
   machine_mode mask_mode = GET_MODE (mask);
 
-  poly_uint64 value;
+  poly_int64 value;
   bool is_dummy_mask = rtx_equal_p (mask, CONSTM1_RTX (mask_mode));
+  bool is_vlmax_len
+    = poly_int_rtx_p (len, &value) && known_eq (value, GET_MODE_NUNITS (mode));
 
   if (is_dummy_mask)
     {
@@ -3483,8 +3561,24 @@ expand_cond_len_ternop (unsigned icode, rtx *ops)
 	gcc_unreachable ();
     }
   else
-    /* FIXME: Enable this case when we support it in the middle-end.  */
-    gcc_unreachable ();
+    {
+      if (is_vlmax_len)
+	{
+	  /* Use TAIL ANY, MU policy.  */
+	  if (FLOAT_MODE_P (mode))
+	    emit_vlmax_masked_fp_mu_insn (icode, RVV_TERNOP_MU, ops);
+	  else
+	    emit_vlmax_masked_mu_insn (icode, RVV_TERNOP_MU, ops);
+	}
+      else
+	{
+	  /* Use TU, MU policy.  */
+	  if (FLOAT_MODE_P (mode))
+	    emit_nonvlmax_fp_tumu_insn (icode, RVV_TERNOP_TUMU, ops, len);
+	  else
+	    emit_nonvlmax_tumu_insn (icode, RVV_TERNOP_TUMU, ops, len);
+	}
+    }
 }
 
 /* Expand reduction operations.  */
@@ -3534,4 +3628,42 @@ expand_reduction (rtx_code code, rtx *ops, rtx init, reduction_type type)
   emit_insn (gen_pred_extract_first (m1_mode, ops[0], m1_tmp2));
 }
 
+/* Prepare ops for ternary operations.
+   It can be called before or after RA.  */
+void
+prepare_ternary_operands (rtx *ops, bool split_p)
+{
+  machine_mode mode = GET_MODE (ops[0]);
+
+  if (split_p
+      || (!rtx_equal_p (ops[2], ops[5])
+	  && !rtx_equal_p (ops[3], ops[5])
+	  && !rtx_equal_p (ops[4], ops[5])
+	  && riscv_get_v_regno_alignment (mode) == 8))
+    {
+      /* RA will fail to find vector REG and report ICE, so we pre-merge
+	 the ops for LMUL = 8.  */
+      if (satisfies_constraint_Wc1 (ops[1]))
+	{
+	  emit_move_insn (ops[0], ops[5]);
+	  emit_insn (gen_pred_mov (mode, ops[0], ops[1], ops[0], ops[4], ops[6],
+				   ops[7], ops[8], ops[9]));
+	}
+      else
+	emit_insn (gen_pred_merge (mode, ops[0], RVV_VUNDEF (mode), ops[5],
+				   ops[4], ops[1], ops[6], ops[7], ops[9]));
+      ops[5] = ops[4] = ops[0];
+    }
+  else
+    {
+      /* Swap the multiplication ops if the fallback value is the
+	 second of the two.  */
+      if (rtx_equal_p (ops[3], ops[5]))
+	std::swap (ops[2], ops[3]);
+
+      /* TODO: ??? Maybe we could support splitting FMA (a, 4, b)
+	 into PLUS (ASHIFT (a, 2), b) according to uarchs.  */
+    }
+}
+
 } // namespace riscv_vector
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 1eacca06b5c..977ef7ef477 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4576,7 +4576,7 @@ riscv_memmodel_needs_amo_release (enum memmodel model)
 /* Get REGNO alignment of vector mode.
    The alignment = LMUL when the LMUL >= 1.
    Otherwise, alignment = 1.  */
-static int
+int
 riscv_get_v_regno_alignment (machine_mode mode)
 {
   /* 3.3.2. LMUL = 2,4,8, register numbers should be multiple of 2,4,8.
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 6ebbefc4ff6..fe95c4dc4c9 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -4979,10 +4979,7 @@
 	  (match_operand:VI 5 "register_operand")))]
   "TARGET_VECTOR"
 {
-  /* Swap the multiplication operands if the fallback value is the
-     second of the two.  */
-  if (rtx_equal_p (operands[3], operands[5]))
-    std::swap (operands[2], operands[3]);
+  riscv_vector::prepare_ternary_operands (operands);
 })
 
 (define_insn "*pred_madd<mode>"
@@ -5048,52 +5045,30 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_mul_plus<mode>"
-  [(set (match_operand:VI 0 "register_operand"            "=&vr,?&vr, ?&vr, ?&vr,  ?&vr")
+  [(set (match_operand:VI 0 "register_operand"            "=&vr")
 	(if_then_else:VI
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"    "   rK,   rK,   rK,   rK,   rK")
-	     (match_operand 7 "const_int_operand"        "    i,    i,    i,    i,    i")
-	     (match_operand 8 "const_int_operand"        "    i,    i,    i,    i,    i")
-	     (match_operand 9 "const_int_operand"        "    i,    i,    i,    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 6 "vector_length_operand"    "   rK")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (match_operand 8 "const_int_operand"        "    i")
+	     (match_operand 9 "const_int_operand"        "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
 	  (plus:VI
 	    (mult:VI
-	      (match_operand:VI 2 "register_operand"     "   vr,   vr,   vi,   vr,   vr")
-	      (match_operand:VI 3 "register_operand"     "   vr,   vr,   vr,   vi,   vr"))
-	    (match_operand:VI 4 "vector_arith_operand"   "   vr,   vi,   vr,   vr,   vr"))
-	  (match_operand:VI 5 "register_operand"         "    0,   vr,   vr,   vr,   vr")))]
+	      (match_operand:VI 2 "register_operand"     "   vr")
+	      (match_operand:VI 3 "register_operand"     "   vr"))
+	    (match_operand:VI 4 "register_operand"       "   vr"))
+	  (match_operand:VI 5 "register_operand"         "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[2], operands[5])
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vmacc.vv\t%0,%2,%3%p1
-   #
-   #
-   #
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    if (satisfies_constraint_vi (operands[3]))
-      std::swap (operands[2], operands[3]);
-
-    if (satisfies_constraint_vi (operands[2]))
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[2], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[2] = operands[0];
-      }
-    else
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[4], operands[1], operands[6], 
-			operands[7], operands[9]));
-        operands[5] = operands[4] = operands[0];
-      }
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
@@ -5112,14 +5087,12 @@
 	  (plus:VI_QHS
 	    (mult:VI_QHS
 	      (vec_duplicate:VI_QHS
-	        (match_operand:<VEL> 2 "reg_or_int_operand"))
+	        (match_operand:<VEL> 2 "register_operand"))
 	      (match_operand:VI_QHS 3 "register_operand"))
 	    (match_operand:VI_QHS 4 "register_operand"))
 	  (match_operand:VI_QHS 5 "register_operand")))]
   "TARGET_VECTOR"
-{
-  operands[2] = force_reg (<VEL>mode, operands[2]);
-})
+{})
 
 (define_insn "*pred_madd<mode>_scalar"
   [(set (match_operand:VI 0 "register_operand"            "=vd,?&vd, vr,?&vr")
@@ -5186,48 +5159,30 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_mul_plus<mode>_scalar"
-  [(set (match_operand:VI 0 "register_operand"            "=&vr, ?&vr, ?&vr, ?&vr")
+  [(set (match_operand:VI 0 "register_operand"            "=&vr")
 	(if_then_else:VI
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"    "   rK,   rK,   rK,   rK")
-	     (match_operand 7 "const_int_operand"        "    i,    i,    i,    i")
-	     (match_operand 8 "const_int_operand"        "    i,    i,    i,    i")
-	     (match_operand 9 "const_int_operand"        "    i,    i,    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 6 "vector_length_operand"    "   rK")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (match_operand 8 "const_int_operand"        "    i")
+	     (match_operand 9 "const_int_operand"        "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
 	  (plus:VI
 	    (mult:VI
 	      (vec_duplicate:VI
-	        (match_operand:<VEL> 2 "register_operand" "    r,    r,    r,    r"))
-	      (match_operand:VI 3 "register_operand"      "   vr,   vr,   vi,   vr"))
-	    (match_operand:VI 4 "vector_arith_operand"    "   vr,   vi,   vr,   vr"))
-	  (match_operand:VI 5 "register_operand"          "    0,   vr,   vr,   vr")))]
+	        (match_operand:<VEL> 2 "register_operand" "    r"))
+	      (match_operand:VI 3 "register_operand"      "   vr"))
+	    (match_operand:VI 4 "vector_arith_operand"    "   vr"))
+	  (match_operand:VI 5 "register_operand"          "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1
-   #
-   #
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    if (satisfies_constraint_vi (operands[3]))
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[3], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[3] = operands[0];
-      }
-    else
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[4] = operands[0];
-      }
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
@@ -5333,49 +5288,31 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_mul_plus<mode>_extended_scalar"
-  [(set (match_operand:VI_D 0 "register_operand"                "=&vr, ?&vr, ?&vr, ?&vr")
+  [(set (match_operand:VI_D 0 "register_operand"                "=&vr")
 	(if_then_else:VI_D
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand"       "vmWc1,vmWc1,vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"          "   rK,   rK,   rK,   rK")
-	     (match_operand 7 "const_int_operand"              "    i,    i,    i,    i")
-	     (match_operand 8 "const_int_operand"              "    i,    i,    i,    i")
-	     (match_operand 9 "const_int_operand"              "    i,    i,    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand"       "vmWc1")
+	     (match_operand 6 "vector_length_operand"          "   rK")
+	     (match_operand 7 "const_int_operand"              "    i")
+	     (match_operand 8 "const_int_operand"              "    i")
+	     (match_operand 9 "const_int_operand"              "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
 	  (plus:VI_D
 	    (mult:VI_D
 	      (vec_duplicate:VI_D
 	        (sign_extend:<VEL>
-	          (match_operand:<VSUBEL> 2 "register_operand" "    r,    r,    r,    r")))
-	      (match_operand:VI_D 3 "register_operand"         "   vr,   vr,   vr,   vr"))
-	    (match_operand:VI_D 4 "vector_arith_operand"       "   vr,   vr,   vr,   vr"))
-	  (match_operand:VI_D 5 "register_operand"             "    0,   vr,   vr,   vr")))]
+	          (match_operand:<VSUBEL> 2 "register_operand" "    r")))
+	      (match_operand:VI_D 3 "register_operand"         "   vr"))
+	    (match_operand:VI_D 4 "register_operand"           "   vr"))
+	  (match_operand:VI_D 5 "register_operand"             "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vmacc.vx\t%0,%2,%3%p1
-   #
-   #
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    if (satisfies_constraint_vi (operands[3]))
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[3], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[3] = operands[0];
-      }
-    else
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[4] = operands[0];
-      }
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
@@ -5399,10 +5336,7 @@
 	  (match_operand:VI 5 "register_operand")))]
   "TARGET_VECTOR"
 {
-  /* Swap the multiplication operands if the fallback value is the
-     second of the two.  */
-  if (rtx_equal_p (operands[3], operands[5]))
-    std::swap (operands[2], operands[3]);
+  riscv_vector::prepare_ternary_operands (operands);
 })
 
 (define_insn "*pred_nmsub<mode>"
@@ -5468,52 +5402,30 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_minus_mul<mode>"
-  [(set (match_operand:VI 0 "register_operand"            "=&vr,?&vr, ?&vr, ?&vr,  ?&vr")
+  [(set (match_operand:VI 0 "register_operand"            "=&vr")
 	(if_then_else:VI
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"    "   rK,   rK,   rK,   rK,   rK")
-	     (match_operand 7 "const_int_operand"        "    i,    i,    i,    i,    i")
-	     (match_operand 8 "const_int_operand"        "    i,    i,    i,    i,    i")
-	     (match_operand 9 "const_int_operand"        "    i,    i,    i,    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 6 "vector_length_operand"    "   rK")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (match_operand 8 "const_int_operand"        "    i")
+	     (match_operand 9 "const_int_operand"        "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
 	  (minus:VI
-	    (match_operand:VI 4 "vector_arith_operand"   "   vr,   vi,   vr,   vr,   vr")
+	    (match_operand:VI 4 "vector_arith_operand"   "   vr")
 	    (mult:VI
-	      (match_operand:VI 2 "register_operand"     "   vr,   vr,   vi,   vr,   vr")
-	      (match_operand:VI 3 "register_operand"     "   vr,   vr,   vr,   vi,   vr")))
-	  (match_operand:VI 5 "register_operand"         "    0,   vr,   vr,   vr,   vr")))]
+	      (match_operand:VI 2 "register_operand"     "   vr")
+	      (match_operand:VI 3 "register_operand"     "   vr")))
+	  (match_operand:VI 5 "register_operand"         "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[2], operands[5])
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vnmsac.vv\t%0,%2,%3%p1
-   #
-   #
-   #
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    if (satisfies_constraint_vi (operands[3]))
-      std::swap (operands[2], operands[3]);
-
-    if (satisfies_constraint_vi (operands[2]))
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[2], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[2] = operands[0];
-      }
-    else
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[4], operands[1], operands[6], 
-			operands[7], operands[9]));
-        operands[5] = operands[4] = operands[0];
-      }
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
@@ -5533,13 +5445,11 @@
 	    (match_operand:VI_QHS 4 "register_operand")
 	    (mult:VI_QHS
 	      (vec_duplicate:VI_QHS
-	        (match_operand:<VEL> 2 "reg_or_int_operand"))
+	        (match_operand:<VEL> 2 "register_operand"))
 	      (match_operand:VI_QHS 3 "register_operand")))
 	  (match_operand:VI_QHS 5 "register_operand")))]
   "TARGET_VECTOR"
-{
-  operands[2] = force_reg (<VEL>mode, operands[2]);
-})
+{})
 
 (define_insn "*pred_nmsub<mode>_scalar"
   [(set (match_operand:VI 0 "register_operand"            "=vd,?&vd, vr,?&vr")
@@ -5606,48 +5516,30 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_minus_mul<mode>_scalar"
-  [(set (match_operand:VI 0 "register_operand"            "=&vr, ?&vr, ?&vr, ?&vr")
+  [(set (match_operand:VI 0 "register_operand"            "=&vr")
 	(if_then_else:VI
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"    "   rK,   rK,   rK,   rK")
-	     (match_operand 7 "const_int_operand"        "    i,    i,    i,    i")
-	     (match_operand 8 "const_int_operand"        "    i,    i,    i,    i")
-	     (match_operand 9 "const_int_operand"        "    i,    i,    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 6 "vector_length_operand"    "   rK")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (match_operand 8 "const_int_operand"        "    i")
+	     (match_operand 9 "const_int_operand"        "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
 	  (minus:VI
-	    (match_operand:VI 4 "vector_arith_operand"    "   vr,   vi,   vr,   vr")
+	    (match_operand:VI 4 "vector_arith_operand"    "   vr")
 	    (mult:VI
 	      (vec_duplicate:VI
-	        (match_operand:<VEL> 2 "register_operand" "    r,    r,    r,    r"))
-	      (match_operand:VI 3 "register_operand"      "   vr,   vr,   vi,   vr")))
-	  (match_operand:VI 5 "register_operand"          "    0,   vr,   vr,   vr")))]
+	        (match_operand:<VEL> 2 "register_operand" "    r"))
+	      (match_operand:VI 3 "register_operand"      "   vr")))
+	  (match_operand:VI 5 "register_operand"          "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vnmsac.vx\t%0,%2,%3%p1
-   #
-   #
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    if (satisfies_constraint_vi (operands[3]))
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[3], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[3] = operands[0];
-      }
-    else
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[4] = operands[0];
-      }
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
@@ -5753,49 +5645,31 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_minus_mul<mode>_extended_scalar"
-  [(set (match_operand:VI_D 0 "register_operand"                "=&vr, ?&vr, ?&vr, ?&vr")
+  [(set (match_operand:VI_D 0 "register_operand"                "=&vr")
 	(if_then_else:VI_D
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand"       "vmWc1,vmWc1,vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"          "   rK,   rK,   rK,   rK")
-	     (match_operand 7 "const_int_operand"              "    i,    i,    i,    i")
-	     (match_operand 8 "const_int_operand"              "    i,    i,    i,    i")
-	     (match_operand 9 "const_int_operand"              "    i,    i,    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand"       "vmWc1")
+	     (match_operand 6 "vector_length_operand"          "   rK")
+	     (match_operand 7 "const_int_operand"              "    i")
+	     (match_operand 8 "const_int_operand"              "    i")
+	     (match_operand 9 "const_int_operand"              "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
 	  (minus:VI_D
-	    (match_operand:VI_D 4 "vector_arith_operand"       "   vr,   vr,   vr,   vr")
+	    (match_operand:VI_D 4 "vector_arith_operand"       "   vr")
 	    (mult:VI_D
 	      (vec_duplicate:VI_D
 	        (sign_extend:<VEL>
-	          (match_operand:<VSUBEL> 2 "register_operand" "    r,    r,    r,    r")))
-	      (match_operand:VI_D 3 "register_operand"         "   vr,   vr,   vr,   vr")))
-	  (match_operand:VI_D 5 "register_operand"             "    0,   vr,   vr,   vr")))]
+	          (match_operand:<VSUBEL> 2 "register_operand" "    r")))
+	      (match_operand:VI_D 3 "register_operand"         "   vr")))
+	  (match_operand:VI_D 5 "register_operand"             "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vnmsac.vx\t%0,%2,%3%p1
-   #
-   #
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    if (satisfies_constraint_vi (operands[3]))
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[3], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[3] = operands[0];
-      }
-    else
-      {
-        emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-                	operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-        operands[5] = operands[4] = operands[0];
-      }
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vimuladd")
    (set_attr "mode" "<MODE>")])
@@ -6371,10 +6245,7 @@
 	  (match_operand:VF 5 "register_operand")))]
   "TARGET_VECTOR"
 {
-  /* Swap the multiplication operands if the fallback value is the
-     second of the two.  */
-  if (rtx_equal_p (operands[3], operands[5]))
-    std::swap (operands[2], operands[3]);
+  riscv_vector::prepare_ternary_operands (operands);
 })
 
 (define_insn "*pred_<madd_msub><mode>"
@@ -6444,38 +6315,32 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_mul_<optab><mode>"
-  [(set (match_operand:VF 0 "register_operand"            "=&vr, ?&vr")
+  [(set (match_operand:VF 0 "register_operand"            "=&vr")
 	(if_then_else:VF
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"    "   rK,   rK")
-	     (match_operand 7 "const_int_operand"        "    i,    i")
-	     (match_operand 8 "const_int_operand"        "    i,    i")
-	     (match_operand 9 "const_int_operand"        "    i,    i")
-	     (match_operand 10 "const_int_operand"       "    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 6 "vector_length_operand"    "   rK")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (match_operand 8 "const_int_operand"        "    i")
+	     (match_operand 9 "const_int_operand"        "    i")
+	     (match_operand 10 "const_int_operand"       "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)
 	     (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
 	  (plus_minus:VF
 	    (mult:VF
-	      (match_operand:VF 2 "register_operand"     "   vr,   vr")
-	      (match_operand:VF 3 "register_operand"     "   vr,   vr"))
-	    (match_operand:VF 4 "vector_arith_operand"   "   vr,   vr"))
-	  (match_operand:VF 5 "register_operand"         "    0,   vr")))]
+	      (match_operand:VF 2 "register_operand"     "   vr")
+	      (match_operand:VF 3 "register_operand"     "   vr"))
+	    (match_operand:VF 4 "register_operand"       "   vr"))
+	  (match_operand:VF 5 "register_operand"         "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[2], operands[5])
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vf<macc_msac>.vv\t%0,%2,%3%p1
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-			operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-    operands[5] = operands[4] = operands[0];
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vfmuladd")
    (set_attr "mode" "<MODE>")])
@@ -6572,38 +6437,32 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_mul_<optab><mode>_scalar"
-  [(set (match_operand:VF 0 "register_operand"            "=&vr, ?&vr")
+  [(set (match_operand:VF 0 "register_operand"            "=&vr")
 	(if_then_else:VF
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"    "   rK,   rK")
-	     (match_operand 7 "const_int_operand"        "    i,    i")
-	     (match_operand 8 "const_int_operand"        "    i,    i")
-	     (match_operand 9 "const_int_operand"        "    i,    i")
-	     (match_operand 10 "const_int_operand"       "    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 6 "vector_length_operand"    "   rK")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (match_operand 8 "const_int_operand"        "    i")
+	     (match_operand 9 "const_int_operand"        "    i")
+	     (match_operand 10 "const_int_operand"       "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)
 	     (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
 	  (plus_minus:VF
 	    (mult:VF
 	      (vec_duplicate:VF
-	        (match_operand:<VEL> 2 "register_operand" "    f,   f"))
-	      (match_operand:VF 3 "register_operand"      "   vr,  vr"))
-	    (match_operand:VF 4 "vector_arith_operand"    "   vr,  vr"))
-	  (match_operand:VF 5 "register_operand"          "    0,  vr")))]
+	        (match_operand:<VEL> 2 "register_operand" "   f"))
+	      (match_operand:VF 3 "register_operand"      "  vr"))
+	    (match_operand:VF 4 "vector_arith_operand"    "  vr"))
+	  (match_operand:VF 5 "register_operand"          "  vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vf<macc_msac>.vf\t%0,%2,%3%p1
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-			operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-    operands[5] = operands[4] = operands[0];
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vfmuladd")
    (set_attr "mode" "<MODE>")])
@@ -6630,10 +6489,7 @@
 	  (match_operand:VF 5 "register_operand")))]
   "TARGET_VECTOR"
 {
-  /* Swap the multiplication operands if the fallback value is the
-     second of the two.  */
-  if (rtx_equal_p (operands[3], operands[5]))
-    std::swap (operands[2], operands[3]);
+  riscv_vector::prepare_ternary_operands (operands);
 })
 
 (define_insn "*pred_<nmsub_nmadd><mode>"
@@ -6705,39 +6561,33 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_mul_neg_<optab><mode>"
-  [(set (match_operand:VF 0 "register_operand"            "=&vr, ?&vr")
+  [(set (match_operand:VF 0 "register_operand"            "=&vr")
 	(if_then_else:VF
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"    "   rK,   rK")
-	     (match_operand 7 "const_int_operand"        "    i,    i")
-	     (match_operand 8 "const_int_operand"        "    i,    i")
-	     (match_operand 9 "const_int_operand"        "    i,    i")
-	     (match_operand 10 "const_int_operand"       "    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 6 "vector_length_operand"    "   rK")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (match_operand 8 "const_int_operand"        "    i")
+	     (match_operand 9 "const_int_operand"        "    i")
+	     (match_operand 10 "const_int_operand"       "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)
 	     (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
 	  (plus_minus:VF
 	    (neg:VF
 	      (mult:VF
-	        (match_operand:VF 2 "register_operand"     "   vr,   vr")
-	        (match_operand:VF 3 "register_operand"     "   vr,   vr")))
-	    (match_operand:VF 4 "vector_arith_operand"   "   vr,   vr"))
-	  (match_operand:VF 5 "register_operand"         "    0,   vr")))]
+	        (match_operand:VF 2 "register_operand"   "   vr")
+	        (match_operand:VF 3 "register_operand"   "   vr")))
+	    (match_operand:VF 4 "vector_arith_operand"   "   vr"))
+	  (match_operand:VF 5 "register_operand"         "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[2], operands[5])
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vf<nmsac_nmacc>.vv\t%0,%2,%3%p1
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-			operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-    operands[5] = operands[4] = operands[0];
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vfmuladd")
    (set_attr "mode" "<MODE>")])
@@ -6837,15 +6687,15 @@
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[8])"))])
 
 (define_insn_and_rewrite "*pred_mul_neg_<optab><mode>_scalar"
-  [(set (match_operand:VF 0 "register_operand"               "=&vr, ?&vr")
+  [(set (match_operand:VF 0 "register_operand"               "=&vr")
 	(if_then_else:VF
 	  (unspec:<VM>
-	    [(match_operand:<VM> 1 "vector_mask_operand"    "vmWc1,vmWc1")
-	     (match_operand 6 "vector_length_operand"       "   rK,   rK")
-	     (match_operand 7 "const_int_operand"           "    i,    i")
-	     (match_operand 8 "const_int_operand"           "    i,    i")
-	     (match_operand 9 "const_int_operand"           "    i,    i")
-	     (match_operand 10 "const_int_operand"          "    i,    i")
+	    [(match_operand:<VM> 1 "vector_mask_operand"    "vmWc1")
+	     (match_operand 6 "vector_length_operand"       "   rK")
+	     (match_operand 7 "const_int_operand"           "    i")
+	     (match_operand 8 "const_int_operand"           "    i")
+	     (match_operand 9 "const_int_operand"           "    i")
+	     (match_operand 10 "const_int_operand"          "    i")
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)
 	     (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
@@ -6853,23 +6703,17 @@
 	    (neg:VF
 	      (mult:VF
 	        (vec_duplicate:VF
-	          (match_operand:<VEL> 2 "register_operand" "    f,   f"))
-	        (match_operand:VF 3 "register_operand"      "   vr,  vr")))
-	    (match_operand:VF 4 "vector_arith_operand"      "   vr,  vr"))
-	  (match_operand:VF 5 "register_operand"            "    0,  vr")))]
+	          (match_operand:<VEL> 2 "register_operand" "    f"))
+	        (match_operand:VF 3 "register_operand"      "   vr")))
+	    (match_operand:VF 4 "vector_arith_operand"      "   vr"))
+	  (match_operand:VF 5 "register_operand"            "   vr")))]
   "TARGET_VECTOR
    && !rtx_equal_p (operands[3], operands[5])
    && !rtx_equal_p (operands[4], operands[5])"
-  "@
-   vmv.v.v\t%0,%4\;vf<nmsac_nmacc>.vf\t%0,%2,%3%p1
-   #"
-  "&& reload_completed
-   && !rtx_equal_p (operands[0], operands[5])"
+  "#"
+  "&& reload_completed"
   {
-    emit_insn (gen_pred_merge<mode> (operands[0], RVV_VUNDEF (<MODE>mode),
-			operands[5], operands[4], operands[1], operands[6],
-			operands[7], operands[9]));
-    operands[5] = operands[4] = operands[0];
+    riscv_vector::prepare_ternary_operands (operands, true);
   }
   [(set_attr "type" "vfmuladd")
    (set_attr "mode" "<MODE>")])
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c
new file mode 100644
index 00000000000..e05226cb2e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(TYPE, NAME, OP)                                                   \
+  void __attribute__ ((noinline, noclone))                                     \
+  test_##TYPE##_##NAME (TYPE *__restrict x, TYPE *__restrict y,                \
+			TYPE *__restrict z, TYPE *__restrict pred, int n)      \
+  {                                                                            \
+    for (int i = 0; i < n; ++i)                                                \
+      x[i] = pred[i] != 1 ? y[i] OP z[i] : y[i];                               \
+  }
+
+#define TEST_TYPE(TYPE)                                                        \
+  TEST (TYPE, add, +)                                                          \
+  TEST (TYPE, sub, -)                                                          \
+  TEST (TYPE, mul, *)                                                          \
+  TEST (TYPE, div, /)
+
+#define TEST_ALL                                                               \
+  TEST_TYPE (int8_t)                                                           \
+  TEST_TYPE (uint8_t)                                                          \
+  TEST_TYPE (int16_t)                                                          \
+  TEST_TYPE (uint16_t)                                                         \
+  TEST_TYPE (int32_t)                                                          \
+  TEST_TYPE (uint32_t)                                                         \
+  TEST_TYPE (int64_t)                                                          \
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_RDIV" 3 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c
new file mode 100644
index 00000000000..2b73536b13a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
+
+#include "cond_arith-1.c"
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 3 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c
new file mode 100644
index 00000000000..5fdeb3837ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(DATA_TYPE, PRED_TYPE, NAME, OP)                                   \
+  void __attribute__ ((noinline, noclone))                                     \
+  test_##DATA_TYPE##_##PRED_TYPE##_##NAME (DATA_TYPE *__restrict x,            \
+					   DATA_TYPE *__restrict y,            \
+					   DATA_TYPE *__restrict z,            \
+					   PRED_TYPE *__restrict pred, int n)  \
+  {                                                                            \
+    for (int i = 0; i < n; ++i)                                                \
+      x[i] = pred[i] != 1 ? y[i] OP z[i] : y[i];                               \
+  }
+
+#define TEST_TYPE(DATA_TYPE, PRED_TYPE)                                        \
+  TEST (DATA_TYPE, PRED_TYPE, add, +)                                          \
+  TEST (DATA_TYPE, PRED_TYPE, sub, -)                                          \
+  TEST (DATA_TYPE, PRED_TYPE, mul, *)                                          \
+  TEST (DATA_TYPE, PRED_TYPE, div, /)
+
+#define TEST_ALL                                                               \
+  TEST_TYPE (int32_t, int8_t)                                                  \
+  TEST_TYPE (uint32_t, int8_t)                                                 \
+  TEST_TYPE (int32_t, int16_t)                                                 \
+  TEST_TYPE (uint32_t, int16_t)                                                \
+  TEST_TYPE (int64_t, int8_t)                                                  \
+  TEST_TYPE (uint64_t, int8_t)                                                 \
+  TEST_TYPE (int64_t, int16_t)                                                 \
+  TEST_TYPE (uint64_t, int16_t)                                                \
+  TEST_TYPE (int64_t, int32_t)                                                 \
+  TEST_TYPE (uint64_t, int32_t)                                                \
+  TEST_TYPE (_Float16, int8_t)                                                 \
+  TEST_TYPE (float, int8_t)                                                    \
+  TEST_TYPE (float, int16_t)                                                   \
+  TEST_TYPE (double, int8_t)                                                   \
+  TEST_TYPE (double, int16_t)                                                  \
+  TEST_TYPE (double, int32_t)
+
+TEST_ALL
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 10 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 16 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 16 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 16 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_RDIV" 6 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c
new file mode 100644
index 00000000000..0cbe9bbb479
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
+
+#include "cond_arith-3.c"
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 10 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 10 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 10 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 10 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 6 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 10 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c
new file mode 100644
index 00000000000..cf9c95066c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(TYPE, NAME, OP)                                                   \
+  void __attribute__ ((noinline, noclone))                                     \
+  test_##TYPE##_##NAME (TYPE *__restrict x, TYPE *__restrict y,                \
+			TYPE *__restrict z, TYPE *__restrict pred, int n)      \
+  {                                                                            \
+    for (int i = 0; i < n; ++i)                                                \
+      x[i] = pred[i] != 1 ? y[i] OP z[i] : 1;                                  \
+  }
+
+#define TEST_TYPE(TYPE)                                                        \
+  TEST (TYPE, add, +)                                                          \
+  TEST (TYPE, sub, -)                                                          \
+  TEST (TYPE, mul, *)                                                          \
+  TEST (TYPE, div, /)
+
+#define TEST_ALL                                                               \
+  TEST_TYPE (int8_t)                                                           \
+  TEST_TYPE (uint8_t)                                                          \
+  TEST_TYPE (int16_t)                                                          \
+  TEST_TYPE (uint16_t)                                                         \
+  TEST_TYPE (int32_t)                                                          \
+  TEST_TYPE (uint32_t)                                                         \
+  TEST_TYPE (int64_t)                                                          \
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 11 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_RDIV" 3 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c
new file mode 100644
index 00000000000..487cf51a411
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
+
+#include "cond_arith-5.c"
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 3 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c
new file mode 100644
index 00000000000..8d4fa880710
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(TYPE, NAME, OP)                                                   \
+  void __attribute__ ((noinline, noclone))                                     \
+  test_##TYPE##_##NAME (TYPE *__restrict x, TYPE *__restrict y, TYPE z1,       \
+			TYPE z2, TYPE *__restrict pred, int n)                 \
+  {                                                                            \
+    for (int i = 0; i < n; i += 2)                                             \
+      {                                                                        \
+	x[i] = (pred[i] != 1 ? y[i] OP z1 : y[i]);                             \
+	x[i + 1] = (pred[i + 1] != 1 ? y[i + 1] OP z2 : y[i + 1]);             \
+      }                                                                        \
+  }
+
+#define TEST_TYPE(TYPE)                                                        \
+  TEST (TYPE, add, +)                                                          \
+  TEST (TYPE, sub, -)                                                          \
+  TEST (TYPE, mul, *)                                                          \
+  TEST (TYPE, div, /)
+
+#define TEST_ALL                                                               \
+  TEST_TYPE (int32_t)                                                          \
+  TEST_TYPE (uint32_t)                                                         \
+  TEST_TYPE (int64_t)                                                          \
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL
+
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 3 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c
new file mode 100644
index 00000000000..d191d4cebab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(DATA_TYPE, OTHER_TYPE, NAME, OP)                                  \
+  void __attribute__ ((noinline, noclone))                                     \
+  test_##DATA_TYPE##_##OTHER_TYPE##_##NAME (DATA_TYPE *__restrict x,           \
+					    DATA_TYPE *__restrict y,           \
+					    DATA_TYPE z1, DATA_TYPE z2,        \
+					    DATA_TYPE *__restrict pred,        \
+					    OTHER_TYPE *__restrict foo, int n) \
+  {                                                                            \
+    for (int i = 0; i < n; i += 2)                                             \
+      {                                                                        \
+	x[i] = (pred[i] != 1 ? y[i] OP z1 : y[i]);                             \
+	x[i + 1] = (pred[i + 1] != 1 ? y[i + 1] OP z2 : y[i + 1]);             \
+	foo[i] += 1;                                                           \
+	foo[i + 1] += 2;                                                       \
+      }                                                                        \
+  }
+
+#define TEST_TYPE(DATA_TYPE, OTHER_TYPE)                                       \
+  TEST (DATA_TYPE, OTHER_TYPE, add, +)                                         \
+  TEST (DATA_TYPE, OTHER_TYPE, sub, -)                                         \
+  TEST (DATA_TYPE, OTHER_TYPE, mul, *)                                         \
+  TEST (DATA_TYPE, OTHER_TYPE, div, /)
+
+#define TEST_ALL                                                               \
+  TEST_TYPE (int32_t, int8_t)                                                  \
+  TEST_TYPE (int32_t, int16_t)                                                 \
+  TEST_TYPE (uint32_t, int8_t)                                                 \
+  TEST_TYPE (uint32_t, int16_t)                                                \
+  TEST_TYPE (int64_t, int8_t)                                                  \
+  TEST_TYPE (int64_t, int16_t)                                                 \
+  TEST_TYPE (int64_t, int32_t)                                                 \
+  TEST_TYPE (uint64_t, int8_t)                                                 \
+  TEST_TYPE (uint64_t, int16_t)                                                \
+  TEST_TYPE (uint64_t, int32_t)                                                \
+  TEST_TYPE (_Float16, int8_t)                                                 \
+  TEST_TYPE (float, int8_t)                                                    \
+  TEST_TYPE (float, int16_t)                                                   \
+  TEST_TYPE (double, int8_t)                                                   \
+  TEST_TYPE (double, int16_t)                                                  \
+  TEST_TYPE (double, int32_t)
+
+TEST_ALL
+
+/* { dg-final { scan-tree-dump-times "\.COND_ADD" 40 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_SUB" 40 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_MUL" 40 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_ADD" 22 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_SUB" 22 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_MUL" 22 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_DIV" 40 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\.COND_LEN_RDIV" 22 "optimized" } } */
+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 104 } } */
+/* { dg-final { scan-assembler-times {vsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 40 } } */
+/* { dg-final { scan-assembler-times {vmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 40 } } */
+/* { dg-final { scan-assembler-times {vdivu?\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 40 } } */
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 22 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 22 } } */
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 22 } } */
+/* { dg-final { scan-assembler-times {vfdiv\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 22 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-9.c
new file mode 100644
index 00000000000..38bb613c67e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-9.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -fno-vect-cost-model -fdump-tree-optimized-details" } */
+
+#include <stdint-gcc.h>
+
+#define TEST(TYPE, NAME, OP)                                                   \
+  void __attribute__ ((noinline, noclone))                                     \
+  test_##TYPE##_##NAME (TYPE *__restrict x, TYPE *__restrict y,                \
+			TYPE *__restrict z, TYPE *__restrict pred, int n)      \
+  {                                                                            \
+    for (int i = 0; i < 128; ++i)                                              \
+      x[i] = pred[i] != 1 ? y[i] OP z[i] : y[i];                               \
+  }
+
+#define TEST_TYPE(TYPE)                                                        \
+  TEST (TYPE, add, +)                                                          \
+  TEST (TYPE, sub, -)                                                          \
+  TEST (TYPE, mul, *)                                                          \
+  TEST (TYPE, div, /)
+
+#define TEST_ALL                                                               \
+  TEST_TYPE (int8_t)                                                           \
+  TEST_TYPE (uint8_t)                                                          \
+  TEST_TYPE (int16_t)                                                          \
+  TEST_TYPE (uint16_t)                                                         \
+  TEST_TYPE (int32_t)                                                          \
+  TEST_TYPE (uint32_t)                                                         \
+  TEST_TYPE (int64_t)                                                          \
+  TEST_TYPE (uint64_t)                                                         \
+  TEST_TYPE (_Float16)                                                         \
+  TEST_TYPE (float)                                                            \
+  TEST_TYPE (double)
+
+TEST_ALL
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-1.c
new file mode 100644
index 00000000000..9d0ba59ba82
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_arith-1.c"
+
+#define N 99
+
+#undef TEST
+#define TEST(TYPE, NAME, OP)					\
+  {								\
+    TYPE x[N], y[N], z[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	y[i] = i * i;						\
+	z[i] = ((i + 2) % 3) * (i + 1);				\
+	pred[i] = i % 3;					\
+      }								\
+    test_##TYPE##_##NAME (x, y, z, pred, N);			\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = i % 3 != 1 ? y[i] OP z[i] : y[i];	\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-2.c
new file mode 100644
index 00000000000..608354de60a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-2.c
@@ -0,0 +1,4 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_arith_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-3.c
new file mode 100644
index 00000000000..20e49e7563a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-3.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_arith-3.c"
+
+#define N 99
+
+#undef TEST
+#define TEST(DATA_TYPE, PRED_TYPE, NAME, OP)			\
+  {								\
+    DATA_TYPE x[N], y[N], z[N];					\
+    PRED_TYPE pred[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	y[i] = i * i;						\
+	z[i] = ((i + 2) % 3) * (i + 1);				\
+	pred[i] = i % 3;					\
+      }								\
+    test_##DATA_TYPE##_##PRED_TYPE##_##NAME (x, y, z, pred, N);	\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	DATA_TYPE expected = i % 3 != 1 ? y[i] OP z[i] : y[i];	\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-4.c
new file mode 100644
index 00000000000..a47243c0f8a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-4.c
@@ -0,0 +1,4 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_arith_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-5.c
new file mode 100644
index 00000000000..e4cb7a66438
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-5.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_arith-5.c"
+
+#define N 99
+
+#undef TEST
+#define TEST(TYPE, NAME, OP)					\
+  {								\
+    TYPE x[N], y[N], z[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	x[i] = -1;						\
+	y[i] = i * i;						\
+	z[i] = ((i + 2) % 3) * (i + 1);				\
+	pred[i] = i % 3;					\
+      }								\
+    test_##TYPE##_##NAME (x, y, z, pred, N);			\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = i % 3 != 1 ? y[i] OP z[i] : 1;		\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-6.c
new file mode 100644
index 00000000000..717790de0ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-6.c
@@ -0,0 +1,4 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_arith_run-5.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-7.c
new file mode 100644
index 00000000000..a49525f296c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-7.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_arith-7.c"
+
+#define N 98
+
+#undef TEST
+#define TEST(TYPE, NAME, OP)					\
+  {								\
+    TYPE x[N], y[N], pred[N], z[2] = { 5, 7 };			\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	y[i] = i * i;						\
+	pred[i] = i % 3;					\
+      }								\
+    test_##TYPE##_##NAME (x, y, z[0], z[1], pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = i % 3 != 1 ? y[i] OP z[i & 1] : y[i];	\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-8.c
new file mode 100644
index 00000000000..3f06a213591
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-8.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_arith-8.c"
+
+#define N 98
+
+#undef TEST
+#define TEST(DATA_TYPE, OTHER_TYPE, NAME, OP)				\
+  {									\
+    DATA_TYPE x[N], y[N], pred[N], z[2] = { 5, 7 };			\
+    OTHER_TYPE foo[N];							\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i * i;							\
+	pred[i] = i % 3;						\
+	foo[i] = i * 5;							\
+      }									\
+    test_##DATA_TYPE##_##OTHER_TYPE##_##NAME (x, y, z[0], z[1],		\
+					      pred, foo, N);		\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	DATA_TYPE expected = i % 3 != 1 ? y[i] OP z[i & 1] : y[i];	\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-9.c
new file mode 100644
index 00000000000..280479df542
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-9.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=fixed-vlmax -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_arith-9.c"
+
+#define N 128
+
+#undef TEST
+#define TEST(TYPE, NAME, OP)					\
+  {								\
+    TYPE x[N], y[N], z[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	y[i] = i * i;						\
+	z[i] = ((i + 2) % 3) * (i + 1);				\
+	pred[i] = i % 3;					\
+      }								\
+    test_##TYPE##_##NAME (x, y, z, pred, N);			\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = i % 3 != 1 ? y[i] OP z[i] : y[i];	\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c
new file mode 100644
index 00000000000..11c5c54309b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST)		\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? y[i] + (TYPE) CONST : y[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+  T (TYPE, PRED_TYPE, half, 0.5) \
+  T (TYPE, PRED_TYPE, one, 1.0) \
+  T (TYPE, PRED_TYPE, two, 2.0) \
+  T (TYPE, PRED_TYPE, minus_half, -0.5) \
+  T (TYPE, PRED_TYPE, minus_one, -1.0) \
+  T (TYPE, PRED_TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16, int16_t) \
+  TEST_TYPE (T, float, int32_t) \
+  TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c
new file mode 100644
index 00000000000..e992459a7b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, CONST)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			TYPE *__restrict z,		\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = y[i] < 8 ? z[i] + (TYPE) CONST : y[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, half, 0.5) \
+  T (TYPE, one, 1.0) \
+  T (TYPE, two, 2.0) \
+  T (TYPE, minus_half, -0.5) \
+  T (TYPE, minus_one, -1.0) \
+  T (TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c
new file mode 100644
index 00000000000..f940d64742e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST)		\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? y[i] + (TYPE) CONST : 4;	\
+  }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+  T (TYPE, PRED_TYPE, half, 0.5) \
+  T (TYPE, PRED_TYPE, one, 1.0) \
+  T (TYPE, PRED_TYPE, two, 2.0) \
+  T (TYPE, PRED_TYPE, minus_half, -0.5) \
+  T (TYPE, PRED_TYPE, minus_one, -1.0) \
+  T (TYPE, PRED_TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16, int16_t) \
+  TEST_TYPE (T, float, int32_t) \
+  TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c
new file mode 100644
index 00000000000..e4f3e823819
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST)		\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? y[i] + (TYPE) CONST : 0;	\
+  }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+  T (TYPE, PRED_TYPE, half, 0.5) \
+  T (TYPE, PRED_TYPE, one, 1.0) \
+  T (TYPE, PRED_TYPE, two, 2.0) \
+  T (TYPE, PRED_TYPE, minus_half, -0.5) \
+  T (TYPE, PRED_TYPE, minus_one, -1.0) \
+  T (TYPE, PRED_TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16, int16_t) \
+  TEST_TYPE (T, float, int32_t) \
+  TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-1.c
new file mode 100644
index 00000000000..4ceedeb8a72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-1.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fadd-1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST)				\
+  {									\
+    TYPE x[N], y[N];							\
+    PRED_TYPE pred[N];							\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i * i;							\
+	pred[i] = i % 3;						\
+      }									\
+    test_##TYPE##_##NAME (x, y, pred, N);				\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = i % 3 != 1 ? y[i] + (TYPE) CONST : y[i];	\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-2.c
new file mode 100644
index 00000000000..d10c42c373b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-2.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fadd-2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, CONST)					\
+  {									\
+    TYPE x[N], y[N], z[N];						\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i % 13;							\
+	z[i] = i * i;							\
+      }									\
+    test_##TYPE##_##NAME (x, y, z, N);					\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = y[i] < 8 ? z[i] + (TYPE) CONST : y[i];		\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-3.c
new file mode 100644
index 00000000000..7ee291b4951
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-3.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fadd-3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST)			\
+  {								\
+    TYPE x[N], y[N];						\
+    PRED_TYPE pred[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	y[i] = i * i;						\
+	pred[i] = i % 3;					\
+      }								\
+    test_##TYPE##_##NAME (x, y, pred, N);			\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = i % 3 != 1 ? y[i] + (TYPE) CONST : 4;	\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-4.c
new file mode 100644
index 00000000000..2502b6014a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-4.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fadd-4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST)				\
+  {									\
+    TYPE x[N], y[N];							\
+    PRED_TYPE pred[N];							\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i * i;							\
+	pred[i] = i % 3;						\
+      }									\
+    test_##TYPE##_##NAME (x, y, pred, N);				\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = i % 3 != 1 ? y[i] + (TYPE) CONST : 0;		\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c
new file mode 100644
index 00000000000..0b19c54b562
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] != 1 ? a[i] OP b[i] * c : b[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, uint64_t) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfmadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c
new file mode 100644
index 00000000000..bd61c0e2edc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] != 1 ? a[i] OP b[i] * c : c;	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, uint64_t) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfmadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfnmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c
new file mode 100644
index 00000000000..c011a290908
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] != 1 ? a[i] OP b[i] * c : a[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, uint64_t) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c
new file mode 100644
index 00000000000..98ba3c1a58d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] == 1 ? a[i] OP b[i] * c : pred[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, uint64_t) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c
new file mode 100644
index 00000000000..98ba3c1a58d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] == 1 ? a[i] OP b[i] * c : pred[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, uint64_t) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c
new file mode 100644
index 00000000000..e72eb5e7603
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] ? a[i] OP b[i] * c : 5;		\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, uint64_t) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c
new file mode 100644
index 00000000000..3a69a59e8e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP, CONST)				\
+  void __attribute__ ((noipa))					\
+  test_##TYPE##_##NAME##_##CONST (TYPE *__restrict r, 		\
+				  TYPE *__restrict a,		\
+				  TYPE *__restrict b,		\
+				  TYPE *__restrict pred, int n)	\
+  {								\
+    for (int i = 0; i < n; ++i)					\
+      r[i] = pred[i] != 1 ? a[i] OP b[i] * CONST : a[i];	\
+  }
+
+#define TEST_COUNT(T, TYPE, CONST) \
+  T (TYPE, add, +, CONST) \
+  T (TYPE, sub, -, CONST)
+
+#define TEST_TYPE(T, TYPE, CONST) \
+  TEST_COUNT (T, TYPE, 2) \
+  TEST_COUNT (T, TYPE, 4) \
+  TEST_COUNT (T, TYPE, CONST)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t, 0x80) \
+  TEST_TYPE (T, uint16_t, 0x8000) \
+  TEST_TYPE (T, uint32_t, 0x80000000) \
+  TEST_TYPE (T, uint64_t, 0x8000000000000000ULL)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
+/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c
new file mode 100644
index 00000000000..4df9da8ea4e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP, CONST)				\
+  void __attribute__ ((noipa))					\
+  test_##TYPE##_##NAME##_##CONST (TYPE *__restrict r, 		\
+				  TYPE *__restrict a,		\
+				  TYPE *__restrict b,		\
+				  TYPE *__restrict pred, int n)	\
+  {								\
+    for (int i = 0; i < n; ++i)					\
+      r[i] = pred[i] != 1 ? a[i] OP b[i] * -CONST : a[i];	\
+  }
+
+#define TEST_COUNT(T, TYPE, CONST) \
+  T (TYPE, add, +, CONST) \
+  T (TYPE, sub, -, CONST)
+
+#define TEST_TYPE(T, TYPE, CONST) \
+  TEST_COUNT (T, TYPE, 2) \
+  TEST_COUNT (T, TYPE, 4) \
+  TEST_COUNT (T, TYPE, CONST)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, uint8_t, 0x80) \
+  TEST_TYPE (T, uint16_t, 0x8000) \
+  TEST_TYPE (T, uint32_t, 0x80000000) \
+  TEST_TYPE (T, uint64_t, 0x8000000000000000ULL)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
+/* { dg-final { scan-assembler-times {vnmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 12 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-1.c
new file mode 100644
index 00000000000..91578a49098
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-1.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-1.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] != 1 ? a[i] OP b[i] * (TYPE) FACTOR : b[i];	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-2.c
new file mode 100644
index 00000000000..61526b6cf79
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-2.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = (pred[i] != 1				\
+			 ? a[i] OP b[i] * (TYPE) FACTOR		\
+			 : (TYPE) FACTOR);			\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-3.c
new file mode 100644
index 00000000000..af446d9dfcf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-3.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-3.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] != 1 ? a[i] OP b[i] * (TYPE) FACTOR : a[i];	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-4.c
new file mode 100644
index 00000000000..4880a4647b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-4.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-4.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3;					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = (pred[i] == 1				\
+			 ? a[i] OP b[i] * (TYPE) FACTOR		\
+			 : pred[i]);				\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c
new file mode 100644
index 00000000000..2aa25245669
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-5.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] ? a[i] OP b[i] * (TYPE) FACTOR : 0;		\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-6.c
new file mode 100644
index 00000000000..36c3c6409a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-6.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-6.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] ? a[i] OP b[i] * (TYPE) FACTOR : 5;	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-7.c
new file mode 100644
index 00000000000..b74b4d266f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-7.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-7.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP, CONST)			\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME##_##CONST (r, a, b, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] != 1 ? a[i] OP b[i] * CONST : a[i];		\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-8.c
new file mode 100644
index 00000000000..fb9b6f28ed1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-8.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fma_fnma-8.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP, CONST)			\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME##_##CONST (r, a, b, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] != 1 ? a[i] OP b[i] * -CONST : a[i];	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
new file mode 100644
index 00000000000..fe37794afeb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST)	\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? FN (y[i], CONST) : y[i];	\
+  }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+  T (FN, TYPE, PRED_TYPE, zero, 0) \
+  T (FN, TYPE, PRED_TYPE, one, 1) \
+  T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, FN (f16), _Float16, int16_t) \
+  TEST_TYPE (T, FN (f32), float, int32_t) \
+  TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
new file mode 100644
index 00000000000..f25562b22dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			TYPE *__restrict z,		\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = y[i] < 8 ? FN (z[i], CONST) : y[i];	\
+  }
+
+#define TEST_TYPE(T, FN, TYPE) \
+  T (FN, TYPE, zero, 0) \
+  T (FN, TYPE, one, 1) \
+  T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, FN (f32), float) \
+  TEST_TYPE (T, FN (f64), double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
new file mode 100644
index 00000000000..a23f4916caa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST)	\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? FN (y[i], CONST) : 4;	\
+  }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+  T (FN, TYPE, PRED_TYPE, zero, 0) \
+  T (FN, TYPE, PRED_TYPE, one, 1) \
+  T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, FN (f16), _Float16, int16_t) \
+  TEST_TYPE (T, FN (f32), float, int32_t) \
+  TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
new file mode 100644
index 00000000000..79e4771eaf3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST)	\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? FN (y[i], CONST) : 0;	\
+  }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+  T (FN, TYPE, PRED_TYPE, zero, 0) \
+  T (FN, TYPE, PRED_TYPE, one, 1) \
+  T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, FN (f16), _Float16, int16_t) \
+  TEST_TYPE (T, FN (f32), float, int32_t) \
+  TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
new file mode 100644
index 00000000000..bbf04f61daa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fmax-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST)			\
+  {									\
+    TYPE x[N], y[N];							\
+    PRED_TYPE pred[N];							\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i * i;							\
+	pred[i] = i % 3;						\
+      }									\
+    test_##TYPE##_##NAME (x, y, pred, N);				\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : y[i];		\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
new file mode 100644
index 00000000000..ae2740f3bfe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fmax-2.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, NAME, CONST)				\
+  {									\
+    TYPE x[N], y[N], z[N];						\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i % 13;							\
+	z[i] = i * i;							\
+      }									\
+    test_##TYPE##_##NAME (x, y, z, N);					\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = y[i] < 8 ? FN (z[i], CONST) : y[i];		\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
new file mode 100644
index 00000000000..d02eba1bf71
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fmax-3.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST)	       	\
+  {								\
+    TYPE x[N], y[N];						\
+    PRED_TYPE pred[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	y[i] = i * i;						\
+	pred[i] = i % 3;					\
+      }								\
+    test_##TYPE##_##NAME (x, y, pred, N);			\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 4;	\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
new file mode 100644
index 00000000000..608a3dd0fea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fmax-4.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST)			\
+  {									\
+    TYPE x[N], y[N];							\
+    PRED_TYPE pred[N];							\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i * i;							\
+	pred[i] = i % 3;						\
+      }									\
+    test_##TYPE##_##NAME (x, y, pred, N);				\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 0;		\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
new file mode 100644
index 00000000000..f1596409312
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
new file mode 100644
index 00000000000..7c8c79ee251
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax-2.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
new file mode 100644
index 00000000000..aee0e3572b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax-3.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
new file mode 100644
index 00000000000..223c8a6938b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax-4.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
new file mode 100644
index 00000000000..31fa50aea18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
new file mode 100644
index 00000000000..13b21896c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
new file mode 100644
index 00000000000..61e347bb09e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
new file mode 100644
index 00000000000..4921464c8dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c
new file mode 100644
index 00000000000..b849cbf7933
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] != 1 ? -a[i] OP b[i] * c : b[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vfmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c
new file mode 100644
index 00000000000..842a191fca7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] != 1 ? -a[i] OP b[i] * c : c;	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vfmsub\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c
new file mode 100644
index 00000000000..83efdda0a87
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] != 1 ? -a[i] OP b[i] * c : a[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfnmadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c
new file mode 100644
index 00000000000..807320cc086
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] == 1 ? -a[i] OP b[i] * c : pred[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c
new file mode 100644
index 00000000000..807320cc086
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] == 1 ? -a[i] OP b[i] * c : pred[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c
new file mode 100644
index 00000000000..c2eb47baaa2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict r,		\
+			TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE c,	\
+			TYPE *__restrict pred, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = pred[i] ? -a[i] OP b[i] * c : 5;		\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, add, +) \
+  T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfnmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vfmsac\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-1.c
new file mode 100644
index 00000000000..29cabc9347d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-1.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fms_fnms-1.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] != 1 ? -a[i] OP b[i] * (TYPE) FACTOR : b[i];	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-2.c
new file mode 100644
index 00000000000..ef691725b35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fms_fnms-2.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = (pred[i] != 1				\
+			 ? -a[i] OP b[i] * (TYPE) FACTOR	\
+			 : (TYPE) FACTOR);			\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-3.c
new file mode 100644
index 00000000000..fe8b5f2b62b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-3.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fms_fnms-3.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] != 1 ? -a[i] OP b[i] * (TYPE) FACTOR : a[i];\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-4.c
new file mode 100644
index 00000000000..b68448de033
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-4.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fms_fnms-4.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3;					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = (pred[i] == 1				\
+			 ? -a[i] OP b[i] * (TYPE) FACTOR	\
+			 : pred[i]);				\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-5.c
new file mode 100644
index 00000000000..575494a4e6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-5.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fms_fnms-5.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] ? -a[i] OP b[i] * (TYPE) FACTOR : 0;	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-6.c
new file mode 100644
index 00000000000..e0e5bd953ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-6.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "cond_fms_fnms-6.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], pred[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	pred[i] = i % 3 < i % 5;				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N);		\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected						\
+	  = pred[i] ? -a[i] OP b[i] * (TYPE) FACTOR : 5;	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c
new file mode 100644
index 00000000000..94cec7ff0b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST)		\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? y[i] * (TYPE) CONST : y[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+  T (TYPE, PRED_TYPE, half, 0.5) \
+  T (TYPE, PRED_TYPE, two, 2.0) \
+  T (TYPE, PRED_TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16, int16_t) \
+  TEST_TYPE (T, float, int32_t) \
+  TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c
new file mode 100644
index 00000000000..c8ada38c002
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, CONST)			\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			TYPE *__restrict z,		\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = y[i] < 8 ? z[i] * (TYPE) CONST : y[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, half, 0.5) \
+  T (TYPE, two, 2.0) \
+  T (TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, float) \
+  TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c
new file mode 100644
index 00000000000..bd325ea84ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST)		\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? y[i] * (TYPE) CONST : 8;	\
+  }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+  T (TYPE, PRED_TYPE, half, 0.5) \
+  T (TYPE, PRED_TYPE, two, 2.0) \
+  T (TYPE, PRED_TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16, int16_t) \
+  TEST_TYPE (T, float, int32_t) \
+  TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c
new file mode 100644
index 00000000000..118c9a40e8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST)		\
+  void __attribute__ ((noipa))				\
+  test_##TYPE##_##NAME (TYPE *__restrict x,		\
+			TYPE *__restrict y,		\
+			PRED_TYPE *__restrict pred,	\
+			int n)				\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      x[i] = pred[i] != 1 ? y[i] * (TYPE) CONST : 0;	\
+  }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+  T (TYPE, PRED_TYPE, half, 0.5) \
+  T (TYPE, PRED_TYPE, two, 2.0) \
+  T (TYPE, PRED_TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, _Float16, int16_t) \
+  TEST_TYPE (T, float, int32_t) \
+  TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmul\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-1.c
new file mode 100644
index 00000000000..49290a878d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-1.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmul-1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST)				\
+  {									\
+    TYPE x[N], y[N];							\
+    PRED_TYPE pred[N];							\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i * i;							\
+	pred[i] = i % 3;						\
+      }									\
+    test_##TYPE##_##NAME (x, y, pred, N);				\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = i % 3 != 1 ? y[i] * (TYPE) CONST : y[i];	\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-2.c
new file mode 100644
index 00000000000..f25a24cdb9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-2.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmul-2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, CONST)					\
+  {									\
+    TYPE x[N], y[N], z[N];						\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i % 13;							\
+	z[i] = i * i;							\
+      }									\
+    test_##TYPE##_##NAME (x, y, z, N);					\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = y[i] < 8 ? z[i] * (TYPE) CONST : y[i];		\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-3.c
new file mode 100644
index 00000000000..fc958e1f02e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-3.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmul-3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST)			\
+  {								\
+    TYPE x[N], y[N];						\
+    PRED_TYPE pred[N];						\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	y[i] = i * i;						\
+	pred[i] = i % 3;					\
+      }								\
+    test_##TYPE##_##NAME (x, y, pred, N);			\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = i % 3 != 1 ? y[i] * (TYPE) CONST : 8;	\
+	if (x[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-4.c
new file mode 100644
index 00000000000..692f4cd394c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-4.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmul-4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST)				\
+  {									\
+    TYPE x[N], y[N];							\
+    PRED_TYPE pred[N];							\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	y[i] = i * i;							\
+	pred[i] = i % 3;						\
+      }									\
+    test_##TYPE##_##NAME (x, y, pred, N);				\
+    for (int i = 0; i < N; ++i)						\
+      {									\
+	TYPE expected = i % 3 != 1 ? y[i] * (TYPE) CONST : 0;		\
+	if (x[i] != expected)						\
+	  __builtin_abort ();						\
+	asm volatile ("" ::: "memory");					\
+      }									\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-1.c
new file mode 100644
index 00000000000..af1a2614f52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-1.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP)				\
+  void __attribute__ ((noinline, noclone))		\
+  test_##TYPE##_##OP (TYPE *__restrict r,		\
+		      TYPE *__restrict a,		\
+		      TYPE *__restrict b,		\
+		      TYPE *__restrict c, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = a[i] < 20 ? OP (b[i], c[i]) : b[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, bit_and) \
+  T (TYPE, bit_or) \
+  T (TYPE, bit_xor) \
+  T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vnot\.v\s+v[0-9]+,v[0-9]+} 8 } } */
+/* { dg-final { scan-assembler-times {vand\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vxor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-2.c
new file mode 100644
index 00000000000..5f7614dd092
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-2.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP)				\
+  void __attribute__ ((noinline, noclone))		\
+  test_##TYPE##_##OP (TYPE *__restrict r,		\
+		      TYPE *__restrict a,		\
+		      TYPE *__restrict b,		\
+		      TYPE *__restrict c, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = a[i] < 20 ? OP (b[i], c[i]) : c[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, bit_and) \
+  T (TYPE, bit_or) \
+  T (TYPE, bit_xor) \
+  T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vnot\.v\s+v[0-9]+,v[0-9]+} 8 } } */
+/* { dg-final { scan-assembler-times {vand\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vxor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-3.c
new file mode 100644
index 00000000000..032d12c393f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-3.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP)				\
+  void __attribute__ ((noinline, noclone))		\
+  test_##TYPE##_##OP (TYPE *__restrict r,		\
+		      TYPE *__restrict a,		\
+		      TYPE *__restrict b,		\
+		      TYPE *__restrict c, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = a[i] < 20 ? OP (b[i], c[i]) : a[i];	\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, bit_and) \
+  T (TYPE, bit_or) \
+  T (TYPE, bit_xor) \
+  T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vnot\.v\s+v[0-9]+,v[0-9]+} 8 } } */
+/* { dg-final { scan-assembler-times {vand\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vxor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-4.c
new file mode 100644
index 00000000000..e8d93377861
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-4.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP)				\
+  void __attribute__ ((noinline, noclone))		\
+  test_##TYPE##_##OP (TYPE *__restrict r,		\
+		      TYPE *__restrict a,		\
+		      TYPE *__restrict b,		\
+		      TYPE *__restrict c, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = a[i] < 20 ? OP (b[i], c[i]) : 42;		\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, bit_and) \
+  T (TYPE, bit_or) \
+  T (TYPE, bit_xor) \
+  T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vnot\.v\s+v[0-9]+,v[0-9]+} 8 } } */
+/* { dg-final { scan-assembler-times {vand\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vxor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-5.c
new file mode 100644
index 00000000000..c59ef510fd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-5.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP)				\
+  void __attribute__ ((noinline, noclone))		\
+  test_##TYPE##_##OP (TYPE *__restrict r,		\
+		      TYPE *__restrict a,		\
+		      TYPE *__restrict b,		\
+		      TYPE *__restrict c, int n)	\
+  {							\
+    for (int i = 0; i < n; ++i)				\
+      r[i] = a[i] < 20 ? OP (b[i], c[i]) : 0;		\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, bit_and) \
+  T (TYPE, bit_or) \
+  T (TYPE, bit_xor) \
+  T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vnot\.v\s+v[0-9]+,v[0-9]+} 8 } } */
+/* { dg-final { scan-assembler-times {vand\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 16 } } */
+/* { dg-final { scan-assembler-times {vor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vxor\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-1.c
new file mode 100644
index 00000000000..e741f7d6aac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_logical-1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP)					\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ((i + 2) % 3) * (i + 1);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##OP (r, a, b, c, N);				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : b[i];	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-2.c
new file mode 100644
index 00000000000..bdd697ec991
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-2.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_logical-2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP)					\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ((i + 2) % 3) * (i + 1);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##OP (r, a, b, c, N);				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : c[i];	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-3.c
new file mode 100644
index 00000000000..b48bcb19d26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-3.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_logical-3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP)					\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ((i + 2) % 3) * (i + 1);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##OP (r, a, b, c, N);				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : a[i];	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-4.c
new file mode 100644
index 00000000000..0d04e69177f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-4.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_logical-4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP)					\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ((i + 2) % 3) * (i + 1);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##OP (r, a, b, c, N);				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : 42;	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-5.c
new file mode 100644
index 00000000000..87501057c20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-5.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_logical-5.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP)					\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ((i + 2) % 3) * (i + 1);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##OP (r, a, b, c, N);				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : 0;	\
+	if (r[i] != expected)					\
+	  __builtin_abort ();					\
+	asm volatile ("" ::: "memory");				\
+      }								\
+  }
+
+int
+main (void)
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c
new file mode 100644
index 00000000000..6bf25383dee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, int n)			\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP 3 : b[i];				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c
new file mode 100644
index 00000000000..2edf38f89bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, int n)			\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP 3 : a[i];				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c
new file mode 100644
index 00000000000..84f91ee2668
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, int n)			\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP 3 : 72;				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c
new file mode 100644
index 00000000000..a4be0b35aaf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, int n)			\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP 3 : 0;					\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int8_t) \
+  TEST_TYPE (T, uint8_t) \
+  TEST_TYPE (T, int16_t) \
+  TEST_TYPE (T, uint16_t) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 8 } } */
+/* { dg-final { scan-assembler-times {vsra\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vi\s+v[0-9]+,v[0-9]+,3,v0.t} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c
new file mode 100644
index 00000000000..06a0a1aaecd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE *__restrict c, int n)	\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP c[i] : b[i];				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c
new file mode 100644
index 00000000000..3b1c4859e05
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE *__restrict c, int n)	\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP c[i] : c[i];				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 1 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c
new file mode 100644
index 00000000000..d44cf43eeb0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE *__restrict c, int n)	\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP c[i] : a[i];				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c
new file mode 100644
index 00000000000..e68289be5e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE *__restrict c, int n)	\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP c[i] : 91;				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c
new file mode 100644
index 00000000000..892bc08407d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_LOOP(TYPE, NAME, OP)					\
+  void __attribute__ ((noipa))						\
+  test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a,		\
+			TYPE *__restrict b, TYPE *__restrict c, int n)	\
+  {									\
+    for (int i = 0; i < n; ++i)						\
+      r[i] = a[i] > 20 ? b[i] OP c[i] : 0;				\
+  }
+
+#define TEST_TYPE(T, TYPE) \
+  T (TYPE, shl, <<) \
+  T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+  TEST_TYPE (T, int32_t) \
+  TEST_TYPE (T, uint32_t) \
+  TEST_TYPE (T, int64_t) \
+  TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vsll\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 4 } } */
+/* { dg-final { scan-assembler-times {vsra\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
+/* { dg-final { scan-assembler-times {vsrl\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-1.c
new file mode 100644
index 00000000000..d4ddc1cfa48
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-1.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N];					\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, N);				\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : b[i]))	\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-2.c
new file mode 100644
index 00000000000..a2eb673fbcf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-2.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N];					\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, N);				\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : a[i]))	\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-3.c
new file mode 100644
index 00000000000..e1bb44ed00f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-3.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N];					\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, N);				\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : 72))		\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-4.c
new file mode 100644
index 00000000000..c1bbe6bcc67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-4.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N];					\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, N);				\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : 0))		\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-5.c
new file mode 100644
index 00000000000..ff6b78ce576
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-5.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-5.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ~i & 7;						\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, c, N);			\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : b[i]))	\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-6.c
new file mode 100644
index 00000000000..1a3a6e938d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-6.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-6.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ~i & 7;						\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, c, N);			\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : c[i]))	\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-7.c
new file mode 100644
index 00000000000..45823c8c888
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-7.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-7.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ~i & 7;						\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, c, N);			\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : a[i]))	\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-8.c
new file mode 100644
index 00000000000..dd34df0b4cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-8.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-8.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ~i & 7;						\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, c, N);			\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : 91))	\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-9.c
new file mode 100644
index 00000000000..d822796372b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-9.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_shift-9.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP)				\
+  {								\
+    TYPE r[N], a[N], b[N], c[N];				\
+    for (int i = 0; i < N; ++i)					\
+      {								\
+	a[i] = (i & 1 ? i : 3 * i);				\
+	b[i] = (i >> 4) << (i & 15);				\
+	c[i] = ~i & 7;						\
+	asm volatile ("" ::: "memory");				\
+      }								\
+    test_##TYPE##_##NAME (r, a, b, c, N);			\
+    for (int i = 0; i < N; ++i)					\
+      if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : 0))	\
+	__builtin_abort ();					\
+  }
+
+int main ()
+{
+  TEST_ALL (TEST_LOOP)
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-1.c
new file mode 100644
index 00000000000..1a3ca9cdf11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+double foo (double *a, double *b, double *c)
+{
+  double result = 0.0;
+  for (int i = 0; i < 1024; ++i)
+    result += i & 1 ? __builtin_fma (a[i], b[i], c[i]) : 0.0;
+  return result;
+}
+
+/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-2.c
new file mode 100644
index 00000000000..cc07a047cd5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+
+#include "reduc_call-1.c"
+
+/* { dg-final { scan-assembler-times {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-3.c
new file mode 100644
index 00000000000..91004e7760f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-3.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -fno-vect-cost-model" } */
+
+#include "reduc_call-1.c"
+
+/* { dg-final { scan-assembler {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c
new file mode 100644
index 00000000000..6d00c404d2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -fno-vect-cost-model -ffast-math" } */
+
+#include "reduc_call-1.c"
+
+/* { dg-final { scan-assembler {vfmacc\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-5.c
new file mode 100644
index 00000000000..3523c0f5cd5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+double
+foo (double *restrict r, const double *restrict a, const double *restrict b,
+     const double *restrict c, double res)
+{
+  for (int i = 0; i < 1024; i++)
+    {
+      double x = __builtin_fma (a[i], b[i], c[i]);
+      res += __builtin_fma (a[i], b[i], x);
+    }
+  return res;
+}
+
+/* { dg-final { scan-assembler-times {vfredosum\.vs\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
index b41553bc2f5..1bc53cef891 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
@@ -75,6 +75,8 @@ foreach op $AUTOVEC_TEST_OPTS {
     "" "$op"
   dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/reduc/*.\[cS\]]] \
     "" "$op"
+  dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/cond/*.\[cS\]]] \
+    "" "$op"
 }
 
 # widening operation only test on LMUL < 8
-- 
2.36.3


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

* Re: [PATCH V2] RISC-V: Support CALL conditional autovec patterns
  2023-08-03  1:58 [PATCH V2] RISC-V: Support CALL conditional autovec patterns Juzhe-Zhong
@ 2023-08-03 11:03 ` Robin Dapp
  2023-08-03 12:48   ` 钟居哲
  0 siblings, 1 reply; 4+ messages in thread
From: Robin Dapp @ 2023-08-03 11:03 UTC (permalink / raw)
  To: Juzhe-Zhong, gcc-patches; +Cc: rdapp.gcc, kito.cheng, kito.cheng, jeffreyalaw

Hi Juzhe,

I would find it a bit clearer if the prepare_ternay part were a
separate patch.  As it's mostly mechanical replacements I don't
mind too much, though so it's LGTM from my side without that.

As to the lmul = 8 ICE, is the problem that the register allocator
would actually need 5 "registers" when doing the merge by itself
and we only have 4?

Regards
 Robin

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

* Re: Re: [PATCH V2] RISC-V: Support CALL conditional autovec patterns
  2023-08-03 11:03 ` Robin Dapp
@ 2023-08-03 12:48   ` 钟居哲
  2023-08-08 13:11     ` Li, Pan2
  0 siblings, 1 reply; 4+ messages in thread
From: 钟居哲 @ 2023-08-03 12:48 UTC (permalink / raw)
  To: rdapp.gcc, gcc-patches; +Cc: rdapp.gcc, kito.cheng, kito.cheng, Jeff Law

[-- Attachment #1: Type: text/plain, Size: 980 bytes --]

No. prepare_ternary can not be seperate patch.
It's a bug fix patch which is discovered in autovectorization.

Thanks for comments. I will commit it when middle-end is approved by Richi.

>> As to the lmul = 8 ICE, is the problem that the register allocator
>> would actually need 5 "registers" when doing the merge by itself
>> and we only have 4?
Yes.



juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-08-03 19:03
To: Juzhe-Zhong; gcc-patches
CC: rdapp.gcc; kito.cheng; kito.cheng; jeffreyalaw
Subject: Re: [PATCH V2] RISC-V: Support CALL conditional autovec patterns
Hi Juzhe,
 
I would find it a bit clearer if the prepare_ternay part were a
separate patch.  As it's mostly mechanical replacements I don't
mind too much, though so it's LGTM from my side without that.
 
As to the lmul = 8 ICE, is the problem that the register allocator
would actually need 5 "registers" when doing the merge by itself
and we only have 4?
 
Regards
Robin
 

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

* RE: Re: [PATCH V2] RISC-V: Support CALL conditional autovec patterns
  2023-08-03 12:48   ` 钟居哲
@ 2023-08-08 13:11     ` Li, Pan2
  0 siblings, 0 replies; 4+ messages in thread
From: Li, Pan2 @ 2023-08-08 13:11 UTC (permalink / raw)
  To: 钟居哲, rdapp.gcc, gcc-patches
  Cc: rdapp.gcc, kito.cheng, kito.cheng, Jeff Law

Committed, thanks Robin.

Pan

-----Original Message-----
From: Gcc-patches <gcc-patches-bounces+pan2.li=intel.com@gcc.gnu.org> On Behalf Of ???
Sent: Thursday, August 3, 2023 8:48 PM
To: rdapp.gcc <rdapp.gcc@gmail.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: rdapp.gcc <rdapp.gcc@gmail.com>; kito.cheng <kito.cheng@gmail.com>; kito.cheng <kito.cheng@sifive.com>; Jeff Law <jeffreyalaw@gmail.com>
Subject: Re: Re: [PATCH V2] RISC-V: Support CALL conditional autovec patterns

No. prepare_ternary can not be seperate patch.
It's a bug fix patch which is discovered in autovectorization.

Thanks for comments. I will commit it when middle-end is approved by Richi.

>> As to the lmul = 8 ICE, is the problem that the register allocator
>> would actually need 5 "registers" when doing the merge by itself
>> and we only have 4?
Yes.



juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-08-03 19:03
To: Juzhe-Zhong; gcc-patches
CC: rdapp.gcc; kito.cheng; kito.cheng; jeffreyalaw
Subject: Re: [PATCH V2] RISC-V: Support CALL conditional autovec patterns
Hi Juzhe,
 
I would find it a bit clearer if the prepare_ternay part were a
separate patch.  As it's mostly mechanical replacements I don't
mind too much, though so it's LGTM from my side without that.
 
As to the lmul = 8 ICE, is the problem that the register allocator
would actually need 5 "registers" when doing the merge by itself
and we only have 4?
 
Regards
Robin
 

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

end of thread, other threads:[~2023-08-08 13:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-03  1:58 [PATCH V2] RISC-V: Support CALL conditional autovec patterns Juzhe-Zhong
2023-08-03 11:03 ` Robin Dapp
2023-08-03 12:48   ` 钟居哲
2023-08-08 13:11     ` Li, Pan2

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