[2/2] RISC-V: Add support for XCValu extension in CV32E40P

Message ID 20230919150734.2854664-3-mary.bennett@embecosm.com
State Unresolved
Headers
Series RISC-V: Support CORE-V XCVMAC and XCVALU extensions |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Mary Bennett Sept. 19, 2023, 3:07 p.m. UTC
  Spec: github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md

Contributors:
      Mary Bennett <mary.bennett@embecosm.com>
      Nandni Jamnadas <nandni.jamnadas@embecosm.com>
      Pietra Ferreira <pietra.ferreira@embecosm.com>
      Charlie Keaney
      Jessica Mills
      Craig Blackmore <craig.blackmore@embecosm.com>
      Simon Cook <simon.cook@embecosm.com>
      Jeremy Bennett <jeremy.bennett@embecosm.com>
      Helene Chelin <helene.chelin@embecosm.com>

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc: Added the XCValu
          extension.
	* config/riscv/constraints.md: Added builtins for the XCValu
          extension.
	* config/riscv/predicates.md (immediate_register_operand):
          Likewise.
	* config/riscv/riscv-builtins.cc (AVAIL): Likewise.
	  (RISCV_ATYPE_UHI): Likewise.
	* config/riscv/riscv-ftypes.def: Likewise.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.opt: Likewise.
        * config/riscv/riscv.cc (riscv_print_operand): Likewise.
	* doc/extend.texi: Added XCValu documentation.
	* config/riscv/corev.def: New file.
	* config/riscv/corev.md: New file.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Added proc for the XCValu extension.
	* gcc.target/riscv/cv-alu-compile.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addurn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clip.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clipu.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-suburn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile.c: New test.
---
 gcc/common/config/riscv/riscv-common.cc       |   2 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  24 ++
 gcc/config/riscv/corev.md                     | 285 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |   3 +
 gcc/config/riscv/riscv-ftypes.def             |   6 +
 gcc/config/riscv/riscv-opts.h                 |   2 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/doc/extend.texi                           |  94 ++++++
 .../gcc.target/riscv/cv-alu-compile.c         | 252 ++++++++++++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 ++
 gcc/testsuite/lib/target-supports.exp         |  13 +
 23 files changed, 842 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
  

Comments

Kito Cheng Sept. 23, 2023, 9:04 a.m. UTC | #1
Hi Mary:

Several inline comments, mostly are related to the RTX pattern. I
guess we don't really need those unspec except clip*.

> diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
> index 59aeafe485f..30c8bcbe476 100644
> --- a/gcc/config/riscv/corev.md
> +++ b/gcc/config/riscv/corev.md
> @@ -17,6 +17,27 @@
>  ;; along with GCC; see the file COPYING3.  If not see
>  ;; <http://www.gnu.org/licenses/>.
>
> +(define_c_enum "unspec" [
> +
> +  ;;CORE-V ALU
> +  UNSPEC_CV_ALU_CLIP
> +  UNSPEC_CV_ALU_CLIPR
> +  UNSPEC_CV_ALU_CLIPU
> +  UNSPEC_CV_ALU_CLIPUR
> +  UNSPEC_CV_ALU_ADDN
> +  UNSPEC_CV_ALU_ADDUN
> +  UNSPEC_CV_ALU_ADDRN
> +  UNSPEC_CV_ALU_ADDURN
> +  UNSPEC_CV_ALU_SUBN
> +  UNSPEC_CV_ALU_SUBUN
> +  UNSPEC_CV_ALU_SUBRN
> +  UNSPEC_CV_ALU_SUBURN
> +  UNSPEC_CV_ALU_EXTHS
> +  UNSPEC_CV_ALU_EXTHZ
> +  UNSPEC_CV_ALU_EXTBS
> +  UNSPEC_CV_ALU_EXTBZ
> +])
> +
>  ;; XCVMAC extension.
>
>  (define_insn "riscv_cv_mac_mac"
> @@ -388,3 +409,267 @@
>    "cv.machhsRN\t%0,%1,%2,%4"
>    [(set_attr "type" "arith")
>    (set_attr "mode" "SI")])
> +
> +;; XCVALU builtins
> +
> +(define_insn "riscv_cv_alu_slet"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gt:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (const_int 0)
> +      (const_int 1)))]

