https://gcc.gnu.org/g:951b71cb24fb61450a13f40bcb1b01c1d6e3c4da
commit 951b71cb24fb61450a13f40bcb1b01c1d6e3c4da Author: Paul-Antoine Arras <[email protected]> Date: Wed Sep 10 10:47:36 2025 +0200 RISC-V: Add pattern for vector-scalar single widening floating-point sub This pattern enables the combine pass (or late-combine, depending on the case) to merge a float_extend'ed vec_duplicate into a minus RTL instruction. The other minus operand is already wide. Before this patch, we have four instructions, e.g.: fcvt.d.s fa0,fa0 vsetvli a5,zero,e64,m1,ta,ma vfmv.v.f v2,fa0 vfsub.vv v1,v1,v2 After, we get only one: vfwsub.wf v1,v1,fa0 gcc/ChangeLog: * config/riscv/autovec-opt.md (*vfwsub_wf_<mode>): New pattern to combine float_extend + vec_duplicate + vfsub.vv into vfwsub.wf. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfwsub.wf. * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h (DEF_VF_BINOP_WIDEN_CASE_2, DEF_VF_BINOP_WIDEN_CASE_3): Swap operands. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c: New test. (cherry picked from commit e18285867ec41f96078a02fd7049ca693bb15ecd) Diff: --- gcc/config/riscv/autovec-opt.md | 22 ++++++++++++++++++++++ .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c | 2 ++ .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c | 2 ++ .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c | 3 ++- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c | 3 ++- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c | 2 ++ .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c | 2 ++ .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h | 10 +++++----- .../riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c | 21 +++++++++++++++++++++ .../riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c | 17 +++++++++++++++++ 12 files changed, 79 insertions(+), 7 deletions(-) diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index 02f19bc6a42f..315cd1d2ad50 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@ -2238,6 +2238,28 @@ [(set_attr "type" "vfwalu")] ) +;; vfwsub.wf +(define_insn_and_split "*vfwsub_wf_<mode>" + [(set (match_operand:VWEXTF 0 "register_operand") + (minus:VWEXTF + (match_operand:VWEXTF 1 "register_operand") + (vec_duplicate:VWEXTF + (float_extend:<VEL> + (match_operand:<VSUBEL> 2 "register_operand")))))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + riscv_vector::emit_vlmax_insn (code_for_pred_single_widen_scalar (MINUS, + <MODE>mode), + riscv_vector::BINARY_OP_FRM_DYN, operands); + + DONE; + } + [(set_attr "type" "vfwalu")] +) + ;; vfadd.vf (define_insn_and_split "*vfadd_vf_<mode>" [(set (match_operand:V_VLSF 0 "register_operand") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c index 20e809010d84..8c0f0361ff34 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c @@ -29,6 +29,7 @@ DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, *, mul) DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, +, add) DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, -, sub) DEF_VF_BINOP_WIDEN_CASE_2 (_Float16, float, +, add) +DEF_VF_BINOP_WIDEN_CASE_2 (_Float16, float, -, sub) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ @@ -53,3 +54,4 @@ DEF_VF_BINOP_WIDEN_CASE_2 (_Float16, float, +, add) /* { dg-final { scan-assembler-times {vfwadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfwsub.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfwadd.wf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwsub.wf} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c index 8ecd7d0fa002..7e08e5b09174 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c @@ -29,6 +29,7 @@ DEF_VF_BINOP_WIDEN_CASE_0 (float, double, *, mul) DEF_VF_BINOP_WIDEN_CASE_0 (float, double, +, add) DEF_VF_BINOP_WIDEN_CASE_0 (float, double, -, sub) DEF_VF_BINOP_WIDEN_CASE_2 (float, double, +, add) +DEF_VF_BINOP_WIDEN_CASE_2 (float, double, -, sub) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ @@ -53,3 +54,4 @@ DEF_VF_BINOP_WIDEN_CASE_2 (float, double, +, add) /* { dg-final { scan-assembler-times {vfwadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfwsub.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfwadd.wf} 1 } } */ +/* { dg-final { scan-assembler-times {vfwsub.wf} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c index 8fe361f4f70e..ae298b65cad2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c @@ -26,4 +26,5 @@ /* { dg-final { scan-assembler-not {vfwadd.vf} } } */ /* { dg-final { scan-assembler-not {vfwsub.vf} } } */ /* { dg-final { scan-assembler-not {vfwadd.wf} } } */ -/* { dg-final { scan-assembler-times {fcvt.s.h} 8 } } */ +/* { dg-final { scan-assembler-not {vfwsub.wf} } } */ +/* { dg-final { scan-assembler-times {fcvt.s.h} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c index a1eaaa8b47fd..60f258785341 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c @@ -26,4 +26,5 @@ /* { dg-final { scan-assembler-not {vfwadd.vf} } } */ /* { dg-final { scan-assembler-not {vfwsub.vf} } } */ /* { dg-final { scan-assembler-not {vfwadd.wf} } } */ -/* { dg-final { scan-assembler-times {fcvt.d.s} 8 } } */ +/* { dg-final { scan-assembler-not {vfwsub.wf} } } */ +/* { dg-final { scan-assembler-times {fcvt.d.s} 9 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c index f799437d3ca4..e1e7407d6c18 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c @@ -33,6 +33,7 @@ DEF_VF_BINOP_WIDEN_CASE_1 (_Float16, float, *, mul) DEF_VF_BINOP_WIDEN_CASE_1 (_Float16, float, +, add) DEF_VF_BINOP_WIDEN_CASE_1 (_Float16, float, -, sub) DEF_VF_BINOP_WIDEN_CASE_3 (_Float16, float, +, add) +DEF_VF_BINOP_WIDEN_CASE_3 (_Float16, float, -, sub) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ @@ -57,3 +58,4 @@ DEF_VF_BINOP_WIDEN_CASE_3 (_Float16, float, +, add) /* { dg-final { scan-assembler {vfwadd.vf} } } */ /* { dg-final { scan-assembler {vfwsub.vf} } } */ /* { dg-final { scan-assembler {vfwadd.wf} } } */ +/* { dg-final { scan-assembler {vfwsub.wf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c index bb987e1edc0f..36e415f5849f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c @@ -33,6 +33,7 @@ DEF_VF_BINOP_WIDEN_CASE_1 (float, double, *, mul) DEF_VF_BINOP_WIDEN_CASE_1 (float, double, +, add) DEF_VF_BINOP_WIDEN_CASE_1 (float, double, -, sub) DEF_VF_BINOP_WIDEN_CASE_3 (float, double, +, add) +DEF_VF_BINOP_WIDEN_CASE_3 (float, double, -, sub) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ @@ -57,3 +58,4 @@ DEF_VF_BINOP_WIDEN_CASE_3 (float, double, +, add) /* { dg-final { scan-assembler {vfwadd.vf} } } */ /* { dg-final { scan-assembler {vfwsub.vf} } } */ /* { dg-final { scan-assembler {vfwadd.wf} } } */ +/* { dg-final { scan-assembler {vfwsub.wf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c index 50a4968718be..b3a4c7aad6a3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c @@ -26,4 +26,5 @@ /* { dg-final { scan-assembler-not {vfwadd.vf} } } */ /* { dg-final { scan-assembler-not {vfwsub.vf} } } */ /* { dg-final { scan-assembler-not {vfwadd.wf} } } */ +/* { dg-final { scan-assembler-not {vfwsub.wf} } } */ /* { dg-final { scan-assembler {fcvt.s.h} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c index 2e7ef5382150..b19ffd82ba86 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c @@ -26,4 +26,5 @@ /* { dg-final { scan-assembler-not {vfwadd.vf} } } */ /* { dg-final { scan-assembler-not {vfwsub.vf} } } */ /* { dg-final { scan-assembler-not {vfwadd.wf} } } */ +/* { dg-final { scan-assembler-not {vfwsub.wf} } } */ /* { dg-final { scan-assembler {fcvt.d.s} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h index 479a6fa72229..4a3615d2d6f1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h @@ -259,7 +259,7 @@ DEF_MAX_1 (double) unsigned n) \ { \ for (unsigned i = 0; i < n; i++) \ - out[i] = (T2) f OP in[i]; \ + out[i] = in[i] OP (T2) f; \ } #define DEF_VF_BINOP_WIDEN_CASE_2_WRAP(T1, T2, OP, NAME) \ DEF_VF_BINOP_WIDEN_CASE_2 (T1, T2, OP, NAME) @@ -276,10 +276,10 @@ DEF_MAX_1 (double) { \ for (int i = 0; i < n; i++) \ { \ - dst[i] = (TYPE2) * a OP b[i]; \ - dst2[i] = (TYPE2) * a2 OP b[i]; \ - dst3[i] = (TYPE2) * a2 OP b2[i]; \ - dst4[i] = (TYPE2) * a OP b2[i]; \ + dst[i] = b[i] OP (TYPE2) * a; \ + dst2[i] = b[i] OP (TYPE2) * a2; \ + dst3[i] = b2[i] OP (TYPE2) * a2; \ + dst4[i] = b2[i] OP (TYPE2) * a; \ } \ } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c new file mode 100644 index 000000000000..ea1c06e76383 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c @@ -0,0 +1,21 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-require-effective-target riscv_v_ok } */ +/* { dg-require-effective-target riscv_zvfh_ok } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-add-options "riscv_zvfh" } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_binop.h" + +#define T1 _Float16 +#define T2 float +#define NAME sub +#define OP - + +DEF_VF_BINOP_WIDEN_CASE_2_WRAP (T1, T2, OP, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_BINOP_WIDEN_CASE_2_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -32768 +#define SINGLE + +#include "vf_binop_widen_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c new file mode 100644 index 000000000000..813f02094b34 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c @@ -0,0 +1,17 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_binop.h" + +#define T1 float +#define T2 double +#define NAME sub +#define OP - + +DEF_VF_BINOP_WIDEN_CASE_2_WRAP (T1, T2, OP, NAME) + +#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_BINOP_WIDEN_CASE_2_WRAP(T1, T2, NAME, out, in, f, n) +#define LIMIT -2147483648 +#define SINGLE + +#include "vf_binop_widen_run.h"
