LGTM :)

On Wed, Sep 10, 2025 at 6:24 PM Paul-Antoine Arras <par...@baylibre.com> wrote:
>
> 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.
> ---
>  gcc/config/riscv/autovec-opt.md               | 22 +++++++++++++++++++
>  .../riscv/rvv/autovec/vx_vf/vf-1-f16.c        |  2 ++
>  .../riscv/rvv/autovec/vx_vf/vf-1-f32.c        |  2 ++
>  .../riscv/rvv/autovec/vx_vf/vf-2-f16.c        |  3 ++-
>  .../riscv/rvv/autovec/vx_vf/vf-2-f32.c        |  3 ++-
>  .../riscv/rvv/autovec/vx_vf/vf-3-f16.c        |  2 ++
>  .../riscv/rvv/autovec/vx_vf/vf-3-f32.c        |  2 ++
>  .../riscv/rvv/autovec/vx_vf/vf-4-f16.c        |  1 +
>  .../riscv/rvv/autovec/vx_vf/vf-4-f32.c        |  1 +
>  .../riscv/rvv/autovec/vx_vf/vf_binop.h        | 10 ++++-----
>  .../rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c   | 21 ++++++++++++++++++
>  .../rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c   | 17 ++++++++++++++
>  12 files changed, 79 insertions(+), 7 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c
>
> diff --git gcc/config/riscv/autovec-opt.md gcc/config/riscv/autovec-opt.md
> index 02f19bc6a42..315cd1d2ad5 100644
> --- gcc/config/riscv/autovec-opt.md
> +++ gcc/config/riscv/autovec-opt.md
> @@ -2238,6 +2238,28 @@ (define_insn_and_split "*vfwsub_vf_<mode>"
>    [(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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
> index 20e809010d8..8c0f0361ff3 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
> index 8ecd7d0fa00..7e08e5b0917 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c
> index 8fe361f4f70..ae298b65cad 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c
> index a1eaaa8b47f..60f25878534 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c
> index f799437d3ca..e1e7407d6c1 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c
> index bb987e1edc0..36e415f5849 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c
> index 50a4968718b..b3a4c7aad6a 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c
> index 2e7ef538215..b19ffd82ba8 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c
> +++ 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 gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h
> index 479a6fa7222..4a3615d2d6f 100644
> --- gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h
> +++ 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 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f16.c
> new file mode 100644
> index 00000000000..ea1c06e7638
> --- /dev/null
> +++ 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 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c 
> gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwsub-run-2-f32.c
> new file mode 100644
> index 00000000000..813f02094b3
> --- /dev/null
> +++ 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"
> --
> 2.39.5
>

Reply via email to