Maybe just something like that? slt instruction using similar pattern like that.
(set (match_operand:SI 0 "register_operand" "=r")
       (gt:SI
         (match_operand:SI 1 "register_operand" "r")
         (match_operand:SI 2 "register_operand" "r")))


> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.slet\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_sletu"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gtu:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (const_int 0)
> +      (const_int 1)))]

Same comment as riscv_cv_alu_slet.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.sletu\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_min"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gt:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (match_dup:SI 2)
> +      (match_dup:SI 1)))]

Maybe something like that?

(set (match_operand:SI 0 "register_operand" "=r")
   (min
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))

> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.min\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_minu"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gtu:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (match_dup:SI 2)
> +      (match_dup:SI 1)))]


(set (match_operand:SI 0 "register_operand" "=r")
   (minu
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.minu\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_max"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gt:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (match_dup:SI 1)
> +      (match_dup:SI 2)))]

(set (match_operand:SI 0 "register_operand" "=r")
   (max
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.max\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_maxu"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gtu:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))


(set (match_operand:SI 0 "register_operand" "=r")
   (maxu
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))


> +      (match_dup:SI 1)
> +      (match_dup:SI 2)))]
> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.maxu\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_exths"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTHS))]

It's sign-extension from HI to SI?

if so that should just using sign_extend rather than unspec

  [(set (match_operand:SI 0 "register_operand" "=r")
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.exths\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_exthz"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTHZ))]

same comment as riscv_cv_alu_exths but zero_extend


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.exthz\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_extbs"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTBS))]
> +

same comment as riscv_cv_alu_exths with QI

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.extbs\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_extbz"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTBZ))]

same comment as riscv_cv_alu_exths with QI and zero_extend

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.extbz\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_clip"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
> +               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
> +    UNSPEC_CV_ALU_CLIP))]
> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.clip\t%0,%1,%X2
> +  cv.clipr\t%0,%1,%2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_clipu"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
> +               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
> +    UNSPEC_CV_ALU_CLIPU))]
> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.clipu\t%0,%1,%X2
> +  cv.clipur\t%0,%1,%2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_addN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDN))]

I think this should be able to using generic RTL rather than unspec to
represent that?

e.g.
(set (match_operand) (ashiftrt (plus (match_operand) (match_operand))
(match_operand)))

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.addN\t%0,%1,%2,%3
> +  cv.addNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_adduN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +               (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDUN))]
> +

same comment as riscv_cv_alu_addN but lshiftrt

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.adduN\t%0,%1,%2,%3
> +  cv.adduNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_addRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDRN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.addRN\t%0,%1,%2,%3
> +  cv.addRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_adduRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDURN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.adduRN\t%0,%1,%2,%3
> +  cv.adduRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subN\t%0,%1,%2,%3
> +  cv.subNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subuN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBUN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subuN\t%0,%1,%2,%3
> +  cv.subuNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBRN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subRN\t%0,%1,%2,%3
> +  cv.subRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subuRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBURN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subuRN\t%0,%1,%2,%3
> +  cv.subuRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
  

