[clang] [RISCV] Implement Clang Builtins for XCVmac Extension in CV32E40P (PR #110623)

via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 2 22:56:24 PDT 2024


https://github.com/realqhc updated https://github.com/llvm/llvm-project/pull/110623

>From da8b2fc0b5815f5870efe650ba5d585ec14e1a08 Mon Sep 17 00:00:00 2001
From: Qihan Cai <caiqihan021 at hotmail.com>
Date: Tue, 1 Oct 2024 12:14:15 +1000
Subject: [PATCH 1/3] [RISCV] Implement Clang Builtins for XCVmac Extension in
 CV32E40P

This commit adds the Clang Builtins, C API header and relevant tests for
XCVmac extension.

Spec:
https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md

Contributor: @PaoloS02
---
 clang/include/clang/Basic/BuiltinsRISCVXCV.td |  72 +++-
 clang/lib/CodeGen/CGBuiltin.cpp               |  55 +++
 clang/lib/Headers/CMakeLists.txt              |   1 +
 clang/lib/Headers/riscv_corev_mac.h           | 109 ++++++
 clang/test/CodeGen/RISCV/riscv-xcvmac-c-api.c | 343 ++++++++++++++++++
 clang/test/CodeGen/RISCV/riscv-xcvmac.c       | 309 ++++++++++++++++
 6 files changed, 872 insertions(+), 17 deletions(-)
 create mode 100644 clang/lib/Headers/riscv_corev_mac.h
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xcvmac-c-api.c
 create mode 100644 clang/test/CodeGen/RISCV/riscv-xcvmac.c

diff --git a/clang/include/clang/Basic/BuiltinsRISCVXCV.td b/clang/include/clang/Basic/BuiltinsRISCVXCV.td
index 06ce07ade5c122..4c813ecf3d33d3 100644
--- a/clang/include/clang/Basic/BuiltinsRISCVXCV.td
+++ b/clang/include/clang/Basic/BuiltinsRISCVXCV.td
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-class RISCXCVBuiltin<string prototype, string features = ""> : TargetBuiltin {
+class RISCVXCVBuiltin<string prototype, string features = ""> : TargetBuiltin {
   let Spellings = ["__builtin_riscv_cv_" # NAME];
   let Prototype = prototype;
   let Features = features;
@@ -21,21 +21,59 @@ let Attributes = [NoThrow, Const] in {
 //===----------------------------------------------------------------------===//
 // XCValu extension.
 //===----------------------------------------------------------------------===//
-def alu_slet  : RISCXCVBuiltin<"int(int, int)", "xcvalu">;
-def alu_sletu : RISCXCVBuiltin<"int(unsigned int, unsigned int)", "xcvalu">;
-def alu_exths : RISCXCVBuiltin<"int(int)", "xcvalu">;
-def alu_exthz : RISCXCVBuiltin<"unsigned int(unsigned int)", "xcvalu">;
-def alu_extbs : RISCXCVBuiltin<"int(int)", "xcvalu">;
-def alu_extbz : RISCXCVBuiltin<"unsigned int(unsigned int)", "xcvalu">;
+def alu_slet  : RISCVXCVBuiltin<"int(int, int)", "xcvalu">;
+def alu_sletu : RISCVXCVBuiltin<"int(unsigned int, unsigned int)", "xcvalu">;
+def alu_exths : RISCVXCVBuiltin<"int(int)", "xcvalu">;
+def alu_exthz : RISCVXCVBuiltin<"unsigned int(unsigned int)", "xcvalu">;
+def alu_extbs : RISCVXCVBuiltin<"int(int)", "xcvalu">;
+def alu_extbz : RISCVXCVBuiltin<"unsigned int(unsigned int)", "xcvalu">;
 
-def alu_clip   : RISCXCVBuiltin<"int(int, int)", "xcvalu">;
-def alu_clipu  : RISCXCVBuiltin<"unsigned int(unsigned int, unsigned int)", "xcvalu">;
-def alu_addN   : RISCXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
-def alu_adduN  : RISCXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
-def alu_addRN  : RISCXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
-def alu_adduRN : RISCXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
-def alu_subN   : RISCXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
-def alu_subuN  : RISCXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
-def alu_subRN  : RISCXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
-def alu_subuRN : RISCXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
+def alu_clip   : RISCVXCVBuiltin<"int(int, int)", "xcvalu">;
+def alu_clipu  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int)", "xcvalu">;
+def alu_addN   : RISCVXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
+def alu_adduN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
+def alu_addRN  : RISCVXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
+def alu_adduRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
+def alu_subN   : RISCVXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
+def alu_subuN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
+def alu_subRN  : RISCVXCVBuiltin<"int(int, int, unsigned int)", "xcvalu">;
+def alu_subuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)", "xcvalu">;
+
+//===----------------------------------------------------------------------===//
+// XCVmac extension.
+//===----------------------------------------------------------------------===//
+def mac_mac      : RISCVXCVBuiltin<"int(int, int, int)", "xcvmac">;
+def mac_msu      : RISCVXCVBuiltin<"int(int, int, int)", "xcvmac">;
+def mac_muluN    : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_mulhhuN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_mulsN    : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_mulhhsN  : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_muluRN   : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_mulhhuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_mulsRN   : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_mulhhsRN : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_macuN    : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_machhuN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_macsN    : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_machhsN  : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_macuRN   : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                    "xcvmac">;
+def mac_machhuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_macsRN   : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
+def mac_machhsRN : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+                                   "xcvmac">;
 } // Attributes = [NoThrow, Const]
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index da3eca73bfb575..c6b9e23721b7db 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -22389,6 +22389,61 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
   case RISCV::BI__builtin_riscv_cv_alu_subuRN:
     ID = Intrinsic::riscv_cv_alu_subuRN;
     break;
+  // XCVmac
+  case RISCV::BI__builtin_riscv_cv_mac_mac:
+    ID = Intrinsic::riscv_cv_mac_mac;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_msu:
+    ID = Intrinsic::riscv_cv_mac_msu;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_muluN:
+    ID = Intrinsic::riscv_cv_mac_muluN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhuN:
+    ID = Intrinsic::riscv_cv_mac_mulhhuN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_mulsN:
+    ID = Intrinsic::riscv_cv_mac_mulsN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhsN:
+    ID = Intrinsic::riscv_cv_mac_mulhhsN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_muluRN:
+    ID = Intrinsic::riscv_cv_mac_muluRN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhuRN:
+    ID = Intrinsic::riscv_cv_mac_mulhhuRN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_mulsRN:
+    ID = Intrinsic::riscv_cv_mac_mulsRN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhsRN:
+    ID = Intrinsic::riscv_cv_mac_mulhhsRN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_macuN:
+    ID = Intrinsic::riscv_cv_mac_macuN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_machhuN:
+    ID = Intrinsic::riscv_cv_mac_machhuN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_macsN:
+    ID = Intrinsic::riscv_cv_mac_macsN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_machhsN:
+    ID = Intrinsic::riscv_cv_mac_machhsN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_macuRN:
+    ID = Intrinsic::riscv_cv_mac_macuRN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_machhuRN:
+    ID = Intrinsic::riscv_cv_mac_machhuRN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_macsRN:
+    ID = Intrinsic::riscv_cv_mac_macsRN;
+    break;
+  case RISCV::BI__builtin_riscv_cv_mac_machhsRN:
+    ID = Intrinsic::riscv_cv_mac_machhsRN;
+    break;
 
     // Vector builtins are handled from here.
 #include "clang/Basic/riscv_vector_builtin_cg.inc"
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index ff392e7122a448..ff2aa6c999e851 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -121,6 +121,7 @@ set(ppc_htm_files
 set(riscv_files
   riscv_bitmanip.h
         riscv_corev_alu.h
+        riscv_corev_mac.h
   riscv_crypto.h
   riscv_ntlh.h
   sifive_vector.h
diff --git a/clang/lib/Headers/riscv_corev_mac.h b/clang/lib/Headers/riscv_corev_mac.h
new file mode 100644
index 00000000000000..9863162647606c
--- /dev/null
+++ b/clang/lib/Headers/riscv_corev_mac.h
@@ -0,0 +1,109 @@
+/*===---- riscv_corev_mac.h - CORE-V multiply accumulate intrinsics --------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __RISCV_COREV_MAC_H
+#define __RISCV_COREV_MAC_H
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__riscv_xcvmac)
+
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_mac_mac(long a, long b, long c) {
+  return __builtin_riscv_cv_mac_mac(a, b, c);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_mac_msu(long a, long b, long c) {
+  return __builtin_riscv_cv_mac_msu(a, b, c);
+}
+
+#define __riscv_cv_mac_muluN(rs1, rs2, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_muluN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_mulhhuN(rs1, rs2, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_mulhhuN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_mulsN(rs1, rs2, SHIFT) \
+  (long) __builtin_riscv_cv_mac_mulsN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_mulhhsN(rs1, rs2, SHIFT) \
+  (long) __builtin_riscv_cv_mac_mulhhsN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_muluRN(rs1, rs2, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_muluRN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_mulhhuRN(rs1, rs2, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_mulhhuRN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_mulsRN(rs1, rs2, SHIFT) \
+  (long) __builtin_riscv_cv_mac_mulsRN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_mulhhsRN(rs1, rs2, SHIFT) \
+  (long) __builtin_riscv_cv_mac_mulhhsRN((unsigned long) (rs1), \
+                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_macuN(rs1, rs2, rD, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_macuN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_machhuN(rs1, rs2, rD, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_machhuN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_macsN(rs1, rs2, rD, SHIFT) \
+  (long) __builtin_riscv_cv_mac_macsN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_machhsN(rs1, rs2, rD, SHIFT) \
+  (long) __builtin_riscv_cv_mac_machhsN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_macuRN(rs1, rs2, rD, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_macuRN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_machhuRN(rs1, rs2, rD, SHIFT) \
+  (unsigned long) __builtin_riscv_cv_mac_machhuRN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_macsRN(rs1, rs2, rD, SHIFT) \
+  (long) __builtin_riscv_cv_mac_macsRN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#define __riscv_cv_mac_machhsRN(rs1, rs2, rD, SHIFT) \
+  (long) __builtin_riscv_cv_mac_machhsRN((unsigned long) (rs1), \
+                                  (unsigned long) (rs2), (unsigned long) (rD), \
+                                  (const uint8_t) (SHIFT))
+
+#endif // defined(__riscv_xcvmac)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // define __RISCV_COREV_MAC_H
diff --git a/clang/test/CodeGen/RISCV/riscv-xcvmac-c-api.c b/clang/test/CodeGen/RISCV/riscv-xcvmac-c-api.c
new file mode 100644
index 00000000000000..34ed4bfe27c7e1
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xcvmac-c-api.c
@@ -0,0 +1,343 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xcvmac -emit-llvm %s -o - \
+// RUN:     | FileCheck %s
+
+#include <stdint.h>
+#include <riscv_corev_mac.h>
+
+// CHECK-LABEL: define dso_local i32 @test_mac_mac(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[C_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP2]], ptr [[C_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[C_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.riscv.cv.mac.mac(i32 [[TMP3]], i32 [[TMP4]], i32 [[TMP5]])
+// CHECK-NEXT:    ret i32 [[TMP6]]
+//
+int32_t test_mac_mac(int32_t x, int32_t y, int32_t z) {
+    return __riscv_cv_mac_mac(x, y, z);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_msu(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[A_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[B_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[C_ADDR_I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[TMP0]], ptr [[A_ADDR_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP1]], ptr [[B_ADDR_I]], align 4
+// CHECK-NEXT:    store i32 [[TMP2]], ptr [[C_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[A_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[B_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[C_ADDR_I]], align 4
+// CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.riscv.cv.mac.msu(i32 [[TMP3]], i32 [[TMP4]], i32 [[TMP5]])
+// CHECK-NEXT:    ret i32 [[TMP6]]
+//
+int32_t test_mac_msu(int32_t x, int32_t y, int32_t z) {
+    return __riscv_cv_mac_msu(x, y, z);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_muluN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_muluN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_muluN(x, y, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_mulhhuN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_mulhhuN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_mulhhuN(x, y, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_mulsN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulsN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_mulsN(x, y, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_mulhhsN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulhhsN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_mulhhsN(x, y, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_muluRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_muluRN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_muluRN(x, y, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_mulhhuRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_mulhhuRN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_mulhhuRN(x, y, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_mulsRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulsRN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_mulsRN(x, y, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_mulhhsRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulhhsRN(uint32_t x, uint32_t y) {
+    return __riscv_cv_mac_mulhhsRN(x, y, 0);
+}
+
+// 16-bit x 16-bit multiply-accumulate
+// CHECK-LABEL: define dso_local i32 @test_mac_macuN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_macuN(uint32_t x, uint32_t y, uint32_t z) {
+    return __riscv_cv_mac_macuN(x, y, z, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_machhuN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_machhuN(uint32_t x, uint32_t y, uint32_t z) {
+    return __riscv_cv_mac_machhuN(x, y, z, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_macsN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_macsN(uint32_t x, uint32_t y, int32_t z) {
+    return __riscv_cv_mac_macsN(x, y, z, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_machhsN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_machhsN(uint32_t x, uint32_t y, int32_t z) {
+    return __riscv_cv_mac_machhsN(x, y, z, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_macuRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_macuRN(uint32_t x, uint32_t y, uint32_t z) {
+    return __riscv_cv_mac_macuRN(x, y, z, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_machhuRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_machhuRN(uint32_t x, uint32_t y, uint32_t z) {
+    return __riscv_cv_mac_machhuRN(x, y, z, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_macsRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_macsRN(uint32_t x, uint32_t y, int32_t z) {
+    return __riscv_cv_mac_macsRN(x, y, z, 0);
+}
+
+// CHECK-LABEL: define dso_local i32 @test_mac_machhsRN(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]], i32 noundef [[Z:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_machhsRN(uint32_t x, uint32_t y, int32_t z) {
+    return __riscv_cv_mac_machhsRN(x, y, z, 0);
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-xcvmac.c b/clang/test/CodeGen/RISCV/riscv-xcvmac.c
new file mode 100644
index 00000000000000..eae3b806629a13
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xcvmac.c
@@ -0,0 +1,309 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xcvmac -emit-llvm %s -o - \
+// RUN:     | FileCheck %s
+
+
+#include <stdint.h>
+
+
+
+// CHECK-LABEL: @test_mac_mac(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.mac(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]])
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_mac(int32_t x, int32_t y, int32_t z) {
+    return __builtin_riscv_cv_mac_mac(x, y, z);
+}
+
+// CHECK-LABEL: @test_mac_msu(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.msu(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]])
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_msu(int32_t x, int32_t y, int32_t z) {
+    return __builtin_riscv_cv_mac_msu(x, y, z);
+}
+
+// CHECK-LABEL: @test_mac_muluN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_muluN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_muluN(x, y, 0);
+}
+
+// CHECK-LABEL: @test_mac_mulhhuN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_mulhhuN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_mulhhuN(x, y, 0);
+}
+
+// CHECK-LABEL: @test_mac_mulsN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsN(i32 [[TMP0]], i32 [[TMP1]], i32 1)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulsN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_mulsN(x, y, 1);
+}
+
+// CHECK-LABEL: @test_mac_mulhhsN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsN(i32 [[TMP0]], i32 [[TMP1]], i32 1)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulhhsN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_mulhhsN(x, y, 1);
+}
+
+// CHECK-LABEL: @test_mac_muluRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluRN(i32 [[TMP0]], i32 [[TMP1]], i32 2)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_muluRN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_muluRN(x, y, 2);
+}
+
+// CHECK-LABEL: @test_mac_mulhhuRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 2)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+uint32_t test_mac_mulhhuRN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_mulhhuRN(x, y, 2);
+}
+
+// CHECK-LABEL: @test_mac_mulsRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsRN(i32 [[TMP0]], i32 [[TMP1]], i32 3)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulsRN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_mulsRN(x, y, 3);
+}
+
+// CHECK-LABEL: @test_mac_mulhhsRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 3)
+// CHECK-NEXT:    ret i32 [[TMP2]]
+//
+int32_t test_mac_mulhhsRN(uint32_t x, uint32_t y) {
+    return __builtin_riscv_cv_mac_mulhhsRN(x, y, 3);
+}
+
+// 16-bit x 16-bit multiply-accumulate
+// CHECK-LABEL: @test_mac_macuN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 4)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_macuN(uint32_t x, uint32_t y, uint32_t z) {
+    return __builtin_riscv_cv_mac_macuN(x, y, z, 4);
+}
+
+// CHECK-LABEL: @test_mac_machhuN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 4)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_machhuN(uint32_t x, uint32_t y, uint32_t z) {
+    return __builtin_riscv_cv_mac_machhuN(x, y, z, 4);
+}
+
+// CHECK-LABEL: @test_mac_macsN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 5)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_macsN(uint32_t x, uint32_t y, int32_t z) {
+    return __builtin_riscv_cv_mac_macsN(x, y, z, 5);
+}
+
+// CHECK-LABEL: @test_mac_machhsN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 5)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_machhsN(uint32_t x, uint32_t y, int32_t z) {
+    return __builtin_riscv_cv_mac_machhsN(x, y, z, 5);
+}
+
+// CHECK-LABEL: @test_mac_macuRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 6)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_macuRN(uint32_t x, uint32_t y, uint32_t z) {
+    return __builtin_riscv_cv_mac_macuRN(x, y, z, 6);
+}
+
+// CHECK-LABEL: @test_mac_machhuRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 6)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+uint32_t test_mac_machhuRN(uint32_t x, uint32_t y, uint32_t z) {
+    return __builtin_riscv_cv_mac_machhuRN(x, y, z, 6);
+}
+
+// CHECK-LABEL: @test_mac_macsRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 7)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_macsRN(uint32_t x, uint32_t y, int32_t z) {
+    return __builtin_riscv_cv_mac_macsRN(x, y, z, 7);
+}
+
+// CHECK-LABEL: @test_mac_machhsRN(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Y_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 7)
+// CHECK-NEXT:    ret i32 [[TMP3]]
+//
+int32_t test_mac_machhsRN(uint32_t x, uint32_t y, int32_t z) {
+    return __builtin_riscv_cv_mac_machhsRN(x, y, z, 7);
+}

>From 5a089179b4b7af4cd04aeaf01575dd986906d72e Mon Sep 17 00:00:00 2001
From: Qihan Cai <caiqihan021 at hotmail.com>
Date: Tue, 1 Oct 2024 14:00:11 +1000
Subject: [PATCH 2/3] reformat

---
 clang/lib/Headers/CMakeLists.txt    |   4 +-
 clang/lib/Headers/riscv_corev_mac.h | 148 ++++++++++++++--------------
 2 files changed, 77 insertions(+), 75 deletions(-)

diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index ff2aa6c999e851..7e0358f83cefcb 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -120,8 +120,8 @@ set(ppc_htm_files
 
 set(riscv_files
   riscv_bitmanip.h
-        riscv_corev_alu.h
-        riscv_corev_mac.h
+  riscv_corev_alu.h
+  riscv_corev_mac.h
   riscv_crypto.h
   riscv_ntlh.h
   sifive_vector.h
diff --git a/clang/lib/Headers/riscv_corev_mac.h b/clang/lib/Headers/riscv_corev_mac.h
index 9863162647606c..33e9103cdd2f83 100644
--- a/clang/lib/Headers/riscv_corev_mac.h
+++ b/clang/lib/Headers/riscv_corev_mac.h
@@ -20,85 +20,87 @@ extern "C" {
 
 #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
 
-static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_mac_mac(long a, long b, long c) {
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_mac_mac(long a, long b,
+                                                             long c) {
   return __builtin_riscv_cv_mac_mac(a, b, c);
 }
 
-static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_mac_msu(long a, long b, long c) {
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_mac_msu(long a, long b,
+                                                             long c) {
   return __builtin_riscv_cv_mac_msu(a, b, c);
 }
 
-#define __riscv_cv_mac_muluN(rs1, rs2, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_muluN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_mulhhuN(rs1, rs2, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_mulhhuN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_mulsN(rs1, rs2, SHIFT) \
-  (long) __builtin_riscv_cv_mac_mulsN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_mulhhsN(rs1, rs2, SHIFT) \
-  (long) __builtin_riscv_cv_mac_mulhhsN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_muluRN(rs1, rs2, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_muluRN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_mulhhuRN(rs1, rs2, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_mulhhuRN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_mulsRN(rs1, rs2, SHIFT) \
-  (long) __builtin_riscv_cv_mac_mulsRN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_mulhhsRN(rs1, rs2, SHIFT) \
-  (long) __builtin_riscv_cv_mac_mulhhsRN((unsigned long) (rs1), \
-                                 (unsigned long) (rs2), (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_macuN(rs1, rs2, rD, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_macuN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_machhuN(rs1, rs2, rD, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_machhuN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_macsN(rs1, rs2, rD, SHIFT) \
-  (long) __builtin_riscv_cv_mac_macsN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_machhsN(rs1, rs2, rD, SHIFT) \
-  (long) __builtin_riscv_cv_mac_machhsN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_macuRN(rs1, rs2, rD, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_macuRN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_machhuRN(rs1, rs2, rD, SHIFT) \
-  (unsigned long) __builtin_riscv_cv_mac_machhuRN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_macsRN(rs1, rs2, rD, SHIFT) \
-  (long) __builtin_riscv_cv_mac_macsRN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
-
-#define __riscv_cv_mac_machhsRN(rs1, rs2, rD, SHIFT) \
-  (long) __builtin_riscv_cv_mac_machhsRN((unsigned long) (rs1), \
-                                  (unsigned long) (rs2), (unsigned long) (rD), \
-                                  (const uint8_t) (SHIFT))
+#define __riscv_cv_mac_muluN(rs1, rs2, SHIFT)                                  \
+  (unsigned long)__builtin_riscv_cv_mac_muluN(                                 \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_mulhhuN(rs1, rs2, SHIFT)                                \
+  (unsigned long)__builtin_riscv_cv_mac_mulhhuN(                               \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_mulsN(rs1, rs2, SHIFT)                                  \
+  (long)__builtin_riscv_cv_mac_mulsN(                                          \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_mulhhsN(rs1, rs2, SHIFT)                                \
+  (long)__builtin_riscv_cv_mac_mulhhsN(                                        \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_muluRN(rs1, rs2, SHIFT)                                 \
+  (unsigned long)__builtin_riscv_cv_mac_muluRN(                                \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_mulhhuRN(rs1, rs2, SHIFT)                               \
+  (unsigned long)__builtin_riscv_cv_mac_mulhhuRN(                              \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_mulsRN(rs1, rs2, SHIFT)                                 \
+  (long)__builtin_riscv_cv_mac_mulsRN(                                         \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_mulhhsRN(rs1, rs2, SHIFT)                               \
+  (long)__builtin_riscv_cv_mac_mulhhsRN(                                       \
+      (unsigned long)(rs1), (unsigned long)(rs2), (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_macuN(rs1, rs2, rD, SHIFT)                              \
+  (unsigned long)__builtin_riscv_cv_mac_macuN(                                 \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_machhuN(rs1, rs2, rD, SHIFT)                            \
+  (unsigned long)__builtin_riscv_cv_mac_machhuN(                               \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_macsN(rs1, rs2, rD, SHIFT)                              \
+  (long)__builtin_riscv_cv_mac_macsN(                                          \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_machhsN(rs1, rs2, rD, SHIFT)                            \
+  (long)__builtin_riscv_cv_mac_machhsN(                                        \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_macuRN(rs1, rs2, rD, SHIFT)                             \
+  (unsigned long)__builtin_riscv_cv_mac_macuRN(                                \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_machhuRN(rs1, rs2, rD, SHIFT)                           \
+  (unsigned long)__builtin_riscv_cv_mac_machhuRN(                              \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_macsRN(rs1, rs2, rD, SHIFT)                             \
+  (long)__builtin_riscv_cv_mac_macsRN(                                         \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
+
+#define __riscv_cv_mac_machhsRN(rs1, rs2, rD, SHIFT)                           \
+  (long)__builtin_riscv_cv_mac_machhsRN(                                       \
+      (unsigned long)(rs1), (unsigned long)(rs2), (unsigned long)(rD),         \
+      (const uint8_t)(SHIFT))
 
 #endif // defined(__riscv_xcvmac)
 

>From 69bdb09045b1c343d820d32f82205985cc8b7c50 Mon Sep 17 00:00:00 2001
From: Qihan Cai <caiqihan021 at hotmail.com>
Date: Thu, 3 Oct 2024 15:56:01 +1000
Subject: [PATCH 3/3] add check for SHIFT value

---
 clang/include/clang/Basic/BuiltinsRISCVXCV.td | 32 ++++-----
 clang/lib/Sema/SemaRISCV.cpp                  | 19 ++++++
 clang/test/CodeGen/RISCV/riscv-xcvmac.c       | 67 +++++++++----------
 3 files changed, 67 insertions(+), 51 deletions(-)

diff --git a/clang/include/clang/Basic/BuiltinsRISCVXCV.td b/clang/include/clang/Basic/BuiltinsRISCVXCV.td
index 4c813ecf3d33d3..db82b224d55c6f 100644
--- a/clang/include/clang/Basic/BuiltinsRISCVXCV.td
+++ b/clang/include/clang/Basic/BuiltinsRISCVXCV.td
@@ -44,36 +44,36 @@ def alu_subuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsig
 //===----------------------------------------------------------------------===//
 def mac_mac      : RISCVXCVBuiltin<"int(int, int, int)", "xcvmac">;
 def mac_msu      : RISCVXCVBuiltin<"int(int, int, int)", "xcvmac">;
-def mac_muluN    : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+def mac_muluN    : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_mulhhuN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+def mac_mulhhuN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_mulsN    : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+def mac_mulsN    : RISCVXCVBuiltin<"int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_mulhhsN  : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+def mac_mulhhsN  : RISCVXCVBuiltin<"int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_muluRN   : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+def mac_muluRN   : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_mulhhuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)",
+def mac_mulhhuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_mulsRN   : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+def mac_mulsRN   : RISCVXCVBuiltin<"int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_mulhhsRN : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int)",
+def mac_mulhhsRN : RISCVXCVBuiltin<"int(unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_macuN    : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_macuN    : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_machhuN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_machhuN  : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_macsN    : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_macsN    : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_machhsN  : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_machhsN  : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_macuRN   : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_macuRN   : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                     "xcvmac">;
-def mac_machhuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_machhuRN : RISCVXCVBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_macsRN   : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_macsRN   : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
-def mac_machhsRN : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, unsigned int)",
+def mac_machhsRN : RISCVXCVBuiltin<"int(unsigned int, unsigned int, unsigned int, _Constant unsigned int)",
                                    "xcvmac">;
 } // Attributes = [NoThrow, Const]
diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp
index 3da4b515b1b114..be9de14e250c3e 100644
--- a/clang/lib/Sema/SemaRISCV.cpp
+++ b/clang/lib/Sema/SemaRISCV.cpp
@@ -835,6 +835,25 @@ bool SemaRISCV::CheckBuiltinFunctionCall(const TargetInfo &TI,
   // Check if rnum is in [0, 10]
   case RISCV::BI__builtin_riscv_aes64ks1i:
     return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 10);
+  // Check if shift is in [0, 31]
+  case RISCV::BI__builtin_riscv_cv_mac_muluN:
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhuN:
+  case RISCV::BI__builtin_riscv_cv_mac_mulsN:
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhsN:
+  case RISCV::BI__builtin_riscv_cv_mac_muluRN:
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhuRN:
+  case RISCV::BI__builtin_riscv_cv_mac_mulsRN:
+  case RISCV::BI__builtin_riscv_cv_mac_mulhhsRN:
+    return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31);
+  case RISCV::BI__builtin_riscv_cv_mac_macuN:
+  case RISCV::BI__builtin_riscv_cv_mac_machhuN:
+  case RISCV::BI__builtin_riscv_cv_mac_macsN:
+  case RISCV::BI__builtin_riscv_cv_mac_machhsN:
+  case RISCV::BI__builtin_riscv_cv_mac_macuRN:
+  case RISCV::BI__builtin_riscv_cv_mac_machhuRN:
+  case RISCV::BI__builtin_riscv_cv_mac_macsRN:
+  case RISCV::BI__builtin_riscv_cv_mac_machhsRN:
+    return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 31);
   // Check if value range for vxrm is in [0, 3]
   case RISCVVector::BI__builtin_rvv_vaaddu_vv:
   case RISCVVector::BI__builtin_rvv_vaaddu_vx:
diff --git a/clang/test/CodeGen/RISCV/riscv-xcvmac.c b/clang/test/CodeGen/RISCV/riscv-xcvmac.c
index eae3b806629a13..9662710362250f 100644
--- a/clang/test/CodeGen/RISCV/riscv-xcvmac.c
+++ b/clang/test/CodeGen/RISCV/riscv-xcvmac.c
@@ -2,11 +2,8 @@
 // RUN: %clang_cc1 -triple riscv32 -target-feature +xcvmac -emit-llvm %s -o - \
 // RUN:     | FileCheck %s
 
-
 #include <stdint.h>
 
-
-
 // CHECK-LABEL: @test_mac_mac(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
@@ -51,11 +48,11 @@ int32_t test_mac_msu(int32_t x, int32_t y, int32_t z) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 uint32_t test_mac_muluN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_muluN(x, y, 0);
+    return __builtin_riscv_cv_mac_muluN(x, y, 31);
 }
 
 // CHECK-LABEL: @test_mac_mulhhuN(
@@ -66,11 +63,11 @@ uint32_t test_mac_muluN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 uint32_t test_mac_mulhhuN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_mulhhuN(x, y, 0);
+    return __builtin_riscv_cv_mac_mulhhuN(x, y, 31);
 }
 
 // CHECK-LABEL: @test_mac_mulsN(
@@ -81,11 +78,11 @@ uint32_t test_mac_mulhhuN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsN(i32 [[TMP0]], i32 [[TMP1]], i32 1)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 int32_t test_mac_mulsN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_mulsN(x, y, 1);
+    return __builtin_riscv_cv_mac_mulsN(x, y, 31);
 }
 
 // CHECK-LABEL: @test_mac_mulhhsN(
@@ -96,11 +93,11 @@ int32_t test_mac_mulsN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsN(i32 [[TMP0]], i32 [[TMP1]], i32 1)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 int32_t test_mac_mulhhsN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_mulhhsN(x, y, 1);
+    return __builtin_riscv_cv_mac_mulhhsN(x, y, 31);
 }
 
 // CHECK-LABEL: @test_mac_muluRN(
@@ -111,11 +108,11 @@ int32_t test_mac_mulhhsN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluRN(i32 [[TMP0]], i32 [[TMP1]], i32 2)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.muluRN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 uint32_t test_mac_muluRN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_muluRN(x, y, 2);
+    return __builtin_riscv_cv_mac_muluRN(x, y, 31);
 }
 
 // CHECK-LABEL: @test_mac_mulhhuRN(
@@ -126,11 +123,11 @@ uint32_t test_mac_muluRN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 2)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 uint32_t test_mac_mulhhuRN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_mulhhuRN(x, y, 2);
+    return __builtin_riscv_cv_mac_mulhhuRN(x, y, 31);
 }
 
 // CHECK-LABEL: @test_mac_mulsRN(
@@ -141,11 +138,11 @@ uint32_t test_mac_mulhhuRN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsRN(i32 [[TMP0]], i32 [[TMP1]], i32 3)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulsRN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 int32_t test_mac_mulsRN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_mulsRN(x, y, 3);
+    return __builtin_riscv_cv_mac_mulsRN(x, y, 31);
 }
 
 // CHECK-LABEL: @test_mac_mulhhsRN(
@@ -156,11 +153,11 @@ int32_t test_mac_mulsRN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    store i32 [[Y:%.*]], ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 3)
+// CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.riscv.cv.mac.mulhhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP2]]
 //
 int32_t test_mac_mulhhsRN(uint32_t x, uint32_t y) {
-    return __builtin_riscv_cv_mac_mulhhsRN(x, y, 3);
+    return __builtin_riscv_cv_mac_mulhhsRN(x, y, 31);
 }
 
 // 16-bit x 16-bit multiply-accumulate
@@ -175,11 +172,11 @@ int32_t test_mac_mulhhsRN(uint32_t x, uint32_t y) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 4)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 uint32_t test_mac_macuN(uint32_t x, uint32_t y, uint32_t z) {
-    return __builtin_riscv_cv_mac_macuN(x, y, z, 4);
+    return __builtin_riscv_cv_mac_macuN(x, y, z, 31);
 }
 
 // CHECK-LABEL: @test_mac_machhuN(
@@ -193,11 +190,11 @@ uint32_t test_mac_macuN(uint32_t x, uint32_t y, uint32_t z) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 4)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 uint32_t test_mac_machhuN(uint32_t x, uint32_t y, uint32_t z) {
-    return __builtin_riscv_cv_mac_machhuN(x, y, z, 4);
+    return __builtin_riscv_cv_mac_machhuN(x, y, z, 31);
 }
 
 // CHECK-LABEL: @test_mac_macsN(
@@ -211,11 +208,11 @@ uint32_t test_mac_machhuN(uint32_t x, uint32_t y, uint32_t z) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 5)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 int32_t test_mac_macsN(uint32_t x, uint32_t y, int32_t z) {
-    return __builtin_riscv_cv_mac_macsN(x, y, z, 5);
+    return __builtin_riscv_cv_mac_macsN(x, y, z, 31);
 }
 
 // CHECK-LABEL: @test_mac_machhsN(
@@ -229,11 +226,11 @@ int32_t test_mac_macsN(uint32_t x, uint32_t y, int32_t z) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 5)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 int32_t test_mac_machhsN(uint32_t x, uint32_t y, int32_t z) {
-    return __builtin_riscv_cv_mac_machhsN(x, y, z, 5);
+    return __builtin_riscv_cv_mac_machhsN(x, y, z, 31);
 }
 
 // CHECK-LABEL: @test_mac_macuRN(
@@ -247,11 +244,11 @@ int32_t test_mac_machhsN(uint32_t x, uint32_t y, int32_t z) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 6)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 uint32_t test_mac_macuRN(uint32_t x, uint32_t y, uint32_t z) {
-    return __builtin_riscv_cv_mac_macuRN(x, y, z, 6);
+    return __builtin_riscv_cv_mac_macuRN(x, y, z, 31);
 }
 
 // CHECK-LABEL: @test_mac_machhuRN(
@@ -265,11 +262,11 @@ uint32_t test_mac_macuRN(uint32_t x, uint32_t y, uint32_t z) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 6)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhuRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 uint32_t test_mac_machhuRN(uint32_t x, uint32_t y, uint32_t z) {
-    return __builtin_riscv_cv_mac_machhuRN(x, y, z, 6);
+    return __builtin_riscv_cv_mac_machhuRN(x, y, z, 31);
 }
 
 // CHECK-LABEL: @test_mac_macsRN(
@@ -283,11 +280,11 @@ uint32_t test_mac_machhuRN(uint32_t x, uint32_t y, uint32_t z) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 7)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.macsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 int32_t test_mac_macsRN(uint32_t x, uint32_t y, int32_t z) {
-    return __builtin_riscv_cv_mac_macsRN(x, y, z, 7);
+    return __builtin_riscv_cv_mac_macsRN(x, y, z, 31);
 }
 
 // CHECK-LABEL: @test_mac_machhsRN(
@@ -301,9 +298,9 @@ int32_t test_mac_macsRN(uint32_t x, uint32_t y, int32_t z) {
 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[Y_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[Z_ADDR]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 7)
+// CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.riscv.cv.mac.machhsRN(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]], i32 31)
 // CHECK-NEXT:    ret i32 [[TMP3]]
 //
 int32_t test_mac_machhsRN(uint32_t x, uint32_t y, int32_t z) {
-    return __builtin_riscv_cv_mac_machhsRN(x, y, z, 7);
+    return __builtin_riscv_cv_mac_machhsRN(x, y, z, 31);
 }



More information about the cfe-commits mailing list