The Zvabd specification only defines vabd[u]/vwabda[u] for SEW 8 or 16.
We should not allow unsupported SEW instructions to be generated.
gcc/ChangeLog:
* config/riscv/autovec-opt.md (*vwabda<su><mode>): Limit mode to
VWEXTI_HS.
(*vwabda_right<su><mode>): Ditto.
* config/riscv/autovec.md (<su>abd<mode>3): Limit mode to VI_QH.
* config/riscv/vector-iterators.md: New iterators.
* config/riscv/vector.md: Limit modes in Zvabd patterns except
vabs.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/zvabd-2.c: New test.
---
gcc/config/riscv/autovec-opt.md | 16 +++++-----
gcc/config/riscv/autovec.md | 8 ++---
gcc/config/riscv/vector-iterators.md | 32 +++++++++++++++++++
gcc/config/riscv/vector.md | 20 ++++++------
.../gcc.target/riscv/rvv/autovec/zvabd-2.c | 28 ++++++++++++++++
5 files changed, 82 insertions(+), 22 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-2.c
diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index cc84f6336c5..d210b05a8a2 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -685,14 +685,14 @@ (define_insn_and_split
"*single_widen_add<any_extend:su><mode>"
[(set_attr "type" "viwalu")])
(define_insn_and_split "*vwabda<su><mode>"
- [(set (match_operand:VWEXTI 0 "register_operand" "+&vr")
- (plus:VWEXTI
- (zero_extend:VWEXTI
+ [(set (match_operand:VWEXTI_HS 0 "register_operand" "+&vr")
+ (plus:VWEXTI_HS
+ (zero_extend:VWEXTI_HS
(unspec:<V_DOUBLE_TRUNC>
[(match_operand:<V_DOUBLE_TRUNC> 1 "register_operand" "vr")
(match_operand:<V_DOUBLE_TRUNC> 2 "register_operand" "vr")]
UNSPEC_VABD))
- (match_operand:VWEXTI 3 "register_operand" "0")))]
+ (match_operand:VWEXTI_HS 3 "register_operand" "0")))]
"TARGET_ZVABD && can_create_pseudo_p ()"
"#"
"&& 1"
@@ -707,10 +707,10 @@ (define_insn_and_split "*vwabda<su><mode>"
;; have this since we don't canonicalize the plus in the presence of an unspec.
(define_insn_and_split "*vwabda_right<su><mode>"
- [(set (match_operand:VWEXTI 0 "register_operand" "+&vr")
- (plus:VWEXTI
- (match_operand:VWEXTI 1 "register_operand" "0")
- (zero_extend:VWEXTI
+ [(set (match_operand:VWEXTI_HS 0 "register_operand" "+&vr")
+ (plus:VWEXTI_HS
+ (match_operand:VWEXTI_HS 1 "register_operand" "0")
+ (zero_extend:VWEXTI_HS
(unspec:<V_DOUBLE_TRUNC>
[(match_operand:<V_DOUBLE_TRUNC> 2 "register_operand" "vr")
(match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "vr")]
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f6ec19d0025..964eed927c8 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -3080,10 +3080,10 @@ (define_expand "mask_len_strided_store_<mode>"
; == Absolute difference (not including sum)
; ========
(define_insn_and_split "<su>abd<mode>3"
- [(set (match_operand:V_VLSI 0 "register_operand" "=vr")
- (unspec:V_VLSI
- [(match_operand:V_VLSI 1 "register_operand" "vr")
- (match_operand:V_VLSI 2 "register_operand" "vr")]
+ [(set (match_operand:VI_QH 0 "register_operand" "=vr")
+ (unspec:VI_QH
+ [(match_operand:VI_QH 1 "register_operand" "vr")
+ (match_operand:VI_QH 2 "register_operand" "vr")]
UNSPEC_VABD))]
"TARGET_ZVABD && can_create_pseudo_p ()"
"#"
diff --git a/gcc/config/riscv/vector-iterators.md
b/gcc/config/riscv/vector-iterators.md
index 3de38409342..e3ec8e519bb 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1258,6 +1258,36 @@ (define_mode_iterator V_FRACT [
(RVVMF2SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_VECTOR_ELEN_64")
])
+(define_mode_iterator VWEXTI_HS [
+ RVVM8HI RVVM4HI RVVM2HI RVVM1HI RVVMF2HI (RVVMF4HI "TARGET_VECTOR_ELEN_64")
+
+ RVVM8SI RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_VECTOR_ELEN_64")
+
+ (V1HI "riscv_vector::vls_mode_valid_p (V1HImode)")
+ (V2HI "riscv_vector::vls_mode_valid_p (V2HImode)")
+ (V4HI "riscv_vector::vls_mode_valid_p (V4HImode)")
+ (V8HI "riscv_vector::vls_mode_valid_p (V8HImode)")
+ (V16HI "riscv_vector::vls_mode_valid_p (V16HImode)")
+ (V32HI "riscv_vector::vls_mode_valid_p (V32HImode) && TARGET_MIN_VLEN >= 64")
+ (V64HI "riscv_vector::vls_mode_valid_p (V64HImode) && TARGET_MIN_VLEN >=
128")
+ (V128HI "riscv_vector::vls_mode_valid_p (V128HImode) && TARGET_MIN_VLEN >=
256")
+ (V256HI "riscv_vector::vls_mode_valid_p (V256HImode) && TARGET_MIN_VLEN >=
512")
+ (V512HI "riscv_vector::vls_mode_valid_p (V512HImode) && TARGET_MIN_VLEN >=
1024")
+ (V1024HI "riscv_vector::vls_mode_valid_p (V1024HImode) && TARGET_MIN_VLEN >=
2048")
+ (V2048HI "riscv_vector::vls_mode_valid_p (V2048HImode) && TARGET_MIN_VLEN >=
4096")
+ (V1SI "riscv_vector::vls_mode_valid_p (V1SImode)")
+ (V2SI "riscv_vector::vls_mode_valid_p (V2SImode)")
+ (V4SI "riscv_vector::vls_mode_valid_p (V4SImode)")
+ (V8SI "riscv_vector::vls_mode_valid_p (V8SImode)")
+ (V16SI "riscv_vector::vls_mode_valid_p (V16SImode) && TARGET_MIN_VLEN >= 64")
+ (V32SI "riscv_vector::vls_mode_valid_p (V32SImode) && TARGET_MIN_VLEN >=
128")
+ (V64SI "riscv_vector::vls_mode_valid_p (V64SImode) && TARGET_MIN_VLEN >=
256")
+ (V128SI "riscv_vector::vls_mode_valid_p (V128SImode) && TARGET_MIN_VLEN >=
512")
+ (V256SI "riscv_vector::vls_mode_valid_p (V256SImode) && TARGET_MIN_VLEN >=
1024")
+ (V512SI "riscv_vector::vls_mode_valid_p (V512SImode) && TARGET_MIN_VLEN >=
2048")
+ (V1024SI "riscv_vector::vls_mode_valid_p (V1024SImode) && TARGET_MIN_VLEN >=
4096")
+])
+
(define_mode_iterator VWEXTI_D [
(RVVM8DI "TARGET_VECTOR_ELEN_64") (RVVM4DI "TARGET_VECTOR_ELEN_64")
(RVVM2DI "TARGET_VECTOR_ELEN_64") (RVVM1DI "TARGET_VECTOR_ELEN_64")
@@ -5898,6 +5928,8 @@ (define_mode_iterator V_VLSI_S [
(V1024SI "riscv_vector::vls_mode_valid_p (V1024SImode) && TARGET_MIN_VLEN >=
4096")
])
+(define_mode_iterator V_VLSI_SD [V_VLSI_S V_VLSI_D])
+
(define_mode_iterator V_VLSI_S_LMULX2 [
RVVM4SI RVVM2SI RVVM1SI (RVVMF2SI "TARGET_VECTOR_ELEN_64")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 32c0036ffa4..5225e85ed61 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -9264,8 +9264,8 @@ (define_insn "@pred_abs<mode>"
(set (attr "avl_type_idx") (const_int 7))])
(define_insn "@pred_vabd<su><mode>"
- [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vd, vr, vr")
- (if_then_else:V_VLSI
+ [(set (match_operand:VI_QH 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VI_QH
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" " vm, vm, Wc1, Wc1")
(match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
@@ -9274,19 +9274,19 @@ (define_insn "@pred_vabd<su><mode>"
(match_operand 8 "const_int_operand" " i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (unspec:V_VLSI
- [(match_operand:V_VLSI 3 "register_operand" "vr,vr,vr,vr")
- (match_operand:V_VLSI 4 "register_operand" "vr,vr,vr,vr")]
+ (unspec:VI_QH
+ [(match_operand:VI_QH 3 "register_operand" "vr,vr,vr,vr")
+ (match_operand:VI_QH 4 "register_operand" "vr,vr,vr,vr")]
UNSPEC_VABD)
- (match_operand:V_VLSI 2 "vector_merge_operand" "vu,0,vu,0")))]
+ (match_operand:VI_QH 2 "vector_merge_operand" "vu,0,vu,0")))]
"TARGET_ZVABD"
"vabd<u>.vv\t%0,%3,%4%p1"
[(set_attr "type" "vialu")
(set_attr "mode" "<MODE>")])
(define_insn "@pred_widen_abd_plus<su><mode>"
- [(set (match_operand:VWEXTI 0 "register_operand" "+&vd,&vd,&vr,&vr")
- (if_then_else:VWEXTI
+ [(set (match_operand:VWEXTI_HS 0 "register_operand" "+&vd,&vd,&vr,&vr")
+ (if_then_else:VWEXTI_HS
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" "vm,vm,Wc1,Wc1")
(match_operand 5 "vector_length_operand" "rK,rK,rK,rK")
@@ -9295,12 +9295,12 @@ (define_insn "@pred_widen_abd_plus<su><mode>"
(match_operand 8 "const_int_operand" "i,i,i,i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (unspec:VWEXTI
+ (unspec:VWEXTI_HS
[(match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "vr,vr,vr,vr")
(match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "vr,vr,vr,vr")
(match_dup 0)]
UNSPEC_VABDA)
- (match_operand:VWEXTI 2 "vector_merge_operand" "vu,0,vu,0")))]
+ (match_operand:VWEXTI_HS 2 "vector_merge_operand" "vu,0,vu,0")))]
"TARGET_ZVABD"
"vwabda<u>.vv\t%0,%3,%4%p1"
[(set_attr "type" "viwalu")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-2.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-2.c
new file mode 100644
index 00000000000..a3e624d8362
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zvabd-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv64gcv_zvabd -mabi=lp64d
-fno-vect-cost-model" } */
+
+static long
+abs64 (long i)
+{
+ return i < 0 ? -i : i;
+}
+
+__attribute__((noipa)) void
+test_abd_i32 (int *__restrict dst, int *__restrict a, int *__restrict b, int n)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ dst[i] = abs64 (a[i] - b[i]);
+}
+
+__attribute__((noipa)) void
+test_wabda_i32 (long *__restrict dst, int *__restrict a, int *__restrict b,
+ int n)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ dst[i] += abs64 (a[i] - b[i]);
+}
+
+/* { dg-final { scan-assembler-not {vabd\.vv} } } */
+/* { dg-final { scan-assembler-not {vwabda\.vv} } } */
--
2.46.0