Message ID | a515e552-f3de-49ec-b791-7c1dbd039d73@gmail.com |
---|---|
State | New |
Headers | show |
Series | RISC-V: Add vector popcount, clz, ctz. | expand |
LGTM
juzhe.zhong@rivai.ai
From: Robin Dapp
Date: 2024-05-17 23:26
To: gcc-patches
CC: rdapp.gcc; palmer; Kito Cheng; juzhe.zhong@rivai.ai; jeffreyalaw
Subject: [PATCH] RISC-V: Add vector popcount, clz, ctz.
Hi,
this patch adds the zvbb vcpop, vclz and vctz to the autovec machinery
as well as tests for them. It also changes several non-VLS iterators
to V_VLS iterators for consistency.
Regtested on rv64gcv_zvfh_zvbb.
Regards
Robin
gcc/ChangeLog:
* config/riscv/autovec.md (ctz<mode>2): New expander.
(clz<mode>2): Ditto.
* config/riscv/generic-vector-ooo.md: Add bitmanip ops to insn
reservation.
* config/riscv/vector-crypto.md: Add VLS modes to insns.
* config/riscv/vector.md: Add bitmanip ops to mode_idx and other
attributes.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/unop/popcount-1.c: Adjust check
for zvbb.
* gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/popcount-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/popcount-3.c: New test.
* gcc.target/riscv/rvv/autovec/unop/popcount-template.h: New test.
* gcc.target/riscv/rvv/autovec/unop/clz-1.c: New test.
* gcc.target/riscv/rvv/autovec/unop/clz-run.c: New test.
* gcc.target/riscv/rvv/autovec/unop/clz-template.h: New test.
* gcc.target/riscv/rvv/autovec/unop/ctz-1.c: New test.
* gcc.target/riscv/rvv/autovec/unop/ctz-run.c: New test.
* gcc.target/riscv/rvv/autovec/unop/ctz-template.h: New test.
---
gcc/config/riscv/autovec.md | 30 +++++-
gcc/config/riscv/generic-vector-ooo.md | 2 +-
gcc/config/riscv/vector-crypto.md | 93 ++++++++++---------
gcc/config/riscv/vector.md | 14 +--
.../gcc.target/riscv/rvv/autovec/unop/clz-1.c | 8 ++
.../riscv/rvv/autovec/unop/clz-run.c | 36 +++++++
.../riscv/rvv/autovec/unop/clz-template.h | 21 +++++
.../gcc.target/riscv/rvv/autovec/unop/ctz-1.c | 8 ++
.../riscv/rvv/autovec/unop/ctz-run.c | 36 +++++++
.../riscv/rvv/autovec/unop/ctz-template.h | 21 +++++
.../riscv/rvv/autovec/unop/popcount-1.c | 4 +-
.../riscv/rvv/autovec/unop/popcount-2.c | 4 +-
.../riscv/rvv/autovec/unop/popcount-3.c | 8 ++
.../riscv/rvv/autovec/unop/popcount-run-1.c | 3 +-
.../rvv/autovec/unop/popcount-template.h | 21 +++++
15 files changed, 250 insertions(+), 59 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-run.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-template.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-run.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-template.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-template.h
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index aa1ae0fe075..a9391ed146c 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1566,7 +1566,7 @@ (define_expand "xorsign<mode>3"
})
;; -------------------------------------------------------------------------------
-;; - [INT] POPCOUNT.
+;; - [INT] POPCOUNT, CTZ and CLZ.
;; -------------------------------------------------------------------------------
(define_expand "popcount<mode>2"
@@ -1574,10 +1574,36 @@ (define_expand "popcount<mode>2"
(match_operand:V_VLSI 1 "register_operand")]
"TARGET_VECTOR"
{
- riscv_vector::expand_popcount (operands);
+ if (!TARGET_ZVBB)
+ riscv_vector::expand_popcount (operands);
+ else
+ {
+ riscv_vector::emit_vlmax_insn (code_for_pred_v (POPCOUNT, <MODE>mode),
+ riscv_vector::CPOP_OP, operands);
+ }
DONE;
})
+(define_expand "ctz<mode>2"
+ [(match_operand:V_VLSI 0 "register_operand")
+ (match_operand:V_VLSI 1 "register_operand")]
+ "TARGET_ZVBB"
+ {
+ riscv_vector::emit_vlmax_insn (code_for_pred_v (CTZ, <MODE>mode),
+ riscv_vector::CPOP_OP, operands);
+ DONE;
+})
+
+(define_expand "clz<mode>2"
+ [(match_operand:V_VLSI 0 "register_operand")
+ (match_operand:V_VLSI 1 "register_operand")]
+ "TARGET_ZVBB"
+ {
+ riscv_vector::emit_vlmax_insn (code_for_pred_v (CLZ, <MODE>mode),
+ riscv_vector::CPOP_OP, operands);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [INT] Highpart multiplication
diff --git a/gcc/config/riscv/generic-vector-ooo.md b/gcc/config/riscv/generic-vector-ooo.md
index 96cb1a0be29..5e933c83841 100644
--- a/gcc/config/riscv/generic-vector-ooo.md
+++ b/gcc/config/riscv/generic-vector-ooo.md
@@ -74,7 +74,7 @@ (define_insn_reservation "vec_fmul" 6
;; Vector crypto, assumed to be a generic operation for now.
(define_insn_reservation "vec_crypto" 4
- (eq_attr "type" "crypto")
+ (eq_attr "type" "crypto,vclz,vctz,vcpop")
"vxu_ooo_issue,vxu_ooo_alu")
;; Vector crypto, AES
diff --git a/gcc/config/riscv/vector-crypto.md b/gcc/config/riscv/vector-crypto.md
index 0ddc2f3f3c6..8e23ecca12f 100755
--- a/gcc/config/riscv/vector-crypto.md
+++ b/gcc/config/riscv/vector-crypto.md
@@ -99,8 +99,8 @@ (define_int_iterator UNSPEC_CRYPTO_VI1 [UNSPEC_VAESKF2 UNSPEC_VSM3C])
;; vror.vv vror.vx vror.vi
;; vwsll.vv vwsll.vx vwsll.vi
(define_insn "@pred_vandn<mode>"
- [(set (match_operand:VI 0 "register_operand" "=vd, vr, vd, vr")
- (if_then_else:VI
+ [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vr, vd, vr")
+ (if_then_else:V_VLSI
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" "vm,Wc1, vm,Wc1")
(match_operand 5 "vector_length_operand" "rK, rK, rK, rK")
@@ -109,18 +109,19 @@ (define_insn "@pred_vandn<mode>"
(match_operand 8 "const_int_operand" " i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (and:VI
- (not:VI (match_operand:VI 4 "register_operand" "vr, vr, vr, vr"))
- (match_operand:VI 3 "register_operand" "vr, vr, vr, vr"))
- (match_operand:VI 2 "vector_merge_operand" "vu, vu, 0, 0")))]
+ (and:V_VLSI
+ (not:V_VLSI
+ (match_operand:V_VLSI 4 "register_operand" "vr, vr, vr, vr"))
+ (match_operand:V_VLSI 3 "register_operand" "vr, vr, vr, vr"))
+ (match_operand:V_VLSI 2 "vector_merge_operand" "vu, vu, 0, 0")))]
"TARGET_ZVBB || TARGET_ZVKB"
"vandn.vv\t%0,%3,%4%p1"
[(set_attr "type" "vandn")
(set_attr "mode" "<MODE>")])
(define_insn "@pred_vandn<mode>_scalar"
- [(set (match_operand:VI_QHS 0 "register_operand" "=vd, vr,vd, vr")
- (if_then_else:VI_QHS
+ [(set (match_operand:V_VLSI_QHS 0 "register_operand" "=vd, vr,vd, vr")
+ (if_then_else:V_VLSI_QHS
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,Wc1")
(match_operand 5 "vector_length_operand" " rK, rK,rK, rK")
@@ -129,12 +130,12 @@ (define_insn "@pred_vandn<mode>_scalar"
(match_operand 8 "const_int_operand" " i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (and:VI_QHS
- (not:VI_QHS
- (vec_duplicate:VI_QHS
+ (and:V_VLSI_QHS
+ (not:V_VLSI_QHS
+ (vec_duplicate:V_VLSI_QHS
(match_operand:<VEL> 4 "register_operand" " r, r, r, r")))
- (match_operand:VI_QHS 3 "register_operand" "vr, vr,vr, vr"))
- (match_operand:VI_QHS 2 "vector_merge_operand" "vu, vu, 0, 0")))]
+ (match_operand:V_VLSI_QHS 3 "register_operand" "vr, vr,vr, vr"))
+ (match_operand:V_VLSI_QHS 2 "vector_merge_operand" "vu, vu, 0, 0")))]
"TARGET_ZVBB || TARGET_ZVKB"
"vandn.vx\t%0,%3,%4%p1"
[(set_attr "type" "vandn")
@@ -143,8 +144,8 @@ (define_insn "@pred_vandn<mode>_scalar"
;; Handle GET_MODE_INNER (mode) = DImode. We need to split them since
;; we need to deal with SEW = 64 in RV32 system.
(define_expand "@pred_vandn<mode>_scalar"
- [(set (match_operand:VI_D 0 "register_operand")
- (if_then_else:VI_D
+ [(set (match_operand:V_VLSI_D 0 "register_operand")
+ (if_then_else:V_VLSI_D
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand")
(match_operand 5 "vector_length_operand")
@@ -153,12 +154,12 @@ (define_expand "@pred_vandn<mode>_scalar"
(match_operand 8 "const_int_operand")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (and:VI_D
- (not:VI_D
- (vec_duplicate:VI_D
+ (and:V_VLSI_D
+ (not:V_VLSI_D
+ (vec_duplicate:V_VLSI_D
(match_operand:<VEL> 4 "reg_or_int_operand")))
- (match_operand:VI_D 3 "register_operand"))
- (match_operand:VI_D 2 "vector_merge_operand")))]
+ (match_operand:V_VLSI_D 3 "register_operand"))
+ (match_operand:V_VLSI_D 2 "vector_merge_operand")))]
"TARGET_ZVBB || TARGET_ZVKB"
{
if (riscv_vector::sew64_scalar_helper (
@@ -177,8 +178,8 @@ (define_expand "@pred_vandn<mode>_scalar"
})
(define_insn "*pred_vandn<mode>_scalar"
- [(set (match_operand:VI_D 0 "register_operand" "=vd, vr,vd, vr")
- (if_then_else:VI_D
+ [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr,vd, vr")
+ (if_then_else:V_VLSI_D
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,Wc1")
(match_operand 5 "vector_length_operand" " rK, rK,rK, rK")
@@ -187,20 +188,20 @@ (define_insn "*pred_vandn<mode>_scalar"
(match_operand 8 "const_int_operand" " i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (and:VI_D
- (not:VI_D
- (vec_duplicate:VI_D
+ (and:V_VLSI_D
+ (not:V_VLSI_D
+ (vec_duplicate:V_VLSI_D
(match_operand:<VEL> 4 "reg_or_0_operand" " rJ, rJ,rJ, rJ")))
- (match_operand:VI_D 3 "register_operand" " vr, vr,vr, vr"))
- (match_operand:VI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))]
+ (match_operand:V_VLSI_D 3 "register_operand" " vr, vr,vr, vr"))
+ (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))]
"TARGET_ZVBB || TARGET_ZVKB"
"vandn.vx\t%0,%3,%z4%p1"
[(set_attr "type" "vandn")
(set_attr "mode" "<MODE>")])
(define_insn "*pred_vandn<mode>_extended_scalar"
- [(set (match_operand:VI_D 0 "register_operand" "=vd, vr,vd, vr")
- (if_then_else:VI_D
+ [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr,vd, vr")
+ (if_then_else:V_VLSI_D
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,Wc1")
(match_operand 5 "vector_length_operand" " rK, rK,rK, rK")
@@ -209,13 +210,13 @@ (define_insn "*pred_vandn<mode>_extended_scalar"
(match_operand 8 "const_int_operand" " i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (and:VI_D
- (not:VI_D
- (vec_duplicate:VI_D
+ (and:V_VLSI_D
+ (not:V_VLSI_D
+ (vec_duplicate:V_VLSI_D
(sign_extend:<VEL>
(match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ, rJ,rJ, rJ"))))
- (match_operand:VI_D 3 "register_operand" " vr, vr,vr, vr"))
- (match_operand:VI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))]
+ (match_operand:V_VLSI_D 3 "register_operand" " vr, vr,vr, vr"))
+ (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))]
"TARGET_ZVBB || TARGET_ZVKB"
"vandn.vx\t%0,%3,%z4%p1"
[(set_attr "type" "vandn")
@@ -325,8 +326,8 @@ (define_insn "@pred_vwsll<mode>_scalar"
;; vbrev.v vbrev8.v vrev8.v
(define_insn "@pred_v<rev><mode>"
- [(set (match_operand:VI 0 "register_operand" "=vd,vr,vd,vr")
- (if_then_else:VI
+ [(set (match_operand:V_VLSI 0 "register_operand" "=vd,vr,vd,vr")
+ (if_then_else:V_VLSI
(unspec:<VM>
[(match_operand:<VM> 1 "vector_mask_operand" "vm,Wc1,vm,Wc1")
(match_operand 4 "vector_length_operand" "rK,rK, rK, rK")
@@ -335,24 +336,24 @@ (define_insn "@pred_v<rev><mode>"
(match_operand 7 "const_int_operand" "i, i, i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
- (unspec:VI
- [(match_operand:VI 3 "register_operand" "vr,vr, vr, vr")]UNSPEC_VRBB8)
- (match_operand:VI 2 "vector_merge_operand" "vu,vu, 0, 0")))]
+ (unspec:V_VLSI
+ [(match_operand:V_VLSI 3 "register_operand" "vr,vr, vr, vr")]UNSPEC_VRBB8)
+ (match_operand:V_VLSI 2 "vector_merge_operand" "vu,vu, 0, 0")))]
"TARGET_ZVBB || TARGET_ZVKB"
"v<rev>.v\t%0,%3%p1"
[(set_attr "type" "v<rev>")
(set_attr "mode" "<MODE>")])
-;; vclz.v vctz.v
+;; vclz.v vctz.v vcpop.v
(define_insn "@pred_v<bitmanip_optab><mode>"
- [(set (match_operand:VI 0 "register_operand" "=vd, vr")
- (clz_ctz_pcnt:VI
+ [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vr")
+ (clz_ctz_pcnt:V_VLSI
(parallel
- [(match_operand:VI 2 "register_operand" "vr, vr")
+ [(match_operand:V_VLSI 2 "register_operand" " vr, vr")
(unspec:<VM>
- [(match_operand:<VM> 1 "vector_mask_operand" "vm,Wc1")
- (match_operand 3 "vector_length_operand" "rK, rK")
- (match_operand 4 "const_int_operand" " i, i")
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 3 "vector_length_operand" " rK, rK")
+ (match_operand 4 "const_int_operand" " i, i")
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)])))]
"TARGET_ZVBB"
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index dafcd7d9bf9..b4baccd06a2 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -52,7 +52,7 @@ (define_attr "has_vtype_op" "false,true"
vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,vfmovvf,vfmovfv,\
vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,\
vgather,vcompress,vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,\
- vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,\
+ vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vcpop,vclz,vctz,vrol,\
vror,vwsll,vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,\
vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c")
(const_string "true")]
@@ -76,7 +76,7 @@ (define_attr "has_vl_op" "false,true"
vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovxv,vfmovfv,\
vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,\
vgather,vcompress,vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,\
- vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,\
+ vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vcpop,vclz,vctz,vrol,\
vror,vwsll,vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,\
vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c")
(const_string "true")]
@@ -443,7 +443,7 @@ (define_attr "ratio" ""
vimovxv,vfmovvf,vfmovfv,vslideup,vslidedown,\
vislide1up,vislide1down,vfslide1up,vfslide1down,\
vgather,vcompress,vlsegdux,vlsegdox,vssegtux,vssegtox,\
- vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,vror,vwsll,\
+ vandn,vbrev,vbrev8,vrev8,vcpop,vclz,vctz,vrol,vror,vwsll,\
vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,\
vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,\
vsm3me,vsm3c")
@@ -743,7 +743,7 @@ (define_attr "mode_idx" ""
vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,\
vfcvtitof,vfncvtitof,vfncvtftoi,vfncvtftof,vmalu,vmiota,vmidx,\
vimovxv,vfmovfv,vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,\
- vgather,vcompress,vmov,vnclip,vnshift,vandn")
+ vgather,vcompress,vmov,vnclip,vnshift,vandn,vcpop,vclz,vctz")
(const_int 0)
(eq_attr "type" "vimovvx,vfmovvf")
@@ -789,8 +789,8 @@ (define_attr "vl_op_idx" ""
(eq_attr "type" "vicmp,vimuladd,vfcmp,vfmuladd")
(const_int 6)
- (eq_attr "type" "vmpop,vmffs,vmidx,vssegte,vclz,vctz,vgmul,vaesef,vaesem,vaesdf,vaesdm,\
- vaesz,vsm4r")
+ (eq_attr "type" "vmpop,vmffs,vmidx,vssegte,vcpop,vclz,vctz,vgmul,vaesef,vaesem,vaesdf,\
+ vaesdm,vaesz,vsm4r")
(const_int 3)]
(const_int INVALID_ATTRIBUTE)))
@@ -892,7 +892,7 @@ (define_attr "avl_type_idx" ""
vsm4k,vsm3me,vsm3c")
(const_int 6)
- (eq_attr "type" "vmpop,vmffs,vssegte,vclz,vctz")
+ (eq_attr "type" "vmpop,vmffs,vssegte,vcpop,vclz,vctz")
(const_int 4)]
(const_int INVALID_ATTRIBUTE)))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-1.c
new file mode 100644
index 00000000000..c27d9d399b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-add-options "riscv_v" } */
+/* { dg-add-options "riscv_zvbb" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model" } */
+
+#include "clz-template.h"
+
+/* { dg-final { scan-assembler-times {\tvclz.v} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-run.c
new file mode 100644
index 00000000000..df6f893b8fb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-run.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -mrvv-vector-bits=zvl -ffast-math" } */
+
+#include "clz-template.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#define SZ 128
+
+#define RUN(TYPE) \
+ TYPE dst##TYPE[SZ]; \
+ TYPE a##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ dst##TYPE[i] = 0; \
+ a##TYPE[i] = i; \
+ } \
+ vclz_##TYPE (dst##TYPE, a##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE[i] == __builtin_clz (a##TYPE[i]));
+
+#define RUN_ALL() \
+ RUN (int8_t) \
+ RUN (uint8_t) \
+ RUN (int16_t) \
+ RUN (uint16_t) \
+ RUN (int32_t) \
+ RUN (uint32_t) \
+ RUN (int64_t) \
+ RUN (uint64_t)
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-template.h
new file mode 100644
index 00000000000..1cde9fbc32c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-template.h
@@ -0,0 +1,21 @@
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void vclz_##TYPE (TYPE *restrict dst, \
+ TYPE *restrict a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = __builtin_clz (a[i]); \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (int8_t) \
+ TEST_TYPE (uint8_t) \
+ TEST_TYPE (int16_t) \
+ TEST_TYPE (uint16_t) \
+ TEST_TYPE (int32_t) \
+ TEST_TYPE (uint32_t) \
+ TEST_TYPE (int64_t) \
+ TEST_TYPE (uint64_t)
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-1.c
new file mode 100644
index 00000000000..d5989bd5aad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-add-options "riscv_v" } */
+/* { dg-add-options "riscv_zvbb" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model" } */
+
+#include "ctz-template.h"
+
+/* { dg-final { scan-assembler-times {\tvctz.v} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-run.c
new file mode 100644
index 00000000000..9a74ba20a73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-run.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -mrvv-vector-bits=zvl -ffast-math" } */
+
+#include "ctz-template.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#define SZ 126
+
+#define RUN(TYPE) \
+ TYPE dst##TYPE[SZ]; \
+ TYPE a##TYPE[SZ]; \
+ for (int i = 0; i < SZ; i++) \
+ { \
+ dst##TYPE[i] = 0; \
+ a##TYPE[i] = i + 1; \
+ } \
+ vctz_##TYPE (dst##TYPE, a##TYPE, SZ); \
+ for (int i = 0; i < SZ; i++) \
+ assert (dst##TYPE[i] == __builtin_ctz (a##TYPE[i]));\
+
+#define RUN_ALL() \
+ RUN (uint8_t) \
+ RUN (int8_t) \
+ RUN (int16_t) \
+ RUN (uint16_t) \
+ RUN (int32_t) \
+ RUN (uint32_t) \
+ //RUN (int64_t) \
+ //RUN (uint64_t)
+
+int main ()
+{
+ RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-template.h
new file mode 100644
index 00000000000..c47fc19935d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-template.h
@@ -0,0 +1,21 @@
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void vctz_##TYPE (TYPE *restrict dst, \
+ TYPE *restrict a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = __builtin_ctz (a[i]); \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (int8_t) \
+ TEST_TYPE (uint8_t) \
+ TEST_TYPE (int16_t) \
+ TEST_TYPE (uint16_t) \
+ TEST_TYPE (int32_t) \
+ TEST_TYPE (uint32_t) \
+ TEST_TYPE (int64_t) \
+ TEST_TYPE (uint64_t)
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c
index fad528a842e..1396e46ec8c 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */
+/* { dg-add-options "riscv_v" } */
+/* { dg-additional-options "-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */
#include <stdint-gcc.h>
@@ -18,3 +19,4 @@ popcount_64 (uint64_t *restrict dst, uint64_t *restrict src, int size)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */
+/* { dg-final { scan-assembler-times "vcpop.v" 2 { target { riscv_zvbb } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c
index 0199f8cb515..116cc304da3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-slp-details" } */
+/* { dg-add-options "riscv_v" } */
+/* { dg-additional-options "-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-slp-details" } */
int x[8];
int y[8];
@@ -17,3 +18,4 @@ void foo ()
}
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp2" } } */
+/* { dg-final { scan-assembler "vcpop.v" { target { riscv_zvbb } } } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-3.c
new file mode 100644
index 00000000000..00b87a07fd8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-3.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-add-options "riscv_v" } */
+/* { dg-add-options "riscv_zvbb" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model" } */
+
+#include "popcount-template.h"
+
+/* { dg-final { scan-assembler-times {\tvcpop.v} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c
index 38f1633da99..8ddb1783dd0 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c
@@ -1,4 +1,5 @@
-/* { dg-do run { target { riscv_v } } } */
+/* { dg-do run { target { riscv_v_ok } } } */
+/* { dg-add-options "riscv_v" } */
#include "popcount-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-template.h
new file mode 100644
index 00000000000..28399565bb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-template.h
@@ -0,0 +1,21 @@
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE) \
+ __attribute__ ((noipa)) void vpopcount_##TYPE (TYPE *restrict dst, \
+ TYPE *restrict a, int n) \
+ { \
+ for (int i = 0; i < n; i++) \
+ dst[i] = __builtin_popcount (a[i]); \
+ }
+
+#define TEST_ALL() \
+ TEST_TYPE (int8_t) \
+ TEST_TYPE (uint8_t) \
+ TEST_TYPE (int16_t) \
+ TEST_TYPE (uint16_t) \
+ TEST_TYPE (int32_t) \
+ TEST_TYPE (uint32_t) \
+ TEST_TYPE (int64_t) \
+ TEST_TYPE (uint64_t)
+
+TEST_ALL()
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index aa1ae0fe075..a9391ed146c 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -1566,7 +1566,7 @@ (define_expand "xorsign<mode>3" }) ;; ------------------------------------------------------------------------------- -;; - [INT] POPCOUNT. +;; - [INT] POPCOUNT, CTZ and CLZ. ;; ------------------------------------------------------------------------------- (define_expand "popcount<mode>2" @@ -1574,10 +1574,36 @@ (define_expand "popcount<mode>2" (match_operand:V_VLSI 1 "register_operand")] "TARGET_VECTOR" { - riscv_vector::expand_popcount (operands); + if (!TARGET_ZVBB) + riscv_vector::expand_popcount (operands); + else + { + riscv_vector::emit_vlmax_insn (code_for_pred_v (POPCOUNT, <MODE>mode), + riscv_vector::CPOP_OP, operands); + } DONE; }) +(define_expand "ctz<mode>2" + [(match_operand:V_VLSI 0 "register_operand") + (match_operand:V_VLSI 1 "register_operand")] + "TARGET_ZVBB" + { + riscv_vector::emit_vlmax_insn (code_for_pred_v (CTZ, <MODE>mode), + riscv_vector::CPOP_OP, operands); + DONE; +}) + +(define_expand "clz<mode>2" + [(match_operand:V_VLSI 0 "register_operand") + (match_operand:V_VLSI 1 "register_operand")] + "TARGET_ZVBB" + { + riscv_vector::emit_vlmax_insn (code_for_pred_v (CLZ, <MODE>mode), + riscv_vector::CPOP_OP, operands); + DONE; +}) + ;; ------------------------------------------------------------------------- ;; ---- [INT] Highpart multiplication diff --git a/gcc/config/riscv/generic-vector-ooo.md b/gcc/config/riscv/generic-vector-ooo.md index 96cb1a0be29..5e933c83841 100644 --- a/gcc/config/riscv/generic-vector-ooo.md +++ b/gcc/config/riscv/generic-vector-ooo.md @@ -74,7 +74,7 @@ (define_insn_reservation "vec_fmul" 6 ;; Vector crypto, assumed to be a generic operation for now. (define_insn_reservation "vec_crypto" 4 - (eq_attr "type" "crypto") + (eq_attr "type" "crypto,vclz,vctz,vcpop") "vxu_ooo_issue,vxu_ooo_alu") ;; Vector crypto, AES diff --git a/gcc/config/riscv/vector-crypto.md b/gcc/config/riscv/vector-crypto.md index 0ddc2f3f3c6..8e23ecca12f 100755 --- a/gcc/config/riscv/vector-crypto.md +++ b/gcc/config/riscv/vector-crypto.md @@ -99,8 +99,8 @@ (define_int_iterator UNSPEC_CRYPTO_VI1 [UNSPEC_VAESKF2 UNSPEC_VSM3C]) ;; vror.vv vror.vx vror.vi ;; vwsll.vv vwsll.vx vwsll.vi (define_insn "@pred_vandn<mode>" - [(set (match_operand:VI 0 "register_operand" "=vd, vr, vd, vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vr, vd, vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" "vm,Wc1, vm,Wc1") (match_operand 5 "vector_length_operand" "rK, rK, rK, rK") @@ -109,18 +109,19 @@ (define_insn "@pred_vandn<mode>" (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (and:VI - (not:VI (match_operand:VI 4 "register_operand" "vr, vr, vr, vr")) - (match_operand:VI 3 "register_operand" "vr, vr, vr, vr")) - (match_operand:VI 2 "vector_merge_operand" "vu, vu, 0, 0")))] + (and:V_VLSI + (not:V_VLSI + (match_operand:V_VLSI 4 "register_operand" "vr, vr, vr, vr")) + (match_operand:V_VLSI 3 "register_operand" "vr, vr, vr, vr")) + (match_operand:V_VLSI 2 "vector_merge_operand" "vu, vu, 0, 0")))] "TARGET_ZVBB || TARGET_ZVKB" "vandn.vv\t%0,%3,%4%p1" [(set_attr "type" "vandn") (set_attr "mode" "<MODE>")]) (define_insn "@pred_vandn<mode>_scalar" - [(set (match_operand:VI_QHS 0 "register_operand" "=vd, vr,vd, vr") - (if_then_else:VI_QHS + [(set (match_operand:V_VLSI_QHS 0 "register_operand" "=vd, vr,vd, vr") + (if_then_else:V_VLSI_QHS (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,Wc1") (match_operand 5 "vector_length_operand" " rK, rK,rK, rK") @@ -129,12 +130,12 @@ (define_insn "@pred_vandn<mode>_scalar" (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (and:VI_QHS - (not:VI_QHS - (vec_duplicate:VI_QHS + (and:V_VLSI_QHS + (not:V_VLSI_QHS + (vec_duplicate:V_VLSI_QHS (match_operand:<VEL> 4 "register_operand" " r, r, r, r"))) - (match_operand:VI_QHS 3 "register_operand" "vr, vr,vr, vr")) - (match_operand:VI_QHS 2 "vector_merge_operand" "vu, vu, 0, 0")))] + (match_operand:V_VLSI_QHS 3 "register_operand" "vr, vr,vr, vr")) + (match_operand:V_VLSI_QHS 2 "vector_merge_operand" "vu, vu, 0, 0")))] "TARGET_ZVBB || TARGET_ZVKB" "vandn.vx\t%0,%3,%4%p1" [(set_attr "type" "vandn") @@ -143,8 +144,8 @@ (define_insn "@pred_vandn<mode>_scalar" ;; Handle GET_MODE_INNER (mode) = DImode. We need to split them since ;; we need to deal with SEW = 64 in RV32 system. (define_expand "@pred_vandn<mode>_scalar" - [(set (match_operand:VI_D 0 "register_operand") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand") (match_operand 5 "vector_length_operand") @@ -153,12 +154,12 @@ (define_expand "@pred_vandn<mode>_scalar" (match_operand 8 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (and:VI_D - (not:VI_D - (vec_duplicate:VI_D + (and:V_VLSI_D + (not:V_VLSI_D + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 4 "reg_or_int_operand"))) - (match_operand:VI_D 3 "register_operand")) - (match_operand:VI_D 2 "vector_merge_operand")))] + (match_operand:V_VLSI_D 3 "register_operand")) + (match_operand:V_VLSI_D 2 "vector_merge_operand")))] "TARGET_ZVBB || TARGET_ZVKB" { if (riscv_vector::sew64_scalar_helper ( @@ -177,8 +178,8 @@ (define_expand "@pred_vandn<mode>_scalar" }) (define_insn "*pred_vandn<mode>_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd, vr,vd, vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr,vd, vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,Wc1") (match_operand 5 "vector_length_operand" " rK, rK,rK, rK") @@ -187,20 +188,20 @@ (define_insn "*pred_vandn<mode>_scalar" (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (and:VI_D - (not:VI_D - (vec_duplicate:VI_D + (and:V_VLSI_D + (not:V_VLSI_D + (vec_duplicate:V_VLSI_D (match_operand:<VEL> 4 "reg_or_0_operand" " rJ, rJ,rJ, rJ"))) - (match_operand:VI_D 3 "register_operand" " vr, vr,vr, vr")) - (match_operand:VI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))] + (match_operand:V_VLSI_D 3 "register_operand" " vr, vr,vr, vr")) + (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))] "TARGET_ZVBB || TARGET_ZVKB" "vandn.vx\t%0,%3,%z4%p1" [(set_attr "type" "vandn") (set_attr "mode" "<MODE>")]) (define_insn "*pred_vandn<mode>_extended_scalar" - [(set (match_operand:VI_D 0 "register_operand" "=vd, vr,vd, vr") - (if_then_else:VI_D + [(set (match_operand:V_VLSI_D 0 "register_operand" "=vd, vr,vd, vr") + (if_then_else:V_VLSI_D (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,Wc1") (match_operand 5 "vector_length_operand" " rK, rK,rK, rK") @@ -209,13 +210,13 @@ (define_insn "*pred_vandn<mode>_extended_scalar" (match_operand 8 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (and:VI_D - (not:VI_D - (vec_duplicate:VI_D + (and:V_VLSI_D + (not:V_VLSI_D + (vec_duplicate:V_VLSI_D (sign_extend:<VEL> (match_operand:<VSUBEL> 4 "reg_or_0_operand" " rJ, rJ,rJ, rJ")))) - (match_operand:VI_D 3 "register_operand" " vr, vr,vr, vr")) - (match_operand:VI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))] + (match_operand:V_VLSI_D 3 "register_operand" " vr, vr,vr, vr")) + (match_operand:V_VLSI_D 2 "vector_merge_operand" " vu, vu, 0, 0")))] "TARGET_ZVBB || TARGET_ZVKB" "vandn.vx\t%0,%3,%z4%p1" [(set_attr "type" "vandn") @@ -325,8 +326,8 @@ (define_insn "@pred_vwsll<mode>_scalar" ;; vbrev.v vbrev8.v vrev8.v (define_insn "@pred_v<rev><mode>" - [(set (match_operand:VI 0 "register_operand" "=vd,vr,vd,vr") - (if_then_else:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd,vr,vd,vr") + (if_then_else:V_VLSI (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" "vm,Wc1,vm,Wc1") (match_operand 4 "vector_length_operand" "rK,rK, rK, rK") @@ -335,24 +336,24 @@ (define_insn "@pred_v<rev><mode>" (match_operand 7 "const_int_operand" "i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (unspec:VI - [(match_operand:VI 3 "register_operand" "vr,vr, vr, vr")]UNSPEC_VRBB8) - (match_operand:VI 2 "vector_merge_operand" "vu,vu, 0, 0")))] + (unspec:V_VLSI + [(match_operand:V_VLSI 3 "register_operand" "vr,vr, vr, vr")]UNSPEC_VRBB8) + (match_operand:V_VLSI 2 "vector_merge_operand" "vu,vu, 0, 0")))] "TARGET_ZVBB || TARGET_ZVKB" "v<rev>.v\t%0,%3%p1" [(set_attr "type" "v<rev>") (set_attr "mode" "<MODE>")]) -;; vclz.v vctz.v +;; vclz.v vctz.v vcpop.v (define_insn "@pred_v<bitmanip_optab><mode>" - [(set (match_operand:VI 0 "register_operand" "=vd, vr") - (clz_ctz_pcnt:VI + [(set (match_operand:V_VLSI 0 "register_operand" "=vd, vr") + (clz_ctz_pcnt:V_VLSI (parallel - [(match_operand:VI 2 "register_operand" "vr, vr") + [(match_operand:V_VLSI 2 "register_operand" " vr, vr") (unspec:<VM> - [(match_operand:<VM> 1 "vector_mask_operand" "vm,Wc1") - (match_operand 3 "vector_length_operand" "rK, rK") - (match_operand 4 "const_int_operand" " i, i") + [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1") + (match_operand 3 "vector_length_operand" " rK, rK") + (match_operand 4 "const_int_operand" " i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)])))] "TARGET_ZVBB" diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index dafcd7d9bf9..b4baccd06a2 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -52,7 +52,7 @@ (define_attr "has_vtype_op" "false,true" vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,vfmovvf,vfmovfv,\ vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,\ vgather,vcompress,vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,\ - vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,\ + vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vcpop,vclz,vctz,vrol,\ vror,vwsll,vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,\ vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c") (const_string "true")] @@ -76,7 +76,7 @@ (define_attr "has_vl_op" "false,true" vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovxv,vfmovfv,\ vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,\ vgather,vcompress,vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,\ - vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,\ + vssegtux,vssegtox,vlsegdff,vandn,vbrev,vbrev8,vrev8,vcpop,vclz,vctz,vrol,\ vror,vwsll,vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,\ vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,vsm3me,vsm3c") (const_string "true")] @@ -443,7 +443,7 @@ (define_attr "ratio" "" vimovxv,vfmovvf,vfmovfv,vslideup,vslidedown,\ vislide1up,vislide1down,vfslide1up,vfslide1down,\ vgather,vcompress,vlsegdux,vlsegdox,vssegtux,vssegtox,\ - vandn,vbrev,vbrev8,vrev8,vclz,vctz,vrol,vror,vwsll,\ + vandn,vbrev,vbrev8,vrev8,vcpop,vclz,vctz,vrol,vror,vwsll,\ vclmul,vclmulh,vghsh,vgmul,vaesef,vaesem,vaesdf,vaesdm,\ vaeskf1,vaeskf2,vaesz,vsha2ms,vsha2ch,vsha2cl,vsm4k,vsm4r,\ vsm3me,vsm3c") @@ -743,7 +743,7 @@ (define_attr "mode_idx" "" vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,\ vfcvtitof,vfncvtitof,vfncvtftoi,vfncvtftof,vmalu,vmiota,vmidx,\ vimovxv,vfmovfv,vslideup,vslidedown,vislide1up,vislide1down,vfslide1up,vfslide1down,\ - vgather,vcompress,vmov,vnclip,vnshift,vandn") + vgather,vcompress,vmov,vnclip,vnshift,vandn,vcpop,vclz,vctz") (const_int 0) (eq_attr "type" "vimovvx,vfmovvf") @@ -789,8 +789,8 @@ (define_attr "vl_op_idx" "" (eq_attr "type" "vicmp,vimuladd,vfcmp,vfmuladd") (const_int 6) - (eq_attr "type" "vmpop,vmffs,vmidx,vssegte,vclz,vctz,vgmul,vaesef,vaesem,vaesdf,vaesdm,\ - vaesz,vsm4r") + (eq_attr "type" "vmpop,vmffs,vmidx,vssegte,vcpop,vclz,vctz,vgmul,vaesef,vaesem,vaesdf,\ + vaesdm,vaesz,vsm4r") (const_int 3)] (const_int INVALID_ATTRIBUTE))) @@ -892,7 +892,7 @@ (define_attr "avl_type_idx" "" vsm4k,vsm3me,vsm3c") (const_int 6) - (eq_attr "type" "vmpop,vmffs,vssegte,vclz,vctz") + (eq_attr "type" "vmpop,vmffs,vssegte,vcpop,vclz,vctz") (const_int 4)] (const_int INVALID_ATTRIBUTE))) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-1.c new file mode 100644 index 00000000000..c27d9d399b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-add-options "riscv_zvbb" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model" } */ + +#include "clz-template.h" + +/* { dg-final { scan-assembler-times {\tvclz.v} 8 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-run.c new file mode 100644 index 00000000000..df6f893b8fb --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-run.c @@ -0,0 +1,36 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -mrvv-vector-bits=zvl -ffast-math" } */ + +#include "clz-template.h" + +#include <assert.h> +#include <stdio.h> + +#define SZ 128 + +#define RUN(TYPE) \ + TYPE dst##TYPE[SZ]; \ + TYPE a##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + dst##TYPE[i] = 0; \ + a##TYPE[i] = i; \ + } \ + vclz_##TYPE (dst##TYPE, a##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (dst##TYPE[i] == __builtin_clz (a##TYPE[i])); + +#define RUN_ALL() \ + RUN (int8_t) \ + RUN (uint8_t) \ + RUN (int16_t) \ + RUN (uint16_t) \ + RUN (int32_t) \ + RUN (uint32_t) \ + RUN (int64_t) \ + RUN (uint64_t) + +int main () +{ + RUN_ALL() +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-template.h new file mode 100644 index 00000000000..1cde9fbc32c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/clz-template.h @@ -0,0 +1,21 @@ +#include <stdint-gcc.h> + +#define TEST_TYPE(TYPE) \ + __attribute__ ((noipa)) void vclz_##TYPE (TYPE *restrict dst, \ + TYPE *restrict a, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = __builtin_clz (a[i]); \ + } + +#define TEST_ALL() \ + TEST_TYPE (int8_t) \ + TEST_TYPE (uint8_t) \ + TEST_TYPE (int16_t) \ + TEST_TYPE (uint16_t) \ + TEST_TYPE (int32_t) \ + TEST_TYPE (uint32_t) \ + TEST_TYPE (int64_t) \ + TEST_TYPE (uint64_t) + +TEST_ALL() diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-1.c new file mode 100644 index 00000000000..d5989bd5aad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-add-options "riscv_zvbb" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model" } */ + +#include "ctz-template.h" + +/* { dg-final { scan-assembler-times {\tvctz.v} 8 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-run.c new file mode 100644 index 00000000000..9a74ba20a73 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-run.c @@ -0,0 +1,36 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -mrvv-vector-bits=zvl -ffast-math" } */ + +#include "ctz-template.h" + +#include <assert.h> +#include <stdio.h> + +#define SZ 126 + +#define RUN(TYPE) \ + TYPE dst##TYPE[SZ]; \ + TYPE a##TYPE[SZ]; \ + for (int i = 0; i < SZ; i++) \ + { \ + dst##TYPE[i] = 0; \ + a##TYPE[i] = i + 1; \ + } \ + vctz_##TYPE (dst##TYPE, a##TYPE, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (dst##TYPE[i] == __builtin_ctz (a##TYPE[i]));\ + +#define RUN_ALL() \ + RUN (uint8_t) \ + RUN (int8_t) \ + RUN (int16_t) \ + RUN (uint16_t) \ + RUN (int32_t) \ + RUN (uint32_t) \ + //RUN (int64_t) \ + //RUN (uint64_t) + +int main () +{ + RUN_ALL() +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-template.h new file mode 100644 index 00000000000..c47fc19935d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/ctz-template.h @@ -0,0 +1,21 @@ +#include <stdint-gcc.h> + +#define TEST_TYPE(TYPE) \ + __attribute__ ((noipa)) void vctz_##TYPE (TYPE *restrict dst, \ + TYPE *restrict a, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = __builtin_ctz (a[i]); \ + } + +#define TEST_ALL() \ + TEST_TYPE (int8_t) \ + TEST_TYPE (uint8_t) \ + TEST_TYPE (int16_t) \ + TEST_TYPE (uint16_t) \ + TEST_TYPE (int32_t) \ + TEST_TYPE (uint32_t) \ + TEST_TYPE (int64_t) \ + TEST_TYPE (uint64_t) + +TEST_ALL() diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c index fad528a842e..1396e46ec8c 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-1.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-additional-options "-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-vect-details" } */ #include <stdint-gcc.h> @@ -18,3 +19,4 @@ popcount_64 (uint64_t *restrict dst, uint64_t *restrict src, int size) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect" } } */ +/* { dg-final { scan-assembler-times "vcpop.v" 2 { target { riscv_zvbb } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c index 0199f8cb515..116cc304da3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-2.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-slp-details" } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-additional-options "-mrvv-vector-bits=scalable -fno-vect-cost-model -fdump-tree-slp-details" } */ int x[8]; int y[8]; @@ -17,3 +18,4 @@ void foo () } /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp2" } } */ +/* { dg-final { scan-assembler "vcpop.v" { target { riscv_zvbb } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-3.c new file mode 100644 index 00000000000..00b87a07fd8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-3.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-add-options "riscv_zvbb" } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model" } */ + +#include "popcount-template.h" + +/* { dg-final { scan-assembler-times {\tvcpop.v} 8 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c index 38f1633da99..8ddb1783dd0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-run-1.c @@ -1,4 +1,5 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { riscv_v_ok } } } */ +/* { dg-add-options "riscv_v" } */ #include "popcount-1.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-template.h new file mode 100644 index 00000000000..28399565bb3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/popcount-template.h @@ -0,0 +1,21 @@ +#include <stdint-gcc.h> + +#define TEST_TYPE(TYPE) \ + __attribute__ ((noipa)) void vpopcount_##TYPE (TYPE *restrict dst, \ + TYPE *restrict a, int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = __builtin_popcount (a[i]); \ + } + +#define TEST_ALL() \ + TEST_TYPE (int8_t) \ + TEST_TYPE (uint8_t) \ + TEST_TYPE (int16_t) \ + TEST_TYPE (uint16_t) \ + TEST_TYPE (int32_t) \ + TEST_TYPE (uint32_t) \ + TEST_TYPE (int64_t) \ + TEST_TYPE (uint64_t) + +TEST_ALL()