diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -2633,6 +2633,18 @@ let Name = "vset_v", Log2LMUL = [0, 1, 2], MaskedPolicyScheme = NonePolicy, ManualCodegen = [{ { + if (isa(ResultType)) { // codegen for tuple type + llvm::Value *VTupleOperand = Ops[0]; + llvm::Value *IndexOperand = Ops[1]; + llvm::Value *VOperand = Ops[2]; + assert(isa(IndexOperand)); + + unsigned Index = cast(IndexOperand)->getZExtValue(); + unsigned MaxIndex = cast(VTupleOperand->getType())->getNumElements(); + Index = std::min(Index, MaxIndex); + + return Builder.CreateInsertValue(VTupleOperand, VOperand, {Index}); + } ID = Intrinsic::vector_insert; IntrinsicTypes = {ResultType, Ops[2]->getType()}; auto *ResVecTy = cast(ResultType); @@ -2653,5 +2665,11 @@ def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "csilxfd">; def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "Uv" # dst_lmul #"UvKzUv", "csil">; } + foreach nf = [2] in { + let Log2LMUL = [0] in { + defvar T = "(Tuple:" # nf # ")"; + def : RVVBuiltin; + } + } } } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4534,9 +4534,12 @@ ASTContext::BuiltinVectorTypeInfo VecInfo = Context.getBuiltinVectorTypeInfo(cast( TheCall->getArg(2)->getType().getCanonicalType().getTypePtr())); - unsigned MaxIndex = - (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors) / - (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors); + unsigned MaxIndex; + if (ResVecInfo.NumVectors != 1) // vset for tuple type + MaxIndex = ResVecInfo.NumVectors; + else // vset fo non-tuple type + MaxIndex = (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors) / + (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors); return SemaBuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1); } case RISCVVector::BI__builtin_rvv_sf_vc_i_se_u8mf8: diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vset_tuple.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vset_tuple.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vset_tuple.c @@ -0,0 +1,20 @@ +// 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 -target-feature +zfh \ +// RUN: -target-feature +experimental-zvfh -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local { , } @test_vset_v_i32m1x2_i32m1 +// CHECK-RV64-SAME: ( [[DEST_COERCE0:%.*]], [[DEST_COERCE1:%.*]], i64 noundef [[INDEX:%.*]], [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = insertvalue { , } poison, [[DEST_COERCE0]], 0 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = insertvalue { , } [[TMP0]], [[DEST_COERCE1]], 1 +// CHECK-RV64-NEXT: [[TMP2:%.*]] = insertvalue { , } [[TMP1]], [[VAL]], 0 +// CHECK-RV64-NEXT: ret { , } [[TMP2]] +// +vint32m1x2_t test_vset_v_i32m1x2_i32m1(vint32m1x2_t dest, size_t index, vint32m1_t val) { + return __riscv_vset_v_i32m1x2_i32m1(dest, 0, val); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vset-index-out-of-range.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vset-index-out-of-range.c --- a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vset-index-out-of-range.c +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/vset-index-out-of-range.c @@ -339,3 +339,8 @@ // expected-error@+1 {{argument value 2 is outside the valid range [0, 1]}} return __riscv_vset_v_f16m4_f16m8(dest, 2, val); } + +vint32m1x2_t test_vset_v_i32m1x2_i32m1(vint32m1x2_t dest, size_t index, vint32m1_t val) { + // expected-error@+1 {{argument value 2 is outside the valid range [0, 1]}} + return __riscv_vset_v_i32m1x2_i32m1(dest, 2, val); +}