llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-risc-v Author: Jianjian Guan (jacquesguan) <details> <summary>Changes</summary> Initial support for rvv builtins codegen. Leave all builtins that need manual codegen as NYI now. --- Patch is 175.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/199889.diff 7 Files Affected: - (modified) clang/include/clang/Basic/CMakeLists.txt (+3) - (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp (+36-6) - (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+45) - (added) clang/test/CIR/CodeGenBuiltins/RISCV/rvv/non-policy/non-overloaded/vadd.c (+2299) - (modified) clang/utils/TableGen/RISCVVEmitter.cpp (+112) - (modified) clang/utils/TableGen/TableGen.cpp (+7) - (modified) clang/utils/TableGen/TableGenBackends.h (+2) ``````````diff diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 20172622ca424..b7e8b0d185667 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -226,6 +226,9 @@ clang_tablegen(riscv_vector_builtins.inc -gen-riscv-vector-builtins clang_tablegen(riscv_vector_builtin_cg.inc -gen-riscv-vector-builtin-codegen SOURCE riscv_vector.td TARGET ClangRISCVVectorBuiltinCG) +clang_tablegen(riscv_vector_builtin_cir_cg.inc -gen-riscv-vector-builtin-cir-codegen + SOURCE riscv_vector.td + TARGET ClangRISCVVectorBuiltinCIRCG) clang_tablegen(riscv_vector_builtin_sema.inc -gen-riscv-vector-builtin-sema SOURCE riscv_vector.td TARGET ClangRISCVVectorBuiltinSema) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp index ec262922be942..10119a5a6dcbc 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinRISCV.cpp @@ -30,6 +30,7 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID, const CallExpr *e) { StringRef intrinsicName; mlir::Type returnType = convertType(e->getType()); + mlir::Location loc = getLoc(e->getSourceRange()); llvm::SmallVector<mlir::Value> ops; // `iceArguments` is a bitmap indicating whether the argument at the i-th bit @@ -37,9 +38,33 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID, const CallExpr *e) { unsigned iceArguments = 0; ASTContext::GetBuiltinTypeError error; getContext().GetBuiltinType(builtinID, error, &iceArguments); - assert(error == ASTContext::GE_None && "Should not codegen an error"); - for (auto [idx, arg] : llvm::enumerate(e->arguments())) + + // RVV vector builtins use a special type overload mechanism (no type string). + if (error == ASTContext::GE_Missing_type) { + // Vector intrinsics don't have a type string. + assert(builtinID >= clang::RISCV::FirstRVVBuiltin && + builtinID <= clang::RISCV::LastRVVBuiltin); + iceArguments = 0; + if (builtinID == RISCVVector::BI__builtin_rvv_vget_v || + builtinID == RISCVVector::BI__builtin_rvv_vset_v) + iceArguments = 1 << 1; + } else { + assert(error == ASTContext::GE_None && "Unexpected error"); + } + + for (auto [idx, arg] : llvm::enumerate(e->arguments())) { + // Handle aggregate argument, namely RVV tuple types in segment load/store + if (hasAggregateEvaluationKind(arg->getType())) { + LValue lv = emitAggExprToLValue(arg); + ops.push_back(builder.createLoad(loc, lv.getAddress())); + continue; + } ops.push_back(emitScalarOrConstFoldImmArg(iceArguments, idx, arg)); + } + + // TODO: Handle ManualCodegen. + bool hasCirManualCodegen = false; + int PolicyAttrs = 0; switch (builtinID) { default: @@ -132,7 +157,6 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID, const CallExpr *e) { // Zbb case RISCV::BI__builtin_riscv_clz_32: case RISCV::BI__builtin_riscv_clz_64: { - mlir::Location loc = getLoc(e->getSourceRange()); auto op = cir::BitClzOp::create(builder, loc, ops[0], /*poison_zero=*/false); mlir::Value result = op.getResult(); @@ -142,7 +166,6 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID, const CallExpr *e) { } case RISCV::BI__builtin_riscv_ctz_32: case RISCV::BI__builtin_riscv_ctz_64: { - mlir::Location loc = getLoc(e->getSourceRange()); auto op = cir::BitCtzOp::create(builder, loc, ops[0], /*poison_zero=*/false); mlir::Value result = op.getResult(); @@ -202,9 +225,16 @@ CIRGenFunction::emitRISCVBuiltinExpr(unsigned builtinID, const CallExpr *e) { return mlir::Value{}; } - // TODO: Handle vector builtins in tablegen. +#include "clang/Basic/riscv_vector_builtin_cir_cg.inc" + // TODO: Handle Andes and SiFive vecotor builtin. + } + + if (hasCirManualCodegen) { + cgm.errorNYI(e->getSourceRange(), + std::string("unimplemented RISC-V vector builtin call: ") + + getContext().BuiltinInfo.getName(builtinID)); + return mlir::Value{}; } - mlir::Location loc = getLoc(e->getSourceRange()); return builder.emitIntrinsicCallOp(loc, intrinsicName, returnType, ops); } diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 85b7e854abb7f..1a39bb86d874f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -405,6 +405,51 @@ mlir::Type CIRGenTypes::convertType(QualType type) { /*is_scalable=*/true); break; +// RISC-V vector types. +#define RVV_VECTOR_TYPE_INT(Name, Id, SingletonId, NumEls, ElBits, NF, \ + IsSigned) \ + case BuiltinType::Id: { \ + auto eltTy = \ + IsSigned ? builder.getSIntNTy(ElBits) : builder.getUIntNTy(ElBits); \ + resultType = cir::VectorType::get(eltTy, NumEls, /*is_scalable=*/true); \ + break; \ + } +#define RVV_VECTOR_TYPE_FLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \ + case BuiltinType::Id: { \ + mlir::Type eltTy; \ + if (ElBits == 16) \ + eltTy = builder.getFp16Ty(); \ + else if (ElBits == 32) \ + eltTy = builder.getSingleTy(); \ + else if (ElBits == 64) \ + eltTy = builder.getDoubleTy(); \ + else \ + llvm_unreachable("unsupported RVV FP element width"); \ + resultType = cir::VectorType::get(eltTy, NumEls, /*is_scalable=*/true); \ + break; \ + } +#define RVV_VECTOR_TYPE_BFLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \ + case BuiltinType::Id: { \ + resultType = cir::VectorType::get(builder.getBfloat6Ty(), NumEls, \ + /*is_scalable=*/true); \ + break; \ + } +#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \ + case BuiltinType::Id: { \ + resultType = cir::VectorType::get(builder.getUIntNTy(1), NumEls, \ + /*is_scalable=*/true); \ + break; \ + } +// RVV_VECTOR_TYPE_OFP8 maps to RVV_VECTOR_TYPE_INT (unsigned) +#define RVV_VECTOR_TYPE_OFP8(Name, Id, SingletonId, NumEls, E5m2) \ + case BuiltinType::Id: { \ + resultType = cir::VectorType::get(builder.getUIntNTy(8), NumEls, \ + /*is_scalable=*/true); \ + break; \ + } + +#include "clang/Basic/RISCVVTypes.def" + // Unsigned integral types. case BuiltinType::Char8: case BuiltinType::Char16: diff --git a/clang/test/CIR/CodeGenBuiltins/RISCV/rvv/non-policy/non-overloaded/vadd.c b/clang/test/CIR/CodeGenBuiltins/RISCV/rvv/non-policy/non-overloaded/vadd.c new file mode 100644 index 0000000000000..9a7f2938fbbe1 --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/RISCV/rvv/non-policy/non-overloaded/vadd.c @@ -0,0 +1,2299 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -fclangir -emit-cir %s -o - | FileCheck %s --check-prefix=CIR +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -fclangir -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s --check-prefix=CHECK-RV64 +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include <riscv_vector.h> + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vv_i8mf8( +// CIR-SAME: -> !cir.vector<[1] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[1] x !s8i>, !cir.vector<[1] x !s8i>, !cir.vector<[1] x !s8i>, !u64i) -> !cir.vector<[1] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 1 x i8> @test_vadd_vv_i8mf8 +// CHECK-RV64-SAME: (<vscale x 1 x i8> [[OP1:%.*]], <vscale x 1 x i8> [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 1 x i8> @llvm.riscv.vadd.nxv1i8.nxv1i8.i64(<vscale x 1 x i8> poison, <vscale x 1 x i8> [[OP1]], <vscale x 1 x i8> [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 1 x i8> [[TMP0]] +// +vint8mf8_t test_vadd_vv_i8mf8(vint8mf8_t op1, vint8mf8_t op2, size_t vl) { + return __riscv_vadd_vv_i8mf8(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vx_i8mf8( +// CIR-SAME: -> !cir.vector<[1] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[1] x !s8i>, !cir.vector<[1] x !s8i>, !s8i, !u64i) -> !cir.vector<[1] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 1 x i8> @test_vadd_vx_i8mf8 +// CHECK-RV64-SAME: (<vscale x 1 x i8> [[OP1:%.*]], i8 noundef{{( signext)?}} [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 1 x i8> @llvm.riscv.vadd.nxv1i8.i8.i64(<vscale x 1 x i8> poison, <vscale x 1 x i8> [[OP1]], i8 [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 1 x i8> [[TMP0]] +// +vint8mf8_t test_vadd_vx_i8mf8(vint8mf8_t op1, int8_t op2, size_t vl) { + return __riscv_vadd_vx_i8mf8(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vv_i8mf4( +// CIR-SAME: -> !cir.vector<[2] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[2] x !s8i>, !cir.vector<[2] x !s8i>, !cir.vector<[2] x !s8i>, !u64i) -> !cir.vector<[2] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 2 x i8> @test_vadd_vv_i8mf4 +// CHECK-RV64-SAME: (<vscale x 2 x i8> [[OP1:%.*]], <vscale x 2 x i8> [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 2 x i8> @llvm.riscv.vadd.nxv2i8.nxv2i8.i64(<vscale x 2 x i8> poison, <vscale x 2 x i8> [[OP1]], <vscale x 2 x i8> [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 2 x i8> [[TMP0]] +// +vint8mf4_t test_vadd_vv_i8mf4(vint8mf4_t op1, vint8mf4_t op2, size_t vl) { + return __riscv_vadd_vv_i8mf4(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vx_i8mf4( +// CIR-SAME: -> !cir.vector<[2] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[2] x !s8i>, !cir.vector<[2] x !s8i>, !s8i, !u64i) -> !cir.vector<[2] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 2 x i8> @test_vadd_vx_i8mf4 +// CHECK-RV64-SAME: (<vscale x 2 x i8> [[OP1:%.*]], i8 noundef{{( signext)?}} [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 2 x i8> @llvm.riscv.vadd.nxv2i8.i8.i64(<vscale x 2 x i8> poison, <vscale x 2 x i8> [[OP1]], i8 [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 2 x i8> [[TMP0]] +// +vint8mf4_t test_vadd_vx_i8mf4(vint8mf4_t op1, int8_t op2, size_t vl) { + return __riscv_vadd_vx_i8mf4(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vv_i8mf2( +// CIR-SAME: -> !cir.vector<[4] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[4] x !s8i>, !cir.vector<[4] x !s8i>, !cir.vector<[4] x !s8i>, !u64i) -> !cir.vector<[4] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 4 x i8> @test_vadd_vv_i8mf2 +// CHECK-RV64-SAME: (<vscale x 4 x i8> [[OP1:%.*]], <vscale x 4 x i8> [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 4 x i8> @llvm.riscv.vadd.nxv4i8.nxv4i8.i64(<vscale x 4 x i8> poison, <vscale x 4 x i8> [[OP1]], <vscale x 4 x i8> [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 4 x i8> [[TMP0]] +// +vint8mf2_t test_vadd_vv_i8mf2(vint8mf2_t op1, vint8mf2_t op2, size_t vl) { + return __riscv_vadd_vv_i8mf2(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vx_i8mf2( +// CIR-SAME: -> !cir.vector<[4] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[4] x !s8i>, !cir.vector<[4] x !s8i>, !s8i, !u64i) -> !cir.vector<[4] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 4 x i8> @test_vadd_vx_i8mf2 +// CHECK-RV64-SAME: (<vscale x 4 x i8> [[OP1:%.*]], i8 noundef{{( signext)?}} [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 4 x i8> @llvm.riscv.vadd.nxv4i8.i8.i64(<vscale x 4 x i8> poison, <vscale x 4 x i8> [[OP1]], i8 [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 4 x i8> [[TMP0]] +// +vint8mf2_t test_vadd_vx_i8mf2(vint8mf2_t op1, int8_t op2, size_t vl) { + return __riscv_vadd_vx_i8mf2(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vv_i8m1( +// CIR-SAME: -> !cir.vector<[8] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[8] x !s8i>, !cir.vector<[8] x !s8i>, !cir.vector<[8] x !s8i>, !u64i) -> !cir.vector<[8] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 8 x i8> @test_vadd_vv_i8m1 +// CHECK-RV64-SAME: (<vscale x 8 x i8> [[OP1:%.*]], <vscale x 8 x i8> [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.nxv8i8.nxv8i8.i64(<vscale x 8 x i8> poison, <vscale x 8 x i8> [[OP1]], <vscale x 8 x i8> [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 8 x i8> [[TMP0]] +// +vint8m1_t test_vadd_vv_i8m1(vint8m1_t op1, vint8m1_t op2, size_t vl) { + return __riscv_vadd_vv_i8m1(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vx_i8m1( +// CIR-SAME: -> !cir.vector<[8] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[8] x !s8i>, !cir.vector<[8] x !s8i>, !s8i, !u64i) -> !cir.vector<[8] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 8 x i8> @test_vadd_vx_i8m1 +// CHECK-RV64-SAME: (<vscale x 8 x i8> [[OP1:%.*]], i8 noundef{{( signext)?}} [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.nxv8i8.i8.i64(<vscale x 8 x i8> poison, <vscale x 8 x i8> [[OP1]], i8 [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 8 x i8> [[TMP0]] +// +vint8m1_t test_vadd_vx_i8m1(vint8m1_t op1, int8_t op2, size_t vl) { + return __riscv_vadd_vx_i8m1(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vv_i8m2( +// CIR-SAME: -> !cir.vector<[16] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[16] x !s8i>, !cir.vector<[16] x !s8i>, !cir.vector<[16] x !s8i>, !u64i) -> !cir.vector<[16] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 16 x i8> @test_vadd_vv_i8m2 +// CHECK-RV64-SAME: (<vscale x 16 x i8> [[OP1:%.*]], <vscale x 16 x i8> [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 16 x i8> @llvm.riscv.vadd.nxv16i8.nxv16i8.i64(<vscale x 16 x i8> poison, <vscale x 16 x i8> [[OP1]], <vscale x 16 x i8> [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 16 x i8> [[TMP0]] +// +vint8m2_t test_vadd_vv_i8m2(vint8m2_t op1, vint8m2_t op2, size_t vl) { + return __riscv_vadd_vv_i8m2(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vx_i8m2( +// CIR-SAME: -> !cir.vector<[16] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[16] x !s8i>, !cir.vector<[16] x !s8i>, !s8i, !u64i) -> !cir.vector<[16] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 16 x i8> @test_vadd_vx_i8m2 +// CHECK-RV64-SAME: (<vscale x 16 x i8> [[OP1:%.*]], i8 noundef{{( signext)?}} [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 16 x i8> @llvm.riscv.vadd.nxv16i8.i8.i64(<vscale x 16 x i8> poison, <vscale x 16 x i8> [[OP1]], i8 [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 16 x i8> [[TMP0]] +// +vint8m2_t test_vadd_vx_i8m2(vint8m2_t op1, int8_t op2, size_t vl) { + return __riscv_vadd_vx_i8m2(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vv_i8m4( +// CIR-SAME: -> !cir.vector<[32] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[32] x !s8i>, !cir.vector<[32] x !s8i>, !cir.vector<[32] x !s8i>, !u64i) -> !cir.vector<[32] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 32 x i8> @test_vadd_vv_i8m4 +// CHECK-RV64-SAME: (<vscale x 32 x i8> [[OP1:%.*]], <vscale x 32 x i8> [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 32 x i8> @llvm.riscv.vadd.nxv32i8.nxv32i8.i64(<vscale x 32 x i8> poison, <vscale x 32 x i8> [[OP1]], <vscale x 32 x i8> [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 32 x i8> [[TMP0]] +// +vint8m4_t test_vadd_vv_i8m4(vint8m4_t op1, vint8m4_t op2, size_t vl) { + return __riscv_vadd_vv_i8m4(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vx_i8m4( +// CIR-SAME: -> !cir.vector<[32] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[32] x !s8i>, !cir.vector<[32] x !s8i>, !s8i, !u64i) -> !cir.vector<[32] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 32 x i8> @test_vadd_vx_i8m4 +// CHECK-RV64-SAME: (<vscale x 32 x i8> [[OP1:%.*]], i8 noundef{{( signext)?}} [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 32 x i8> @llvm.riscv.vadd.nxv32i8.i8.i64(<vscale x 32 x i8> poison, <vscale x 32 x i8> [[OP1]], i8 [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 32 x i8> [[TMP0]] +// +vint8m4_t test_vadd_vx_i8m4(vint8m4_t op1, int8_t op2, size_t vl) { + return __riscv_vadd_vx_i8m4(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vv_i8m8( +// CIR-SAME: -> !cir.vector<[64] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[64] x !s8i>, !cir.vector<[64] x !s8i>, !cir.vector<[64] x !s8i>, !u64i) -> !cir.vector<[64] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 64 x i8> @test_vadd_vv_i8m8 +// CHECK-RV64-SAME: (<vscale x 64 x i8> [[OP1:%.*]], <vscale x 64 x i8> [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.nxv64i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> [[OP1]], <vscale x 64 x i8> [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 64 x i8> [[TMP0]] +// +vint8m8_t test_vadd_vv_i8m8(vint8m8_t op1, vint8m8_t op2, size_t vl) { + return __riscv_vadd_vv_i8m8(op1, op2, vl); +} + +// CIR-LABEL: cir.func{{.*}} @test_vadd_vx_i8m8( +// CIR-SAME: -> !cir.vector<[64] +// CIR: {{%.*}} = cir.call_llvm_intrinsic "riscv.vadd" {{%.*}}, {{%.*}}, {{%.*}}, {{%.*}} : (!cir.vector<[64] x !s8i>, !cir.vector<[64] x !s8i>, !s8i, !u64i) -> !cir.vector<[64] +// +// CHECK-RV64-LABEL: define dso_local <vscale x 64 x i8> @test_vadd_vx_i8m8 +// CHECK-RV64-SAME: (<vscale x 64 x i8> [[OP1:%.*]], i8 noundef{{( signext)?}} [[OP2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64: [[TMP0:%.*]] = call <vscale x 64 x i8> @llvm.riscv.vadd.nxv64i8.i8.i64(<vscale x 64 x i8> poison, <vscale x 64 x i8> [[OP1]], i8 [[OP2]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret <vscale x 64 x i8> [[TMP0]] +// +vint8m8_t test_vadd_vx_i8m8(vint8m8_t op1, int8_t op2, size_t vl) { + return __riscv_vadd_vx_i8m8(op1, op... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/199889 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
