]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add pattern for vector-scalar widening floating-point add
authorPaul-Antoine Arras <parras@baylibre.com>
Fri, 5 Sep 2025 16:49:24 +0000 (18:49 +0200)
committerPaul-Antoine Arras <parras@baylibre.com>
Mon, 8 Sep 2025 13:37:30 +0000 (15:37 +0200)
This pattern enables the combine pass (or late-combine, depending on the case)
to merge a float_extend'ed vec_duplicate into a plus RTL instruction.

Before this patch, we have four instructions, e.g.:
  fcvt.d.s        fa0,fa0
  vsetvli         a5,zero,e64,m1,ta,ma
  vfmv.v.f        v3,fa0
  vfwadd.wv       v1,v3,v2

After, we get only one:
  vfwadd.vf       v1,v2,fa0

gcc/ChangeLog:

* config/riscv/autovec-opt.md (*vfwadd_vf_<mode>): New pattern to
combine float_extend + vec_duplicate + vfwadd.vv into vfwadd.vf.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfwadd.
* 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_0): Fix OP.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c: New test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c: New test.

12 files changed:
gcc/config/riscv/autovec-opt.md
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c [new file with mode: 0644]

index 1c1cf76995b4a81bdc915cf8fc88def74cf6df8b..dbbade34dce3d823106c7b0b2f5e02f8f7e87696 100644 (file)
   [(set_attr "type" "vfwmul")]
 )
 