Patch

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 53e21fa4bce..e7c1a99fbd2 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -311,6 +311,7 @@  static const struct riscv_ext_version riscv_ext_version_table[] =
   {"svpbmt",  ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xcvmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xcvalu", ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1483,6 +1484,7 @@  static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
   {"ztso", &gcc_options::x_riscv_ztso_subext, MASK_ZTSO},
 
   {"xcvmac",        &gcc_options::x_riscv_xcv_flags, MASK_XCVMAC},
+  {"xcvalu",        &gcc_options::x_riscv_xcv_flags, MASK_XCVALU},
 
   {"xtheadba",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
   {"xtheadbb",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 3f52bc76f67..33e43260fac 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -131,6 +131,13 @@ 
 (define_register_constraint "zmvr" "(TARGET_ZFA || TARGET_XTHEADFMV) ? GR_REGS : NO_REGS"
   "An integer register for  ZFA or XTheadFmv.")
 
+;; CORE-V Constraints
+(define_constraint "CVP2"
+  "Checking for CORE-V ALU clip if ival plus 1 is a power of 2"
+  (and (match_code "const_int")
+       (and (match_test "IN_RANGE (ival, 0, 1073741823)")
+            (match_test "exact_log2 (ival + 1) != -1"))))
+
 ;; Vector constraints.
 
 (define_register_constraint "vr" "TARGET_VECTOR ? V_REGS : NO_REGS"
diff --git a/gcc/config/riscv/corev.def b/gcc/config/riscv/corev.def
index a4e94680d8e..17580df3c41 100644
--- a/gcc/config/riscv/corev.def
+++ b/gcc/config/riscv/corev.def
@@ -17,3 +17,27 @@  RISCV_BUILTIN (cv_mac_macuRN,    "cv_mac_macuRN",     RISCV_BUILTIN_DIRECT, RISC
 RISCV_BUILTIN (cv_mac_machhuRN,  "cv_mac_machhuRN",   RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_USI_UQI,  cvmac),
 RISCV_BUILTIN (cv_mac_macsRN,    "cv_mac_macsRN",     RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI_UQI,      cvmac),
 RISCV_BUILTIN (cv_mac_machhsRN,  "cv_mac_machhsRN",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI_UQI,      cvmac),
+
+// XCVALU
+RISCV_BUILTIN (cv_alu_slet,     "cv_alu_slet",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_sletu,    "cv_alu_sletu", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI,   cvalu),
+RISCV_BUILTIN (cv_alu_min,      "cv_alu_min",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_minu,     "cv_alu_minu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_max,      "cv_alu_max",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_maxu,     "cv_alu_maxu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+
+RISCV_BUILTIN (cv_alu_exths,    "cv_alu_exths", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_HI,        cvalu),
+RISCV_BUILTIN (cv_alu_exthz,    "cv_alu_exthz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UHI,      cvalu),
+RISCV_BUILTIN (cv_alu_extbs,    "cv_alu_extbs", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_QI,        cvalu),
+RISCV_BUILTIN (cv_alu_extbz,    "cv_alu_extbz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UQI,      cvalu),
+
+RISCV_BUILTIN (cv_alu_clip,     "cv_alu_clip",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_clipu,    "cv_alu_clipu", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_addN,     "cv_alu_addN",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduN,    "cv_alu_adduN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_addRN,    "cv_alu_addRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduRN,   "cv_alu_adduRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subN,     "cv_alu_subN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuN,    "cv_alu_subuN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subRN,    "cv_alu_subRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuRN,   "cv_alu_subuRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
index 59aeafe485f..30c8bcbe476 100644
--- a/gcc/config/riscv/corev.md
+++ b/gcc/config/riscv/corev.md
@@ -17,6 +17,27 @@ 
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+(define_c_enum "unspec" [
+
+  ;;CORE-V ALU
+  UNSPEC_CV_ALU_CLIP
+  UNSPEC_CV_ALU_CLIPR
+  UNSPEC_CV_ALU_CLIPU
+  UNSPEC_CV_ALU_CLIPUR
+  UNSPEC_CV_ALU_ADDN
+  UNSPEC_CV_ALU_ADDUN
+  UNSPEC_CV_ALU_ADDRN
+  UNSPEC_CV_ALU_ADDURN
+  UNSPEC_CV_ALU_SUBN
+  UNSPEC_CV_ALU_SUBUN
+  UNSPEC_CV_ALU_SUBRN
+  UNSPEC_CV_ALU_SUBURN
+  UNSPEC_CV_ALU_EXTHS
+  UNSPEC_CV_ALU_EXTHZ
+  UNSPEC_CV_ALU_EXTBS
+  UNSPEC_CV_ALU_EXTBZ
+])
+
 ;; XCVMAC extension.
 
 (define_insn "riscv_cv_mac_mac"
@@ -388,3 +409,267 @@ 
   "cv.machhsRN\t%0,%1,%2,%4"
   [(set_attr "type" "arith")
   (set_attr "mode" "SI")])
+
+;; XCVALU builtins
+
+(define_insn "riscv_cv_alu_slet"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gt:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (const_int 0)
+      (const_int 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.slet\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_sletu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gtu:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (const_int 0)
+      (const_int 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sletu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_min"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gt:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 2)
+      (match_dup:SI 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.min\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_minu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gtu:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 2)
+      (match_dup:SI 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.minu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_max"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gt:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 1)
+      (match_dup:SI 2)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.max\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_maxu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gtu:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 1)
+      (match_dup:SI 2)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.maxu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exths"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTHS))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exths\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exthz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTHZ))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exthz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTBS))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbs\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTBZ))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clip"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIP))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clip\t%0,%1,%X2
+  cv.clipr\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clipu"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIPU))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clipu\t%0,%1,%X2
+  cv.clipur\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addN\t%0,%1,%2,%3
+  cv.addNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+		(match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDUN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.adduN\t%0,%1,%2,%3
+  cv.adduNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDRN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addRN\t%0,%1,%2,%3
+  cv.addRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDURN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.adduRN\t%0,%1,%2,%3
+  cv.adduRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subN\t%0,%1,%2,%3
+  cv.subNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBUN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subuN\t%0,%1,%2,%3
+  cv.subuNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBRN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subRN\t%0,%1,%2,%3
+  cv.subRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBURN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subuRN\t%0,%1,%2,%3
+  cv.subuRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 4bc7ff2c9d8..0c6926dceb5 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -387,6 +387,11 @@ 
 	return true;
 })
 
+;; CORE-V Predicates:
+(define_predicate "immediate_register_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_code "const_int")))
+
 ;; Predicates for the V extension.
 (define_special_predicate "vector_length_operand"
   (ior (match_operand 0 "pmode_register_operand")
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 1f733337b82..fc3976f3ba1 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -127,6 +127,7 @@  AVAIL (hint_pause, (!0))
 
 // CORE-V AVAIL
 AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
+AVAIL (cvalu, TARGET_XCVALU && !TARGET_64BIT)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
@@ -163,6 +164,8 @@  AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
 #define RISCV_ATYPE_UHI unsigned_intHI_type_node
 #define RISCV_ATYPE_USI unsigned_intSI_type_node
 #define RISCV_ATYPE_UDI unsigned_intDI_type_node
+#define RISCV_ATYPE_QI intQI_type_node
+#define RISCV_ATYPE_HI intHI_type_node
 #define RISCV_ATYPE_SI intSI_type_node
 #define RISCV_ATYPE_VOID_PTR ptr_type_node
 
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index 430a4c2d673..0d1e4dd061e 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -32,6 +32,10 @@  DEF_RISCV_FTYPE (1, (VOID, USI))
 DEF_RISCV_FTYPE (1, (VOID, VOID_PTR))
 DEF_RISCV_FTYPE (1, (USI, USI))
 DEF_RISCV_FTYPE (1, (UDI, UDI))
+DEF_RISCV_FTYPE (1, (USI, UQI))
+DEF_RISCV_FTYPE (1, (USI, UHI))
+DEF_RISCV_FTYPE (1, (SI, QI))
+DEF_RISCV_FTYPE (1, (SI, HI))
 DEF_RISCV_FTYPE (2, (USI, UQI, UQI))
 DEF_RISCV_FTYPE (2, (USI, UHI, UHI))
 DEF_RISCV_FTYPE (2, (USI, USI, USI))
@@ -40,6 +44,8 @@  DEF_RISCV_FTYPE (2, (UDI, UHI, UHI))
 DEF_RISCV_FTYPE (2, (UDI, USI, USI))
 DEF_RISCV_FTYPE (2, (UDI, UDI, USI))
 DEF_RISCV_FTYPE (2, (UDI, UDI, UDI))
+DEF_RISCV_FTYPE (2, (SI, USI, USI))
+DEF_RISCV_FTYPE (2, (SI, SI, SI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, USI))
 DEF_RISCV_FTYPE (3, (SI, SI, SI, UQI))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 8b0aa1d1b41..ec929bc5fe9 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -296,6 +296,7 @@  enum riscv_entity
    : 32 << (__builtin_popcount (riscv_zvl_flags) - 1))
 
 #define MASK_XCVMAC    (1 <<  0)
+#define MASK_XCVALU    (1 <<  1)
 
 #define MASK_XTHEADBA      (1 << 0)
 #define MASK_XTHEADBB      (1 << 1)
@@ -312,6 +313,7 @@  enum riscv_entity
 
 
 #define TARGET_XCVMAC    ((riscv_xcv_flags & MASK_XCVMAC) != 0)
+#define TARGET_XCVALU    ((riscv_xcv_flags & MASK_XCVALU) != 0)
 
 #define TARGET_XTHEADBA      ((riscv_xthead_subext & MASK_XTHEADBA) != 0)
 #define TARGET_XTHEADBB      ((riscv_xthead_subext & MASK_XTHEADBB) != 0)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f1b721d54d1..ff73f2ba6d9 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5633,6 +5633,13 @@  riscv_print_operand (FILE *file, rtx op, int letter)
 	output_addr_const (file, newop);
 	break;
       }
+    case 'X':
+      {
+        int ival = INTVAL (op) + 1;
+        rtx newop = GEN_INT (ctz_hwi (ival) + 1);
+        output_addr_const (file, newop);
+	break;
+      }
     default:
       switch (code)
 	{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f6753de0028..e889b18b643 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21731,6 +21731,100 @@  Generates the @code{cv.macsRN} machine instruction.
 Generates the @code{cv.machhsRN} machine instruction.
 @end deftypefn
 
+These built-in functions are available for the CORE-V ALU machine
+architecture. For more information on CORE-V built-ins, please see
+@uref{https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md#listing-of-miscellaneous-alu-builtins-xcvalu}
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_slet (int32_t, int32_t)
+Generated assembler @code{cv.slet}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_sletu (uint32_t, uint32_t)
+Generated assembler @code{cv.sletu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_min (int32_t, int32_t)
+Generated assembler @code{cv.min}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_minu (uint32_t, uint32_t)
+Generated assembler @code{cv.minu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_max (int32_t, int32_t)
+Generated assembler @code{cv.max}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_tnt} __builtin_riscv_cv_alu_maxu (uint32_t, uint32_t)
+Generated assembler @code{cv.maxu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_exths (int16_t)
+Generated assembler @code{cv.exths}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_exthz (uint16_t)
+Generated assembler @code{cv.exthz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_extbs (int8_t)
+Generated assembler @code{cv.extbs}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_extbz (uint8_t)
+Generated assembler @code{cv.extbz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_clip (int32_t, uint32_t)
+Generated assembler @code{cv.clip} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipr} if  the it is a register.
+@end deftypefn
+ 
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_clipu (uint32_t, uint32_t)
+Generated assembler @code{cv.clipu} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipur} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuRNr} if  the it is a register.
+@end deftypefn
+
 @node RX Built-in Functions
 @subsection RX Built-in Functions
 GCC supports some of the RX instructions which cannot be expressed in
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
new file mode 100644
index 00000000000..4ce3a1b83b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
@@ -0,0 +1,252 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+#include <stdint.h>
+
+extern int d;
+extern int e;
+extern int f;
+
+void
+foo0(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addN (a, b, 31);
+}
+
+void
+foo1(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, c);
+}
+
+void
+foo2(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addRN (a, b, 31);
+}
+
+int
+foo3(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_addRN (a, b, c);
+}
+
+void
+foo4(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduN (a, b, 31);
+}
+
+int
+foo5(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduN (a, b, c);
+}
+
+void
+foo6(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduRN (a, b, 31);
+}
+
+int
+foo7(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduRN (a, b, c);
+}
+
+int
+foo8(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 15);
+}
+
+int
+foo9(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 10);
+}
+
+int
+foo10(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 15);
+}
+
+int
+foo11(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 10);
+}
+
+int
+foo12(int a)
+{
+  return __builtin_riscv_cv_alu_extbs (a);
+}
+
+int
+foo13(int a)
+{
+  return __builtin_riscv_cv_alu_extbz (a);
+}
+
+int
+foo14(int b)
+{
+  return __builtin_riscv_cv_alu_exths (b);
+}
+
+int
+foo15(int a)
+{
+  return __builtin_riscv_cv_alu_exthz (a);
+}
+
+int
+foo16(int a, int b)
+{
+  return __builtin_riscv_cv_alu_max (a, b);
+}
+
+int
+foo17(int a, int b)
+{
+  return __builtin_riscv_cv_alu_maxu (a, b);
+}
+
+int
+foo18(int a, int b)
+{
+  return __builtin_riscv_cv_alu_min (a, b);
+}
+
+int
+foo19(int a, int b)
+{
+  return __builtin_riscv_cv_alu_minu (a, b);
+}
+
+int
+foo20(int a, int b)
+{
+  return __builtin_riscv_cv_alu_slet (a, b);
+}
+
+int
+foo21(unsigned int a, unsigned int b)
+{
+  return __builtin_riscv_cv_alu_sletu (a, b);
+}
+
+void
+foo22(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subN (a, b, 31);
+}
+
+int
+foo23(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subN (a, b, c);
+}
+
+void
+foo24(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subRN (a, b, 31);
+}
+
+int
+foo25(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subRN (a, b, c);
+}
+
+void
+foo26(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuN (a, b, 31);
+}
+
+int
+foo27(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuN (a, b, c);
+}
+
+void
+foo28(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuRN (a, b, 31);
+}
+
+int
+foo29(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuRN (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "cv\.addN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.addNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.addRNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.adduNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.adduRNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clip\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clipu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipur\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.extbs\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.extbz\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.exths\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.exthz\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.max\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.maxu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.min\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.minu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.slet\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sletu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.subNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.subRNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.subuNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuRN\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.subuRNr\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
new file mode 100644
index 00000000000..aa8610f4c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
new file mode 100644
index 00000000000..12371b2c641
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
new file mode 100644
index 00000000000..3faad6c73c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
new file mode 100644
index 00000000000..39dc575b68e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
new file mode 100644
index 00000000000..a5ee231c74d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clip (a, 4294967296); /* { dg-warning "overflow in conversion from \'long long int\' to \'int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
new file mode 100644
index 00000000000..1ee11d2f600
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clipu (a, 4294967296); /* { dg-warning "unsigned conversion from \'long long int\' to \'unsigned int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
new file mode 100644
index 00000000000..91d6bd56672
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
new file mode 100644
index 00000000000..3c7e4ae63d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
new file mode 100644
index 00000000000..46218ea4451
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
new file mode 100644
index 00000000000..f20378dd839
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
new file mode 100644
index 00000000000..bbdb2d58c3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
@@ -0,0 +1,32 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i -mabi=ilp32" } */
+
+extern int d;
+
+int
+foo(int a, int b, int c)
+{
+    d += __builtin_riscv_cv_alu_slet (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_sletu (a, b);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addN (a, b, 31);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clip (a, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clipu (a, 35); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbs (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exths (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exthz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_min (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_minu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_max (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_maxu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+
+    return d;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 45baf112983..f376fd1340c 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12669,6 +12669,19 @@  proc check_effective_target_cv_mac { } {
     } "-march=rv32i_xcvmac" ]
 }
 
+# Return 1 if the CORE-V ALU extension is available.
+proc check_effective_target_cv_alu { } {
+    if { !([istarget riscv*-*-*]) } {
+         return 0
+     }
+    return [check_no_compiler_messages cv_alu object {
+        void foo (void)
+        {
+          asm ("cv.addn t0, t1, t2, 0");
+        }
+    } "-march=rv32i_xcvalu" ]
+}
+
 # Appends necessary Python flags to extra-tool-flags if Python.h is supported.
 # Otherwise, modifies dg-do-what.
 proc dg-require-python-h { args } {