diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index 3b070109b2e3d..4d48c38adb578 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -2569,6 +2569,11 @@ let HasMasked = false, HasVL = false, IRName = "" in { let Name = "vset_v", Log2LMUL = [0, 1, 2], MaskedPolicyScheme = NonePolicy, ManualCodegen = [{ { + if (isa(ResultType)) // For tuple type + // Insert value (operand 2) into index (operand 1) of vtuple (operand 0) + return Builder.CreateInsertValue( + Ops[0], Ops[2], + {(unsigned)cast(Ops[1])->getZExtValue()}); auto *ResVecTy = cast(ResultType); auto *VecTy = cast(Ops[2]->getType()); // Mask to only valid indices. @@ -2586,5 +2591,11 @@ let HasMasked = false, HasVL = false, IRName = "" in { 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 index 7aceade260ad3..6c2cbc60a81d2 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -4537,9 +4537,12 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, 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 index 0000000000000..70bd7acfdd1e0 --- /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:%.*]], [[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, 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 index fad13d9ba23c8..66456e70272e4 100644 --- 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 @@ vfloat16m8_t test_vset_v_f16m4_f16m8(vfloat16m8_t dest, vfloat16m4_t val) { // 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, 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); +}