[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] RISC-V: Add pattern for vector-scalar widening floating-point add
Jeff Law
law@gcc.gnu.org
Sat Sep 13 16:32:18 GMT 2025
https://gcc.gnu.org/g:e386a029c713f016e82d61fab79ec781b3235c26
commit e386a029c713f016e82d61fab79ec781b3235c26
Author: Paul-Antoine Arras <parras@baylibre.com>
Date: Fri Sep 5 18:49:24 2025 +0200
RISC-V: Add pattern for vector-scalar widening floating-point add
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.
(cherry picked from commit 2abfcc6cfc9cd82fbbef47f2b03ee7595277023e)
Diff:
---
gcc/config/riscv/autovec-opt.md | 23 ++++++++++++++++++++++
.../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 | 2 +-
.../riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c | 20 +++++++++++++++++++
.../riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c | 16 +++++++++++++++
12 files changed, 74 insertions(+), 3 deletions(-)
diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index 1c1cf76995b4..dbbade34dce3 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -2170,6 +2170,29 @@
[(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")
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 53969931032e..696b75080659 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
@@ -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 } } */
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 9756184347b4..7f746d8eb6aa 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
@@ -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 } } */
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 1712076031dd..0ecfb6209e62 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
@@ -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 } } */
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 2938bfbc1e35..d48777cf4445 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
@@ -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 } } */
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 54db9809fe9e..8e670a3c13ac 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
@@ -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} } } */
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 97791cd83ce3..3c2e7f510b02 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
@@ -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} } } */
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 b5c94148d371..069e82a27a5d 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
@@ -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} } } */
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 086cf75fe418..62e7aef82dd9 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
@@ -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} } } */
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 c9253e9867a4..1d97ea4f4828 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
@@ -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
index 000000000000..33b28f15c5e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f16.c
@@ -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
index 000000000000..981df91f1533
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfwadd-run-1-f32.c
@@ -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"
More information about the Gcc-cvs
mailing list