diff mbox series

RISC-V: Add vector popcount, clz, ctz.

Message ID a515e552-f3de-49ec-b791-7c1dbd039d73@gmail.com
State New
Headers show
Series RISC-V: Add vector popcount, clz, ctz. | expand

Commit Message

Robin Dapp May 17, 2024, 3:26 p.m. UTC
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

Comments

钟居哲 May 17, 2024, 10:34 p.m. UTC | #1
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 mbox series

Patch

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()