[clang] [llvm] [RISCV] Implement Clang Builtins for XCValu Extension in CV32E40P (PR #100684)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 25 20:17:57 PDT 2024
https://github.com/realqhc updated https://github.com/llvm/llvm-project/pull/100684
>From a989acc4bb84b4224307c7535bcfbf623a88a9be Mon Sep 17 00:00:00 2001
From: Qihan Cai <caiqihan021 at hotmail.com>
Date: Fri, 26 Jul 2024 12:26:16 +1000
Subject: [PATCH] [RISCV] Implement Clang Builtins for XCValu Extension in
CV32E40P
This commit adds the Clang Builtins, C API header and relevant tests for XCValu extension.
Spec: https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md
Contributor: @melonedo, @PaoloS02
---
.../include/clang/Basic/BuiltinsRISCVXCV.def | 41 +++
clang/include/clang/Basic/TargetBuiltins.h | 10 +
clang/include/module.modulemap | 1 +
clang/lib/Basic/Targets/RISCV.cpp | 9 +-
clang/lib/CodeGen/CGBuiltin.cpp | 31 ++
clang/lib/Headers/CMakeLists.txt | 1 +
clang/lib/Headers/riscv_corev_alu.h | 128 ++++++++
clang/test/CodeGen/RISCV/riscv-xcvalu-c-api.c | 126 ++++++++
clang/test/CodeGen/RISCV/riscv-xcvalu.c | 303 ++++++++++++++++++
llvm/include/llvm/IR/IntrinsicsRISCVXCV.td | 26 +-
llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td | 27 +-
llvm/test/CodeGen/RISCV/xcvalu.ll | 222 +++++++++----
12 files changed, 852 insertions(+), 73 deletions(-)
create mode 100644 clang/include/clang/Basic/BuiltinsRISCVXCV.def
create mode 100644 clang/lib/Headers/riscv_corev_alu.h
create mode 100644 clang/test/CodeGen/RISCV/riscv-xcvalu-c-api.c
create mode 100644 clang/test/CodeGen/RISCV/riscv-xcvalu.c
diff --git a/clang/include/clang/Basic/BuiltinsRISCVXCV.def b/clang/include/clang/Basic/BuiltinsRISCVXCV.def
new file mode 100644
index 0000000000000..29c59cdf005d0
--- /dev/null
+++ b/clang/include/clang/Basic/BuiltinsRISCVXCV.def
@@ -0,0 +1,41 @@
+//==- BuiltinsRISCVXCV.def - RISC-V CORE-V Builtin database ----*- C++ -*-==//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CORE-V-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+TARGET_BUILTIN(alu_slet, "ZiZiZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_sletu, "ZiUZiUZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_min, "ZiZiZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_minu, "UZiUZiUZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_max, "ZiZiZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_maxu, "UZiUZiUZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_exths, "Zis", "nc", "xcvalu")
+TARGET_BUILTIN(alu_exthz, "UZiUs", "nc", "xcvalu")
+TARGET_BUILTIN(alu_extbs, "Zic", "nc", "xcvalu")
+TARGET_BUILTIN(alu_extbz, "UZiUc", "nc", "xcvalu")
+
+TARGET_BUILTIN(alu_clip, "ZiZiUZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_clipu, "UZiUZiUZi", "nc", "xcvalu")
+TARGET_BUILTIN(alu_addN, "ZiZiUZiUc", "nc", "xcvalu")
+TARGET_BUILTIN(alu_adduN, "UZiUZiUZiUc", "nc", "xcvalu")
+TARGET_BUILTIN(alu_addRN, "ZiZiZiUc", "nc", "xcvalu")
+TARGET_BUILTIN(alu_adduRN, "UZiUZiUZiUc", "nc", "xcvalu")
+TARGET_BUILTIN(alu_subN, "ZiZiUZiUc", "nc", "xcvalu")
+TARGET_BUILTIN(alu_subuN, "UZiUZiUZiUc", "nc", "xcvalu")
+TARGET_BUILTIN(alu_subRN, "ZiZiZiUc", "nc", "xcvalu")
+TARGET_BUILTIN(alu_subuRN, "UZiUZiUZiUc", "nc", "xcvalu")
+
+#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index 4333830bf34f2..81140286a8da2 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -152,12 +152,22 @@ namespace clang {
};
}
+ namespace RISCVXCV {
+ enum {
+ LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI__builtin_riscv_cv_##ID,
+#include "clang/Basic/BuiltinsRISCVXCV.def"
+ FirstTSBuiltin,
+ };
+ } // namespace RISCVXCV
+
/// RISCV builtins
namespace RISCV {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
FirstRVVBuiltin = clang::Builtin::FirstTSBuiltin,
LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1,
+ LastXCVBuiltin = RISCVXCV::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsRISCV.inc"
LastTSBuiltin
diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap
index 00ecd47d35b62..7f8b721f275c6 100644
--- a/clang/include/module.modulemap
+++ b/clang/include/module.modulemap
@@ -55,6 +55,7 @@ module Clang_Basic {
textual header "clang/Basic/BuiltinsNEON.def"
textual header "clang/Basic/BuiltinsNVPTX.def"
textual header "clang/Basic/BuiltinsPPC.def"
+ textual header "Basic/BuiltinsRISCVXCV.def"
textual header "clang/Basic/BuiltinsRISCVVector.def"
textual header "clang/Basic/BuiltinsSME.def"
textual header "clang/Basic/BuiltinsSVE.def"
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 41d836330b38c..97104998d8777 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -231,7 +231,14 @@ static constexpr Builtin::Info BuiltinInfo[] = {
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsRISCVVector.def"
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+ {"__builtin_riscv_cv_" #ID, TYPE, ATTRS, nullptr, \
+ HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {"__builtin_riscv_cv_" #ID, TYPE, ATTRS, FEATURE, \
+ HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#include "clang/Basic/BuiltinsRISCVXCV.def"
+#define BUILTIN(ID, TYPE, ATTRS) \
+ \ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsRISCV.inc"
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 0c4d0efb70ea5..90727de597cce 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -21901,6 +21901,30 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID,
return nullptr;
}
+static Value *EmitXCVIntrinsic(CodeGenFunction &CGF, unsigned BuiltinID,
+ unsigned IntrinsicID,
+ MutableArrayRef<Value *> Ops,
+ const CallExpr *E) {
+ llvm::Type *MachineType =
+ llvm::IntegerType::getInt32Ty(CGF.CGM.getLLVMContext());
+ for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
+ if (Ops[i]->getType() != MachineType) {
+ QualType type = E->getArg(i)->getType();
+ assert((type->isSignedIntegerType() || type->isUnsignedIntegerType() ||
+ type->isPointerType()) &&
+ "Argument of Core-V builtin must have signed or unsigned integer "
+ "or Pointer type");
+ if (type->isSignedIntegerType()) {
+ Ops[i] = CGF.Builder.CreateSExt(Ops[i], MachineType);
+ } else if ((type->isUnsignedIntegerType())) {
+ Ops[i] = CGF.Builder.CreateZExt(Ops[i], MachineType);
+ }
+ }
+ }
+ llvm::Function *F = CGF.CGM.getIntrinsic(IntrinsicID);
+ return CGF.Builder.CreateCall(F, Ops);
+}
+
Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
const CallExpr *E,
ReturnValueSlot ReturnValue) {
@@ -22126,6 +22150,13 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
return Store;
}
+// Core-V
+#define BUILTIN(NAME, TYPE, ATTRS) \
+ case RISCVXCV::BI__builtin_riscv_cv_##NAME: \
+ ID = Intrinsic::riscv_cv_##NAME; \
+ return EmitXCVIntrinsic(*this, BuiltinID, ID, Ops, E);
+#include "clang/Basic/BuiltinsRISCVXCV.def"
+
// Vector builtins are handled from here.
#include "clang/Basic/riscv_vector_builtin_cg.inc"
// SiFive Vector builtins are handled from here.
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 89fa0ecd45eb4..76a82b845fe23 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -122,6 +122,7 @@ set(riscv_files
riscv_crypto.h
riscv_ntlh.h
sifive_vector.h
+ riscv_corev_alu.h
)
set(systemz_files
diff --git a/clang/lib/Headers/riscv_corev_alu.h b/clang/lib/Headers/riscv_corev_alu.h
new file mode 100644
index 0000000000000..d6230022579b8
--- /dev/null
+++ b/clang/lib/Headers/riscv_corev_alu.h
@@ -0,0 +1,128 @@
+/*===---- riscv_corev_alu.h - CORE-V ALU 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_ALU_H
+#define __RISCV_COREV_ALU_H
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__riscv_xcvalu)
+
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_abs(long a) {
+ return __builtin_abs(a);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_slet(long a, long b) {
+ return __builtin_riscv_cv_alu_slet(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_sletu(unsigned long a, unsigned long b) {
+ return __builtin_riscv_cv_alu_sletu(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_min(long a, long b) {
+ return __builtin_riscv_cv_alu_min(a, b);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_minu(unsigned long a, unsigned long b) {
+ return __builtin_riscv_cv_alu_minu(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_max(long a, long b) {
+ return __builtin_riscv_cv_alu_max(a, b);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_maxu(unsigned long a, unsigned long b) {
+ return __builtin_riscv_cv_alu_maxu(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_exths(int16_t a) {
+ return __builtin_riscv_cv_alu_exths(a);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_exthz(uint16_t a) {
+ return __builtin_riscv_cv_alu_exthz(a);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_extbs(int8_t a) {
+ return __builtin_riscv_cv_alu_extbs(a);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_extbz(uint8_t a) {
+ return __builtin_riscv_cv_alu_extbz(a);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_clip(long a,
+ unsigned long b) {
+ return __builtin_riscv_cv_alu_clip(a, b);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_clipu(unsigned long a, unsigned long b) {
+ return __builtin_riscv_cv_alu_clipu(a, b);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_addN(long a, long b,
+ uint8_t shft) {
+ return __builtin_riscv_cv_alu_addN(a, b, shft);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_adduN(unsigned long a, unsigned long b, uint8_t shft) {
+ return __builtin_riscv_cv_alu_adduN(a, b, shft);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_addRN(long a, long b,
+ uint8_t shft) {
+ return __builtin_riscv_cv_alu_addRN(a, b, shft);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_adduRN(unsigned long a, unsigned long b, uint8_t shft) {
+ return __builtin_riscv_cv_alu_adduRN(a, b, shft);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_subN(long a, long b,
+ uint8_t shft) {
+ return __builtin_riscv_cv_alu_subN(a, b, shft);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_subuN(unsigned long a, unsigned long b, uint8_t shft) {
+ return __builtin_riscv_cv_alu_subuN(a, b, shft);
+}
+
+static __inline__ long __DEFAULT_FN_ATTRS __riscv_cv_alu_subRN(long a, long b,
+ uint8_t shft) {
+ return __builtin_riscv_cv_alu_subRN(a, b, shft);
+}
+
+static __inline__ unsigned long __DEFAULT_FN_ATTRS
+__riscv_cv_alu_subuRN(unsigned long a, unsigned long b, uint8_t shft) {
+ return __builtin_riscv_cv_alu_subuRN(a, b, shft);
+}
+
+#endif // defined(__riscv_xcvalu)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // define __RISCV_COREV_ALU_H
diff --git a/clang/test/CodeGen/RISCV/riscv-xcvalu-c-api.c b/clang/test/CodeGen/RISCV/riscv-xcvalu-c-api.c
new file mode 100644
index 0000000000000..d5c16fbe3d766
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xcvalu-c-api.c
@@ -0,0 +1,126 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xcvalu -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+
+#include <stdint.h>
+#include <riscv_corev_alu.h>
+
+// CHECK-LABEL: @test_alu_slet
+// CHECK: @llvm.riscv.cv.alu.slet
+int test_alu_slet(int32_t a, int32_t b) {
+ return __riscv_cv_alu_slet(a, b);
+}
+
+// CHECK-LABEL: @test_alu_sletu
+// CHECK: @llvm.riscv.cv.alu.sletu
+int test_alu_sletu(uint32_t a, uint32_t b) {
+ return __riscv_cv_alu_sletu(a, b);
+}
+
+// CHECK-LABEL: @test_alu_min
+// CHECK: @llvm.riscv.cv.alu.min
+int test_alu_min(int32_t a, int32_t b) {
+ return __riscv_cv_alu_min(a, b);
+}
+
+// CHECK-LABEL: @test_alu_minu
+// CHECK: @llvm.riscv.cv.alu.minu
+int test_alu_minu(uint32_t a, uint32_t b) {
+ return __riscv_cv_alu_minu(a, b);
+}
+
+// CHECK-LABEL: @test_alu_max
+// CHECK: @llvm.riscv.cv.alu.max
+int test_alu_max(int32_t a, int32_t b) {
+ return __riscv_cv_alu_max(a, b);
+}
+
+// CHECK-LABEL: @test_alu_maxu
+// CHECK: @llvm.riscv.cv.alu.maxu
+int test_alu_maxu(uint32_t a, uint32_t b) {
+ return __riscv_cv_alu_maxu(a, b);
+}
+
+// CHECK-LABEL: @test_alu_exths
+// CHECK: @llvm.riscv.cv.alu.exths
+int test_alu_exths(int16_t a) {
+ return __riscv_cv_alu_exths(a);
+}
+
+// CHECK-LABEL: @test_alu_exthz
+// CHECK: @llvm.riscv.cv.alu.exthz
+int test_alu_exthz(uint16_t a) {
+ return __riscv_cv_alu_exthz(a);
+}
+
+// CHECK-LABEL: @test_alu_extbs
+// CHECK: @llvm.riscv.cv.alu.extbs
+int test_alu_extbs(int8_t a) {
+ return __riscv_cv_alu_extbs(a);
+}
+
+// CHECK-LABEL: @test_alu_extbz
+// CHECK: @llvm.riscv.cv.alu.extbz
+int test_alu_extbz(uint8_t a) {
+ return __riscv_cv_alu_extbz(a);
+}
+
+// CHECK-LABEL: @test_alu_clip
+// CHECK: @llvm.riscv.cv.alu.clip
+int test_alu_clip(int32_t a) {
+ return __riscv_cv_alu_clip(a, 0);
+}
+
+// CHECK-LABEL: @test_alu_clipu
+// CHECK: @llvm.riscv.cv.alu.clipu
+int test_alu_clipu(uint32_t a) {
+ return __riscv_cv_alu_clipu(a, 0);
+}
+
+// CHECK-LABEL: @test_alu_addN
+// CHECK: @llvm.riscv.cv.alu.addN
+int test_alu_addN(int32_t a, int32_t b) {
+ return __riscv_cv_alu_addN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_adduN
+// CHECK: @llvm.riscv.cv.alu.adduN
+int test_alu_adduN(uint32_t a, uint32_t b) {
+ return __riscv_cv_alu_adduN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_addRN
+// CHECK: @llvm.riscv.cv.alu.addRN
+int test_alu_addRN(int32_t a, int32_t b) {
+ return __riscv_cv_alu_addRN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_adduRN
+// CHECK: @llvm.riscv.cv.alu.adduRN
+int test_alu_adduRN(uint32_t a, uint32_t b) {
+ return __riscv_cv_alu_adduRN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subN
+// CHECK: @llvm.riscv.cv.alu.subN
+int test_alu_subN(int32_t a, int32_t b) {
+ return __riscv_cv_alu_subN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subuN
+// CHECK: @llvm.riscv.cv.alu.subuN
+int test_alu_subuN(uint32_t a, uint32_t b) {
+ return __riscv_cv_alu_subuN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subRN
+// CHECK: @llvm.riscv.cv.alu.subRN
+int test_alu_subRN(int32_t a, int32_t b) {
+ return __riscv_cv_alu_subRN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subuRN
+// CHECK: @llvm.riscv.cv.alu.subuRN
+int test_alu_subuRN(uint32_t a, uint32_t b) {
+ return __riscv_cv_alu_subuRN(a, b, 0);
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-xcvalu.c b/clang/test/CodeGen/RISCV/riscv-xcvalu.c
new file mode 100644
index 0000000000000..a3b8c07f22c81
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-xcvalu.c
@@ -0,0 +1,303 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +xcvalu -emit-llvm %s -o - \
+// RUN: | FileCheck %s
+
+#include <stdint.h>
+
+// CHECK-LABEL: @test_abs(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP0]], i1 true)
+// CHECK-NEXT: ret i32 [[TMP1]]
+//
+int test_abs(int a) {
+ return __builtin_abs(a);
+}
+
+// CHECK-LABEL: @test_alu_slet(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.slet(i32 [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_slet(int32_t a, int32_t b) {
+ return __builtin_riscv_cv_alu_slet(a, b);
+}
+
+// CHECK-LABEL: @test_alu_sletu(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.sletu(i32 [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_sletu(uint32_t a, uint32_t b) {
+ return __builtin_riscv_cv_alu_sletu(a, b);
+}
+
+// CHECK-LABEL: @test_alu_min(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.min(i32 [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_min(int32_t a, int32_t b) {
+ return __builtin_riscv_cv_alu_min(a, b);
+}
+
+// CHECK-LABEL: @test_alu_minu(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.minu(i32 [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_minu(uint32_t a, uint32_t b) {
+ return __builtin_riscv_cv_alu_minu(a, b);
+}
+
+// CHECK-LABEL: @test_alu_max(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.max(i32 [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_max(int32_t a, int32_t b) {
+ return __builtin_riscv_cv_alu_max(a, b);
+}
+
+// CHECK-LABEL: @test_alu_maxu(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.maxu(i32 [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_maxu(uint32_t a, uint32_t b) {
+ return __builtin_riscv_cv_alu_maxu(a, b);
+}
+
+// CHECK-LABEL: @test_alu_exths(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i16, align 2
+// CHECK-NEXT: store i16 [[A:%.*]], ptr [[A_ADDR]], align 2
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[A_ADDR]], align 2
+// CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.exths(i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_exths(int16_t a) {
+ return __builtin_riscv_cv_alu_exths(a);
+}
+
+// CHECK-LABEL: @test_alu_exthz(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i16, align 2
+// CHECK-NEXT: store i16 [[A:%.*]], ptr [[A_ADDR]], align 2
+// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[A_ADDR]], align 2
+// CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[TMP0]] to i32
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.exthz(i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_exthz(uint16_t a) {
+ return __builtin_riscv_cv_alu_exthz(a);
+}
+
+// CHECK-LABEL: @test_alu_extbs(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT: store i8 [[A:%.*]], ptr [[A_ADDR]], align 1
+// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[A_ADDR]], align 1
+// CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[TMP0]] to i32
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.extbs(i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_extbs(int8_t a) {
+ return __builtin_riscv_cv_alu_extbs(a);
+}
+
+// CHECK-LABEL: @test_alu_extbz(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT: store i8 [[A:%.*]], ptr [[A_ADDR]], align 1
+// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[A_ADDR]], align 1
+// CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i32
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.extbz(i32 [[TMP1]])
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_extbz(uint8_t a) {
+ return __builtin_riscv_cv_alu_extbz(a);
+}
+
+// CHECK-LABEL: @test_alu_clip(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.cv.alu.clip(i32 [[TMP0]], i32 15)
+// CHECK-NEXT: ret i32 [[TMP1]]
+//
+int test_alu_clip(int32_t a) {
+ return __builtin_riscv_cv_alu_clip(a, 15);
+}
+
+// CHECK-LABEL: @test_alu_clipu(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.riscv.cv.alu.clipu(i32 [[TMP0]], i32 15)
+// CHECK-NEXT: ret i32 [[TMP1]]
+//
+int test_alu_clipu(uint32_t a) {
+ return __builtin_riscv_cv_alu_clipu(a, 15);
+}
+
+// CHECK-LABEL: @test_alu_addN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.addN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_addN(int32_t a, int32_t b) {
+ return __builtin_riscv_cv_alu_addN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_adduN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.adduN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_adduN(uint32_t a, uint32_t b) {
+ return __builtin_riscv_cv_alu_adduN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_addRN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.addRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_addRN(int32_t a, int32_t b) {
+ return __builtin_riscv_cv_alu_addRN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_adduRN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.adduRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_adduRN(uint32_t a, uint32_t b) {
+ return __builtin_riscv_cv_alu_adduRN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.subN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_subN(int32_t a, int32_t b) {
+ return __builtin_riscv_cv_alu_subN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subuN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.subuN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_subuN(uint32_t a, uint32_t b) {
+ return __builtin_riscv_cv_alu_subuN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subRN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.subRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_subRN(int32_t a, int32_t b) {
+ return __builtin_riscv_cv_alu_subRN(a, b, 0);
+}
+
+// CHECK-LABEL: @test_alu_subuRN(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR]], align 4
+// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.riscv.cv.alu.subuRN(i32 [[TMP0]], i32 [[TMP1]], i32 0)
+// CHECK-NEXT: ret i32 [[TMP2]]
+//
+int test_alu_subuRN(uint32_t a, uint32_t b) {
+ return __builtin_riscv_cv_alu_subuRN(a, b, 0);
+}
diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td b/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td
index 38263f375c469..02105900d037a 100644
--- a/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td
+++ b/llvm/include/llvm/IR/IntrinsicsRISCVXCV.td
@@ -59,16 +59,26 @@ let TargetPrefix = "riscv" in {
[IntrNoMem, IntrWillReturn, IntrSpeculatable,
ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+ def int_riscv_cv_alu_slet : ScalarCoreVAluGprGprIntrinsic;
+ def int_riscv_cv_alu_sletu : ScalarCoreVAluGprGprIntrinsic;
+ def int_riscv_cv_alu_min : ScalarCoreVAluGprGprIntrinsic;
+ def int_riscv_cv_alu_minu : ScalarCoreVAluGprGprIntrinsic;
+ def int_riscv_cv_alu_max : ScalarCoreVAluGprGprIntrinsic;
+ def int_riscv_cv_alu_maxu : ScalarCoreVAluGprGprIntrinsic;
+ def int_riscv_cv_alu_exths : ScalarCoreVAluGprIntrinsic;
+ def int_riscv_cv_alu_exthz : ScalarCoreVAluGprIntrinsic;
+ def int_riscv_cv_alu_extbs : ScalarCoreVAluGprIntrinsic;
+ def int_riscv_cv_alu_extbz : ScalarCoreVAluGprIntrinsic;
def int_riscv_cv_alu_clip : ScalarCoreVAluGprGprIntrinsic;
def int_riscv_cv_alu_clipu : ScalarCoreVAluGprGprIntrinsic;
- def int_riscv_cv_alu_addn : ScalarCoreVAluGprGprGprIntrinsic;
- def int_riscv_cv_alu_addun : ScalarCoreVAluGprGprGprIntrinsic;
- def int_riscv_cv_alu_addrn : ScalarCoreVAluGprGprGprIntrinsic;
- def int_riscv_cv_alu_addurn : ScalarCoreVAluGprGprGprIntrinsic;
- def int_riscv_cv_alu_subn : ScalarCoreVAluGprGprGprIntrinsic;
- def int_riscv_cv_alu_subun : ScalarCoreVAluGprGprGprIntrinsic;
- def int_riscv_cv_alu_subrn : ScalarCoreVAluGprGprGprIntrinsic;
- def int_riscv_cv_alu_suburn : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_addN : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_adduN : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_addRN : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_adduRN : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_subN : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_subuN : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_subRN : ScalarCoreVAluGprGprGprIntrinsic;
+ def int_riscv_cv_alu_subuRN : ScalarCoreVAluGprGprGprIntrinsic;
def int_riscv_cv_mac_mac : ScalarCoreVMacGprGprGprIntrinsic;
def int_riscv_cv_mac_msu : ScalarCoreVMacGprGprGprIntrinsic;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
index 3bd6da2868286..e67999cc11a98 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
@@ -789,16 +789,27 @@ let Predicates = [HasVendorXCValu, IsRV32], AddedComplexity = 1 in {
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (CV_EXTBS GPR:$rs1)>;
def : Pat<(and (XLenVT GPR:$rs1), 0xffff), (CV_EXTHZ GPR:$rs1)>;
+ def : PatCoreVAluGprGpr<"slet", "SLET">;
+ def : PatCoreVAluGprGpr<"sletu", "SLETU">;
+ def : PatCoreVAluGprGpr<"min", "MIN">;
+ def : PatCoreVAluGprGpr<"minu", "MINU">;
+ def : PatCoreVAluGprGpr<"max", "MAX">;
+ def : PatCoreVAluGprGpr<"maxu", "MAXU">;
+ def : PatCoreVAluGpr<"exths", "EXTHS">;
+ def : PatCoreVAluGpr<"exthz", "EXTHZ">;
+ def : PatCoreVAluGpr<"extbs", "EXTBS">;
+ def : PatCoreVAluGpr<"extbz", "EXTBZ">;
+
defm CLIP : PatCoreVAluGprImm<int_riscv_cv_alu_clip>;
defm CLIPU : PatCoreVAluGprImm<int_riscv_cv_alu_clipu>;
- defm ADDN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addn>;
- defm ADDUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addun>;
- defm ADDRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addrn>;
- defm ADDURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addurn>;
- defm SUBN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subn>;
- defm SUBUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subun>;
- defm SUBRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subrn>;
- defm SUBURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_suburn>;
+ defm ADDN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addN>;
+ defm ADDUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_adduN>;
+ defm ADDRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addRN>;
+ defm ADDURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_adduRN>;
+ defm SUBN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subN>;
+ defm SUBUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subuN>;
+ defm SUBRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subRN>;
+ defm SUBURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subuRN>;
} // Predicates = [HasVendorXCValu, IsRV32]
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/RISCV/xcvalu.ll b/llvm/test/CodeGen/RISCV/xcvalu.ll
index b1031731d06fa..b37e03bb0fc34 100644
--- a/llvm/test/CodeGen/RISCV/xcvalu.ll
+++ b/llvm/test/CodeGen/RISCV/xcvalu.ll
@@ -91,6 +91,116 @@ define i32 @exthz(i16 %a) {
ret i32 %1
}
+declare i32 @llvm.riscv.cv.alu.slet(i32, i32)
+
+define i32 @test.cv.alu.slet(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.slet:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.slet a0, a0, a1
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.slet(i32 %a, i32 %b)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.sletu(i32, i32)
+
+define i32 @test.cv.alu.sletu(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.sletu:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.sletu a0, a0, a1
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.sletu(i32 %a, i32 %b)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.min(i32, i32)
+
+define i32 @test.cv.alu.min(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.min:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.min a0, a0, a1
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.min(i32 %a, i32 %b)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.minu(i32, i32)
+
+define i32 @test.cv.alu.minu(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.minu:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.minu a0, a0, a1
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.minu(i32 %a, i32 %b)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.max(i32, i32)
+
+define i32 @test.cv.alu.max(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.max:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.max a0, a0, a1
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.max(i32 %a, i32 %b)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.maxu(i32, i32)
+
+define i32 @test.cv.alu.maxu(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.maxu:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.maxu a0, a0, a1
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.maxu(i32 %a, i32 %b)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.exths(i32)
+
+define i32 @test.cv.alu.exths(i32 %a) {
+; CHECK-LABEL: test.cv.alu.exths:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.exths a0, a0
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.exths(i32 %a)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.exthz(i32)
+
+define i32 @test.cv.alu.exthz(i32 %a) {
+; CHECK-LABEL: test.cv.alu.exthz:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.exthz a0, a0
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.exthz(i32 %a)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.extbs(i32)
+
+define i32 @test.cv.alu.extbs(i32 %a) {
+; CHECK-LABEL: test.cv.alu.extbs:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.extbs a0, a0
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.extbs(i32 %a)
+ ret i32 %1
+}
+
+declare i32 @llvm.riscv.cv.alu.extbz(i32)
+
+define i32 @test.cv.alu.extbz(i32 %a) {
+; CHECK-LABEL: test.cv.alu.extbz:
+; CHECK: # %bb.0:
+; CHECK-NEXT: cv.extbz a0, a0
+; CHECK-NEXT: ret
+ %1 = call i32 @llvm.riscv.cv.alu.extbz(i32 %a)
+ ret i32 %1
+}
+
declare i32 @llvm.riscv.cv.alu.clip(i32, i32)
define i32 @test.cv.alu.clip.case.a(i32 %a) {
@@ -133,170 +243,170 @@ define i32 @test.cv.alu.clipu.case.b(i32 %a) {
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.addn(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.addN(i32, i32, i32)
-define i32 @test.cv.alu.addn.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addn.case.a:
+define i32 @test.cv.alu.addN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.addN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.addn a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addn(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.addN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.addn.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addn.case.b:
+define i32 @test.cv.alu.addN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.addN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.addnr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addn(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.addN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.addun(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.adduN(i32, i32, i32)
-define i32 @test.cv.alu.addun.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addun.case.a:
+define i32 @test.cv.alu.adduN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.adduN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.addun a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addun(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.adduN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.addun.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addun.case.b:
+define i32 @test.cv.alu.adduN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.adduN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.addunr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addun(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.adduN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.addrn(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.addRN(i32, i32, i32)
-define i32 @test.cv.alu.addrn.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addrn.case.a:
+define i32 @test.cv.alu.addRN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.addRN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.addrn a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addrn(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.addRN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.addrn.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addrn.case.b:
+define i32 @test.cv.alu.addRN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.addRN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.addrnr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addrn(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.addRN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.addurn(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.adduRN(i32, i32, i32)
-define i32 @test.cv.alu.addurn.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addurn.case.a:
+define i32 @test.cv.alu.adduRN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.adduRN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.addurn a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addurn(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.adduRN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.addurn.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.addurn.case.b:
+define i32 @test.cv.alu.adduRN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.adduRN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.addurnr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.addurn(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.adduRN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.subn(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.subN(i32, i32, i32)
-define i32 @test.cv.alu.subn.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.subn.case.a:
+define i32 @test.cv.alu.subN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.subn a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.subn(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.subN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.subn.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.subn.case.b:
+define i32 @test.cv.alu.subN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.subnr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.subn(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.subN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.subun(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.subuN(i32, i32, i32)
-define i32 @test.cv.alu.subun.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.subun.case.a:
+define i32 @test.cv.alu.subuN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subuN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.subun a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.subun(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.subuN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.subun.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.subun.case.b:
+define i32 @test.cv.alu.subuN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subuN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.subunr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.subun(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.subuN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.subrn(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.subRN(i32, i32, i32)
-define i32 @test.cv.alu.subrn.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.subrn.case.a:
+define i32 @test.cv.alu.subRN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subRN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.subrn a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.subrn(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.subRN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.subrn.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.subrn.case.b:
+define i32 @test.cv.alu.subRN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subRN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.subrnr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.subrn(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.subRN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
-declare i32 @llvm.riscv.cv.alu.suburn(i32, i32, i32)
+declare i32 @llvm.riscv.cv.alu.subuRN(i32, i32, i32)
-define i32 @test.cv.alu.suburn.case.a(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.suburn.case.a:
+define i32 @test.cv.alu.subuRN.case.a(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subuRN.case.a:
; CHECK: # %bb.0:
; CHECK-NEXT: cv.suburn a0, a0, a1, 15
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.suburn(i32 %a, i32 %b, i32 15)
+ %1 = call i32 @llvm.riscv.cv.alu.subuRN(i32 %a, i32 %b, i32 15)
ret i32 %1
}
-define i32 @test.cv.alu.suburn.case.b(i32 %a, i32 %b) {
-; CHECK-LABEL: test.cv.alu.suburn.case.b:
+define i32 @test.cv.alu.subuRN.case.b(i32 %a, i32 %b) {
+; CHECK-LABEL: test.cv.alu.subuRN.case.b:
; CHECK: # %bb.0:
; CHECK-NEXT: li a2, 32
; CHECK-NEXT: cv.suburnr a0, a1, a2
; CHECK-NEXT: ret
- %1 = call i32 @llvm.riscv.cv.alu.suburn(i32 %a, i32 %b, i32 32)
+ %1 = call i32 @llvm.riscv.cv.alu.subuRN(i32 %a, i32 %b, i32 32)
ret i32 %1
}
More information about the llvm-commits
mailing list