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"

Reply via email to