aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Dapp <rdapp@ventanamicro.com>2024-05-16 12:43:43 +0200
committerRobin Dapp <rdapp@ventanamicro.com>2024-05-31 21:54:48 +0200
commit9781885a624f3e29634d95c14cd10940cefb1a5a (patch)
tree47b62b8c3f2415d36dc0d840b86270d29c2d74ac
parenta2fd0812a54cf51520f15e900df4cfb5874b75ed (diff)
downloadgcc-9781885a624f3e29634d95c14cd10940cefb1a5a.zip
gcc-9781885a624f3e29634d95c14cd10940cefb1a5a.tar.gz
gcc-9781885a624f3e29634d95c14cd10940cefb1a5a.tar.bz2
RISC-V: Split vwadd.wx and vwsub.wx and add helpers.
vwadd.wx and vwsub.wx have the same problem vfwadd.wf had. This patch splits the insn pattern in the same way vfwadd.wf was split. It also adds two patterns to recognize extended scalars. In practice those do not provide a lot of improvement over what we already have but in some instances we can get rid of redundant extensions. gcc/ChangeLog: * config/riscv/vector.md: Split vwadd.wx/vwsub.wx pattern and add extended_scalar patterns. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/pr115068.c: Add vwadd.wx/vwsub.wx tests. * gcc.target/riscv/rvv/base/pr115068-run.c: Include pr115068.c. * gcc.target/riscv/rvv/base/vwaddsub-1.c: New test.
-rw-r--r--gcc/config/riscv/vector.md62
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr115068-run.c24
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/pr115068.c26
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/base/vwaddsub-1.c48
4 files changed, 128 insertions, 32 deletions
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 92bbb8c..dccf76f 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -3877,27 +3877,71 @@
(set_attr "mode" "<V_DOUBLE_TRUNC>")])
(define_insn "@pred_single_widen_<plus_minus:optab><any_extend:su><mode>_scalar"
- [(set (match_operand:VWEXTI 0 "register_operand" "=vr, vr")
+ [(set (match_operand:VWEXTI 0 "register_operand" "=vd,vd, vr, vr")
(if_then_else:VWEXTI
(unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1,vmWc1")
- (match_operand 5 "vector_length_operand" " rK, rK")
- (match_operand 6 "const_int_operand" " i, i")
- (match_operand 7 "const_int_operand" " i, i")
- (match_operand 8 "const_int_operand" " i, i")
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK,rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(plus_minus:VWEXTI
- (match_operand:VWEXTI 3 "register_operand" " vr, vr")
+ (match_operand:VWEXTI 3 "register_operand" " vr,vr, vr, vr")
(any_extend:VWEXTI
(vec_duplicate:<V_DOUBLE_TRUNC>
- (match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ, rJ"))))
- (match_operand:VWEXTI 2 "vector_merge_operand" " vu, 0")))]
+ (match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ,rJ, rJ, rJ"))))
+ (match_operand:VWEXTI 2 "vector_merge_operand" " vu, 0, vu, 0")))]
"TARGET_VECTOR"
"vw<plus_minus:insn><any_extend:u>.wx\t%0,%3,%z4%p1"
[(set_attr "type" "vi<widen_binop_insn_type>")
(set_attr "mode" "<V_DOUBLE_TRUNC>")])
+(define_insn "@pred_single_widen_add<any_extend:su><mode>_extended_scalar"
+ [(set (match_operand:VWEXTI 0 "register_operand" "=vd,vd, vr, vr")
+ (if_then_else:VWEXTI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK,rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (plus:VWEXTI
+ (vec_duplicate:VWEXTI
+ (any_extend:<VEL>
+ (match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ,rJ, rJ, rJ")))
+ (match_operand:VWEXTI 3 "register_operand" " vr,vr, vr, vr"))
+ (match_operand:VWEXTI 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "vwadd<any_extend:u>.wx\t%0,%3,%z4%p1"
+ [(set_attr "type" "viwalu")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+(define_insn "@pred_single_widen_sub<any_extend:su><mode>_extended_scalar"
+ [(set (match_operand:VWEXTI 0 "register_operand" "=vd,vd, vr, vr")
+ (if_then_else:VWEXTI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK,rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (minus:VWEXTI
+ (match_operand:VWEXTI 3 "register_operand" " vr,vr, vr, vr")
+ (vec_duplicate:VWEXTI
+ (any_extend:<VEL>
+ (match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ,rJ, rJ, rJ"))))
+ (match_operand:VWEXTI 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "vwsub<any_extend:u>.wx\t%0,%3,%z4%p1"
+ [(set_attr "type" "viwalu")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
(define_insn "@pred_widen_mulsu<mode>"
[(set (match_operand:VWEXTI 0 "register_operand" "=&vr,&vr")
(if_then_else:VWEXTI
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068-run.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068-run.c
index 95ec8e0..d552eb5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068-run.c
@@ -3,26 +3,4 @@
/* { dg-add-options riscv_v } */
/* { dg-additional-options "-std=gnu99" } */
-#include <stdint.h>
-#include <riscv_vector.h>
-
-vfloat64m8_t
-test_vfwadd_wf_f64m8_m (vbool8_t vm, vfloat64m8_t vs2, float rs1, size_t vl)
-{
- return __riscv_vfwadd_wf_f64m8_m (vm, vs2, rs1, vl);
-}
-
-char global_memory[1024];
-void *fake_memory = (void *) global_memory;
-
-int
-main ()
-{
- asm volatile ("fence" ::: "memory");
- vfloat64m8_t vfwadd_wf_f64m8_m_vd = test_vfwadd_wf_f64m8_m (
- __riscv_vreinterpret_v_i8m1_b8 (__riscv_vundefined_i8m1 ()),
- __riscv_vundefined_f64m8 (), 1.0, __riscv_vsetvlmax_e64m8 ());
- asm volatile ("" ::"vr"(vfwadd_wf_f64m8_m_vd) : "memory");
-
- return 0;
-}
+#include "pr115068.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068.c
index 6d68003..8359e81 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr115068.c
@@ -11,6 +11,18 @@ test_vfwadd_wf_f64m8_m (vbool8_t vm, vfloat64m8_t vs2, float rs1, size_t vl)
return __riscv_vfwadd_wf_f64m8_m (vm, vs2, rs1, vl);
}
+vint64m8_t
+test_vwadd_wx_i64m8_m (vbool8_t vm, vint64m8_t vs2, int32_t rs1, size_t vl)
+{
+ return __riscv_vwadd_wx_i64m8_m (vm, vs2, rs1, vl);
+}
+
+vint64m8_t
+test_vwsub_wx_i64m8_m (vbool8_t vm, vint64m8_t vs2, int32_t rs1, size_t vl)
+{
+ return __riscv_vwsub_wx_i64m8_m (vm, vs2, rs1, vl);
+}
+
char global_memory[1024];
void *fake_memory = (void *) global_memory;
@@ -23,7 +35,21 @@ main ()
__riscv_vundefined_f64m8 (), 1.0, __riscv_vsetvlmax_e64m8 ());
asm volatile ("" ::"vr"(vfwadd_wf_f64m8_m_vd) : "memory");
+ asm volatile ("fence" ::: "memory");
+ vint64m8_t vwadd_wx_i64m8_m_vd = test_vwadd_wx_i64m8_m (
+ __riscv_vreinterpret_v_i8m1_b8 (__riscv_vundefined_i8m1 ()),
+ __riscv_vundefined_i64m8 (), 1.0, __riscv_vsetvlmax_e64m8 ());
+ asm volatile ("" ::"vr"(vwadd_wx_i64m8_m_vd) : "memory");
+
+ asm volatile ("fence" ::: "memory");
+ vint64m8_t vwsub_wx_i64m8_m_vd = test_vwsub_wx_i64m8_m (
+ __riscv_vreinterpret_v_i8m1_b8 (__riscv_vundefined_i8m1 ()),
+ __riscv_vundefined_i64m8 (), 1.0, __riscv_vsetvlmax_e64m8 ());
+ asm volatile ("" ::"vr"(vwsub_wx_i64m8_m_vd) : "memory");
+
return 0;
}
/* { dg-final { scan-assembler-not "vfwadd.wf\tv0.*v0" } } */
+/* { dg-final { scan-assembler-not "vwadd.wx\tv0.*v0" } } */
+/* { dg-final { scan-assembler-not "vwsub.wx\tv0.*v0" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vwaddsub-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/vwaddsub-1.c
new file mode 100644
index 0000000..196215a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vwaddsub-1.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-add-options riscv_v } */
+/* { dg-additional-options "-std=gnu99 -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include <stdint.h>
+#include <riscv_vector.h>
+
+/*
+** vwadd_wx_i64m8_m:
+** vsetvli\s+zero,[a-x0-9]+,\s*e32,\s*m4,\s*t[au],\s*m[au]
+** vwadd\.wx\tv8,v8,a0,v0.t
+** ret
+*/
+vint64m8_t
+vwadd_wx_i64m8_m (vbool8_t vm, vint64m8_t vs2, int64_t rs1, size_t vl)
+{
+ return __riscv_vwadd_wx_i64m8_m (vm, vs2, rs1, vl);
+}
+
+/*
+** vwsub_wx_i64m8_m:
+** vsetvli\s+zero,[a-x0-9]+,\s*e32,\s*m4,\s*t[au],\s*m[au]
+** vwsub\.wx\tv8,v8,a0,v0.t
+** ret
+*/
+vint64m8_t
+vwsub_wx_i64m8_m (vbool8_t vm, vint64m8_t vs2, int64_t rs1, size_t vl)
+{
+ return __riscv_vwsub_wx_i64m8_m (vm, vs2, rs1, vl);
+}
+
+/*
+** vwadd_wx_i32m8_m:
+** ...
+** vsetvli\s+zero,[a-x0-9]+,\s*e16,\s*m4,\s*t[au],\s*m[au]
+** vwadd\.wx\tv8,v8,a5,v0.t
+** ret
+*/
+
+extern int8_t bla;
+
+vint32m8_t
+vwadd_wx_i32m8_m (vbool4_t vm, vint32m8_t vs2, int16_t rs1, size_t vl)
+{
+ return __riscv_vwadd_wx_i32m8_m (vm, vs2, bla, vl);
+}
+
+/* { dg-final { check-function-bodies "**" "" } } */