]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Support CALL conditional autovec patterns
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Thu, 3 Aug 2023 01:58:35 +0000 (09:58 +0800)
committerPan Li <pan2.li@intel.com>
Tue, 8 Aug 2023 13:07:56 +0000 (21:07 +0800)
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.

117 files changed:
gcc/config/riscv/autovec.md
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv-v.cc
gcc/config/riscv/riscv.cc
gcc/config/riscv/vector.md
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith-9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_arith_run-9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fadd_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma_run-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms_run-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmul_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_logical_run-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift-9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_shift_run-9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_call-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/rvv.exp

index c678b92192dde275b5da8f00fd27a42298ea8e8d..6cb5fa3ed2721aedea0fd6989d1dacd8f4edc46d 100644 (file)
   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
 ;; -------------------------------------------------------------------------
 ;; - 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")
 ;; - 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")
 ;; - 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")
   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
 ;; -------------------------------------------------------------------------
 ;; - 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")
   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
 ;; =========================================================================
index 53b87cb28d311415962174eac84d80eef27a9530..ac9c4b02f172f4ec5cf3e7f952174cafd188d0d6 100644 (file)
@@ -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
index f73ec8c6474765ee2511e61b29fea5b1e289f1e8..a7b2d7dd2fe007405183ac7be5244df15e12d5da 100644 (file)
@@ -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
@@ -3284,22 +3342,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
@@ -3469,8 +3545,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)
     {
@@ -3482,8 +3560,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.  */
@@ -3533,4 +3627,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
index 5248dd3febe0a9d6431e8f7bdafc7ae545c483a0..f9b53d21d1b218b23534bbf30f31736853f12469 100644 (file)
@@ -4808,7 +4808,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.
index e56a2bf4bed3a8504fe7b70ddfe2ddc6686c6b82..65b5fe456ed296d4caac870f367bbdaec8021bd6 100644 (file)
          (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>"
    (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>")])
          (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")
    (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>")])
    (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>")])
          (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>"
    (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>")])
            (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")
    (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>")])
    (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>")])
          (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>"
    (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>")])
    (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>")])
          (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>"
    (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>")])
    (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)
            (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 (file)
index 0000000..e05226c
--- /dev/null
@@ -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 (file)
index 0000000..2b73536
--- /dev/null
@@ -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 (file)
index 0000000..5fdeb38
--- /dev/null
@@ -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 (file)
index 0000000..0cbe9bb
--- /dev/null
@@ -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 (file)
index 0000000..cf9c950
--- /dev/null
@@ -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 (file)
index 0000000..487cf51
--- /dev/null
@@ -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 (file)
index 0000000..8d4fa88
--- /dev/null
@@ -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 (file)
index 0000000..d191d4c
--- /dev/null
@@ -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 (file)
index 0000000..38bb613
--- /dev/null
@@ -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 (file)
index 0000000..9d0ba59
--- /dev/null
@@ -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 (file)
index 0000000..608354d
--- /dev/null
@@ -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 (file)
index 0000000..20e49e7
--- /dev/null
@@ -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 (file)
index 0000000..a47243c
--- /dev/null
@@ -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 (file)
index 0000000..e4cb7a6
--- /dev/null
@@ -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 (file)
index 0000000..717790d
--- /dev/null
@@ -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 (file)
index 0000000..a49525f
--- /dev/null
@@ -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 (file)
index 0000000..3f06a21
--- /dev/null
@@ -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 (file)
index 0000000..280479d
--- /dev/null
@@ -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 (file)
index 0000000..11c5c54
--- /dev/null
@@ -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 (file)
index 0000000..e992459
--- /dev/null
@@ -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 (file)
index 0000000..f940d64
--- /dev/null
@@ -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 (file)
index 0000000..e4f3e82
--- /dev/null
@@ -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 (file)
index 0000000..4ceedeb
--- /dev/null
@@ -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 (file)
index 0000000..d10c42c
--- /dev/null
@@ -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 (file)
index 0000000..7ee291b
--- /dev/null
@@ -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 (file)
index 0000000..2502b60
--- /dev/null
@@ -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 (file)
index 0000000..0b19c54
--- /dev/null
@@ -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 (file)
index 0000000..bd61c0e
--- /dev/null
@@ -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 (file)
index 0000000..c011a29
--- /dev/null
@@ -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 (file)
index 0000000..98ba3c1
--- /dev/null
@@ -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 (file)
index 0000000..98ba3c1
--- /dev/null
@@ -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 (file)
index 0000000..e72eb5e
--- /dev/null
@@ -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 (file)
index 0000000..3a69a59
--- /dev/null
@@ -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 (file)
index 0000000..4df9da8
--- /dev/null
@@ -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 (file)
index 0000000..91578a4
--- /dev/null
@@ -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 (file)
index 0000000..61526b6
--- /dev/null
@@ -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 (file)
index 0000000..af446d9
--- /dev/null
@@ -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 (file)
index 0000000..4880a46
--- /dev/null
@@ -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 (file)
index 0000000..2aa2524
--- /dev/null
@@ -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 (file)
index 0000000..36c3c64
--- /dev/null
@@ -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 (file)
index 0000000..b74b4d2
--- /dev/null
@@ -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 (file)
index 0000000..fb9b6f2
--- /dev/null
@@ -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 (file)
index 0000000..fe37794
--- /dev/null
@@ -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 (file)
index 0000000..f25562b
--- /dev/null
@@ -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 (file)
index 0000000..a23f491
--- /dev/null
@@ -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 (file)
index 0000000..79e4771
--- /dev/null
@@ -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 (file)
index 0000000..bbf04f6
--- /dev/null
@@ -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 (file)
index 0000000..ae2740f
--- /dev/null
@@ -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 (file)
index 0000000..d02eba1
--- /dev/null
@@ -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 (file)
index 0000000..608a3dd
--- /dev/null
@@ -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 (file)
index 0000000..f159640
--- /dev/null
@@ -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 (file)
index 0000000..7c8c79e
--- /dev/null
@@ -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 (file)
index 0000000..aee0e35
--- /dev/null
@@ -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 (file)
index 0000000..223c8a6
--- /dev/null
@@ -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 (file)
index 0000000..31fa50a
--- /dev/null
@@ -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 (file)
index 0000000..13b2189
--- /dev/null
@@ -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 (file)
index 0000000..61e347b
--- /dev/null
@@ -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 (file)
index 0000000..4921464
--- /dev/null
@@ -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 (file)
index 0000000..b849cbf
--- /dev/null
@@ -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 (file)
index 0000000..842a191
--- /dev/null
@@ -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 (file)
index 0000000..83efdda
--- /dev/null
@@ -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 (file)
index 0000000..807320c
--- /dev/null
@@ -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 (file)
index 0000000..807320c
--- /dev/null
@@ -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 (file)
index 0000000..c2eb47b
--- /dev/null
@@ -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 (file)
index 0000000..29cabc9
--- /dev/null
@@ -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 (file)
index 0000000..ef69172
--- /dev/null
@@ -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 (file)
index 0000000..fe8b5f2
--- /dev/null
@@ -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 (file)
index 0000000..b68448d
--- /dev/null
@@ -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 (file)
index 0000000..575494a
--- /dev/null
@@ -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 (file)
index 0000000..e0e5bd9
--- /dev/null
@@ -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 (file)
index 0000000..94cec7f
--- /dev/null
@@ -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 (file)
index 0000000..c8ada38
--- /dev/null
@@ -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 (file)
index 0000000..bd325ea
--- /dev/null
@@ -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 (file)
index 0000000..118c9a4
--- /dev/null
@@ -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 (file)
index 0000000..49290a8
--- /dev/null
@@ -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 (file)
index 0000000..f25a24c
--- /dev/null
@@ -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 (file)
index 0000000..fc958e1
--- /dev/null
@@ -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 (file)
index 0000000..692f4cd
--- /dev/null
@@ -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 (file)
index 0000000..af1a261
--- /dev/null
@@ -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 (file)
index 0000000..5f7614d
--- /dev/null
@@ -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 (file)
index 0000000..032d12c
--- /dev/null
@@ -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 (file)
index 0000000..e8d9337
--- /dev/null
@@ -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 (file)
index 0000000..c59ef51
--- /dev/null
@@ -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 (file)
index 0000000..e741f7d
--- /dev/null
@@ -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 (file)
index 0000000..bdd697e
--- /dev/null
@@ -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 (file)
index 0000000..b48bcb1
--- /dev/null
@@ -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 (file)
index 0000000..0d04e69
--- /dev/null
@@ -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 (file)
index 0000000..8750105
--- /dev/null
@@ -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 (file)
index 0000000..6bf2538
--- /dev/null
@@ -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 (file)
index 0000000..2edf38f
--- /dev/null
@@ -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 (file)
index 0000000..84f91ee
--- /dev/null
@@ -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 (file)
index 0000000..a4be0b3
--- /dev/null
@@ -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 (file)
index 0000000..06a0a1a
--- /dev/null
@@ -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 (file)
index 0000000..3b1c485
--- /dev/null
@@ -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 (file)
index 0000000..d44cf43
--- /dev/null
@@ -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 (file)
index 0000000..e68289b
--- /dev/null
@@ -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 (file)
index 0000000..892bc08
--- /dev/null
@@ -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 (file)
index 0000000..d4ddc1c
--- /dev/null
@@ -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 (file)
index 0000000..a2eb673
--- /dev/null
@@ -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 (file)
index 0000000..e1bb44e
--- /dev/null
@@ -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 (file)
index 0000000..c1bbe6b
--- /dev/null
@@ -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 (file)
index 0000000..ff6b78c
--- /dev/null
@@ -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 (file)
index 0000000..1a3a6e9
--- /dev/null
@@ -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 (file)
index 0000000..45823c8
--- /dev/null
@@ -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 (file)
index 0000000..dd34df0
--- /dev/null
@@ -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 (file)
index 0000000..d822796
--- /dev/null
@@ -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 (file)
index 0000000..1a3ca9c
--- /dev/null
@@ -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 (file)
index 0000000..cc07a04
--- /dev/null
@@ -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 (file)
index 0000000..91004e7
--- /dev/null
@@ -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 (file)
index 0000000..6d00c40
--- /dev/null
@@ -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 (file)
index 0000000..3523c0f
--- /dev/null
@@ -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 } } */
index b41553bc2f592d69d09a16adb6cca8f135b06015..1bc53cef891b993c6c25787e5641fa2cdc656bad 100644 (file)
@@ -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