+;; vfwadd.vf
+(define_insn_and_split "*vfwadd_vf_<mode>"
+  [(set (match_operand:VWEXTF 0 "register_operand")
+    (plus:VWEXTF
+      (float_extend:VWEXTF
+       (match_operand:<V_DOUBLE_TRUNC> 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_dual_widen_scalar (PLUS,
+                                                                   <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")
index 53969931032eea674a075f1cf06cf416a4e493dc..696b750806599c1dcfec026208ac994e1eb613e7 100644 (file)
@@ -26,6 +26,7 @@ DEF_VF_BINOP_CASE_2_WRAP (_Float16, MIN_FUNC_1_WRAP (_Float16), min)
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, MAX_FUNC_0_WRAP (_Float16), max)
 DEF_VF_BINOP_CASE_2_WRAP (_Float16, MAX_FUNC_1_WRAP (_Float16), max)
 DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, *, mul)
+DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, +, add)
 
 /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */
@@ -47,3 +48,4 @@ DEF_VF_BINOP_WIDEN_CASE_0 (_Float16, float, *, mul)
 /* { dg-final { scan-assembler-times {vfmin.vf} 2 } } */
 /* { dg-final { scan-assembler-times {vfmax.vf} 2 } } */
 /* { dg-final { scan-assembler-times {vfwmul.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfwadd.vf} 1 } } */
index 9756184347b465578e39e6c34505a52f2e1ac10c..7f746d8eb6aa76b9630444eda929410bed3cdf5b 100644 (file)
@@ -26,6 +26,7 @@ DEF_VF_BINOP_CASE_2_WRAP (float, MIN_FUNC_1_WRAP (float), min)
 DEF_VF_BINOP_CASE_2_WRAP (float, MAX_FUNC_0_WRAP (float), max)
 DEF_VF_BINOP_CASE_2_WRAP (float, MAX_FUNC_1_WRAP (float), max)
 DEF_VF_BINOP_WIDEN_CASE_0 (float, double, *, mul)
+DEF_VF_BINOP_WIDEN_CASE_0 (float, double, +, add)
 
 /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */
 /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */
@@ -47,3 +48,4 @@ DEF_VF_BINOP_WIDEN_CASE_0 (float, double, *, mul)
 /* { dg-final { scan-assembler-times {vfmin.vf} 2 } } */
 /* { dg-final { scan-assembler-times {vfmax.vf} 2 } } */
 /* { dg-final { scan-assembler-times {vfwmul.vf} 1 } } */
+/* { dg-final { scan-assembler-times {vfwadd.vf} 1 } } */
index 1712076031ddd0e6c42950ca612d15d4253392a7..0ecfb6209e62e61e5f7adeebee7fa1175d9b9a05 100644 (file)
@@ -23,4 +23,5 @@
 /* { dg-final { scan-assembler-not {vfmin.vf} } } */
 /* { dg-final { scan-assembler-not {vfmax.vf} } } */
 /* { dg-final { scan-assembler-not {vfwmul.vf} } } */
-/* { dg-final { scan-assembler-times {fcvt.s.h} 5 } } */
+/* { dg-final { scan-assembler-not {vfwadd.vf} } } */
+/* { dg-final { scan-assembler-times {fcvt.s.h} 6 } } */
index 2938bfbc1e35f484b3a06dd76b0f0e2ed9646fbf..d48777cf444585c5b6d84d28ece97ccad3835314 100644 (file)
@@ -23,4 +23,5 @@
 /* { dg-final { scan-assembler-not {vfmin.vf} } } */
 /* { dg-final { scan-assembler-not {vfmax.vf} } } */
 /* { dg-final { scan-assembler-not {vfwmul.vf} } } */
-/* { dg-final { scan-assembler-times {fcvt.d.s} 5 } } */
+/* { dg-final { scan-assembler-not {vfwadd.vf} } } */
+/* { dg-final { scan-assembler-times {fcvt.d.s} 6 } } */
index 54db9809fe9e98b39efb05f50b09f45a7079cce7..8e670a3c13accc9203de804232266bcc26428e26 100644 (file)
@@ -30,6 +30,7 @@ DEF_VF_BINOP_CASE_3_WRAP (_Float16, MAX_FUNC_0_WRAP (_Float16), max,
 DEF_VF_BINOP_CASE_3_WRAP (_Float16, MAX_FUNC_1_WRAP (_Float16), max,
                          VF_BINOP_FUNC_BODY_X128)
 DEF_VF_BINOP_WIDEN_CASE_1 (_Float16, float, *, mul)
+DEF_VF_BINOP_WIDEN_CASE_1 (_Float16, float, +, add)
 
 /* { dg-final { scan-assembler {vfmadd.vf} } } */
 /* { dg-final { scan-assembler {vfmsub.vf} } } */
@@ -51,3 +52,4 @@ DEF_VF_BINOP_WIDEN_CASE_1 (_Float16, float, *, mul)
 /* { dg-final { scan-assembler {vfmin.vf} } } */
 /* { dg-final { scan-assembler {vfmax.vf} } } */
 /* { dg-final { scan-assembler {vfwmul.vf} } } */
+/* { dg-final { scan-assembler {vfwadd.vf} } } */
index 97791cd83ce3692cd9a523a50cd7eaaf36e51a01..3c2e7f510b023788fa32258459d1bbbaff9be869 100644 (file)
@@ -30,6 +30,7 @@ DEF_VF_BINOP_CASE_3_WRAP (float, MAX_FUNC_0_WRAP (float), max,
 DEF_VF_BINOP_CASE_3_WRAP (float, MAX_FUNC_1_WRAP (float), max,
                          VF_BINOP_FUNC_BODY_X128)
 DEF_VF_BINOP_WIDEN_CASE_1 (float, double, *, mul)
+DEF_VF_BINOP_WIDEN_CASE_1 (float, double, +, add)
 
 /* { dg-final { scan-assembler {vfmadd.vf} } } */
 /* { dg-final { scan-assembler {vfmsub.vf} } } */
@@ -51,3 +52,4 @@ DEF_VF_BINOP_WIDEN_CASE_1 (float, double, *, mul)
 /* { dg-final { scan-assembler {vfmin.vf} } } */
 /* { dg-final { scan-assembler {vfmax.vf} } } */
 /* { dg-final { scan-assembler {vfwmul.vf} } } */
+/* { dg-final { scan-assembler {vfwadd.vf} } } */
index b5c94148d3712abae6f931c48f6bdf2ab48bdfb9..069e82a27a5d85fd3ab719890ede10fd470e3613 100644 (file)
@@ -23,4 +23,5 @@
 /* { dg-final { scan-assembler-not {vfmin.vf} } } */
 /* { dg-final { scan-assembler-not {vfmax.vf} } } */
 /* { dg-final { scan-assembler-not {vfwmul.vf} } } */
+/* { dg-final { scan-assembler-not {vfwadd.vf} } } */
 /* { dg-final { scan-assembler {fcvt.s.h} } } */
index 086cf75fe418be60c2ceb871085a3dc11804032e..62e7aef82dd924eafef887dee8e59468e3140569 100644 (file)
@@ -23,4 +23,5 @@
 /* { dg-final { scan-assembler-not {vfmin.vf} } } */
 /* { dg-final { scan-assembler-not {vfmax.vf} } } */
 /* { dg-final { scan-assembler-not {vfwmul.vf} } } */
+/* { dg-final { scan-assembler-not {vfwadd.vf} } } */
 /* { dg-final { scan-assembler {fcvt.d.s} } } */
index c9253e9867a4b1c854f21b4ac127dd8feef4eeb3..1d97ea4f4828e839dc64194d03cfe4dea910cd7d 100644 (file)
@@ -37,7 +37,7 @@
                                                   unsigned n)                 \
   {                                                                            \
     for (unsigned i = 0; i < n; i++)                                           \
-      out[i] = (T2) f * (T2) in[i];                                            \
+      out[i] = (T2) f OP (T2) in[i];                                           \
   }
 #define DEF_VF_BINOP_WIDEN_CASE_0_WRAP(T1, T2, OP, NAME)                       \
   DEF_VF_BINOP_WIDEN_CASE_0 (T1, T2, OP, NAME)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c
new file mode 100644 (file)
index 0000000..33b28f1
--- /dev/null
@@ -0,0 +1,20 @@
+/* { 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 add
+#define OP +
+
+DEF_VF_BINOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NAME)
+
+#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_BINOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n)
+#define LIMIT -32768
+
+#include "vf_binop_widen_run.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c
new file mode 100644 (file)
index 0000000..981df91
--- /dev/null
@@ -0,0 +1,16 @@
+/* { 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 add
+#define OP +
+
+DEF_VF_BINOP_WIDEN_CASE_0_WRAP (T1, T2, OP, NAME)
+
+#define TEST_RUN(T1, T2, NAME, out, in, f, n) RUN_VF_BINOP_WIDEN_CASE_0_WRAP(T1, T2, NAME, out, in, f, n)
+#define LIMIT -2147483648
+
+#include "vf_binop_widen_run.h"