eopXD created this revision. eopXD added reviewers: craig.topper, rogfer01, frasercrmck, reames, kito-cheng, nikic. Herald added subscribers: luke, StephenFan, luismarques, apazos, sameer.abuasal, s.egerton, Jim, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, edward-jones, zzheng, jrtc27, niosHD, sabuasal, simoncook, johnrusso, rbar, asb. Herald added a project: All. eopXD requested review of this revision. Herald added subscribers: cfe-commits, pcwang-thead, MaskRay. Herald added a project: clang.
For the cover letter of this patch-set, please checkout D146872 <https://reviews.llvm.org/D146872>. Depends on D147731 <https://reviews.llvm.org/D147731>. This is the 4th patch of the patch-set. This patch is a proof-of-concept and will be extended to full coverage in the future. Currently, the old non-tuple unit-stride segment store is not removed, and only signed integer unit-strided segment store of NF=2, EEW=32 is defined here. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D147774 Files: clang/include/clang/Basic/riscv_vector.td clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e32_tuple.c
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e32_tuple.c =================================================================== --- /dev/null +++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/vsseg2e32_tuple.c @@ -0,0 +1,31 @@ +// 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 <riscv_vector.h> + +// CHECK-RV64-LABEL: define dso_local void @test_vsseg2e32_v_tuple_i32m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], <vscale x 2 x i32> [[V_TUPLE_COERCE0:%.*]], <vscale x 2 x i32> [[V_TUPLE_COERCE1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = insertvalue { <vscale x 2 x i32>, <vscale x 2 x i32> } undef, <vscale x 2 x i32> [[V_TUPLE_COERCE0]], 0 +// CHECK-RV64-NEXT: [[TMP1:%.*]] = insertvalue { <vscale x 2 x i32>, <vscale x 2 x i32> } [[TMP0]], <vscale x 2 x i32> [[V_TUPLE_COERCE1]], 1 +// CHECK-RV64-NEXT: [[TMP2:%.*]] = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32> } [[TMP1]], 0 +// CHECK-RV64-NEXT: [[TMP3:%.*]] = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32> } [[TMP1]], 1 +// CHECK-RV64-NEXT: call void @llvm.riscv.vsseg2.nxv2i32.i64(<vscale x 2 x i32> [[TMP2]], <vscale x 2 x i32> [[TMP3]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_vsseg2e32_v_tuple_i32m1(int32_t *base, vint32m1x2_t v_tuple, size_t vl) { + return __riscv_vsseg2e32_v_tuple_i32m1(base, v_tuple, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_vsseg2e32_v_i32m1_m +// CHECK-RV64-SAME: (<vscale x 2 x i1> [[MASK:%.*]], ptr noundef [[BASE:%.*]], <vscale x 2 x i32> [[V0:%.*]], <vscale x 2 x i32> [[V1:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.vsseg2.mask.nxv2i32.i64(<vscale x 2 x i32> [[V0]], <vscale x 2 x i32> [[V1]], ptr [[BASE]], <vscale x 2 x i1> [[MASK]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_vsseg2e32_v_i32m1_m(vbool32_t mask, int32_t *base, vint32m1_t v0, vint32m1_t v1, size_t vl) { + return __riscv_vsseg2e32_v_i32m1_m(mask, base, v0, v1, vl); +} Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -19602,6 +19602,14 @@ } for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { + // Handle aggregate argument, namely RVV tuple types in segment load/store + if (hasAggregateEvaluationKind(E->getArg(i)->getType())) { + LValue L = EmitAggExprToLValue(E->getArg(i)); + llvm::Value *AggValue = Builder.CreateLoad(L.getAddress(*this)); + Ops.push_back(AggValue); + continue; + } + // If this is a normal argument, just emit it as a scalar. if ((ICEArguments & (1 << i)) == 0) { Ops.push_back(EmitScalarExpr(E->getArg(i))); Index: clang/include/clang/Basic/riscv_vector.td =================================================================== --- clang/include/clang/Basic/riscv_vector.td +++ clang/include/clang/Basic/riscv_vector.td @@ -1779,11 +1779,57 @@ } } } -// TODO: Extend for policy + +multiclass RVVUnitStridedSegStoreTuple<string op> { + foreach type = ["i"] in { + defvar eew = !cond(!eq(type, "i") : "32"); + foreach nf = [2] in { + let Name = op # nf # "e" # eew # "_v_tuple", + OverloadedName = op # nf # "e" # eew # "_tuple", + IRName = op # nf, + MaskedIRName = op # nf # "_mask", + NF = nf, + HasMaskedOffOperand = false, + ManualCodegen = [{ + { + // Masked + // Builtin: (mask, ptr, v_tuple, vl) + // Intrinsic: (val0, val1, ..., ptr, mask, vl) + // Unmasked + // Builtin: (ptr, v_tuple, vl) + // Intrinsic: (val0, val1, ..., ptr, vl) + llvm::Value *MaskOperand = IsMasked ? Ops[0] : nullptr; + llvm::Value *PtrOperand = IsMasked ? Ops[1] : Ops[0]; + llvm::Value *VTupleOperand = IsMasked ? Ops[2] : Ops[1]; + llvm::Value *VLOperand = IsMasked ? Ops[3] : Ops[2]; + + SmallVector<llvm::Value*, 12> Operands; + for (unsigned I = 0; I < NF; ++I) { + llvm::Value *V = Builder.CreateExtractValue(VTupleOperand, {I}); + Operands.push_back(V); + } + Operands.push_back(PtrOperand); + if (MaskOperand) + Operands.push_back(MaskOperand); + Operands.push_back(VLOperand); + + IntrinsicTypes = {Operands[0]->getType(), Operands.back()->getType()}; + llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes); + return Builder.CreateCall(F, Operands, ""); + } + }] in { + defvar T = "(Tuple:" # nf # ")"; + def : RVVBuiltin<"v", "0Pe" # T # "v", type>; + } + } + } +} +// TODO: Extend for policy for load let UnMaskedPolicyScheme = NonePolicy, MaskedPolicyScheme = NonePolicy, IsTuple = true in { defm : RVVUnitStridedSegLoadTuple<"vlseg">; +defm : RVVUnitStridedSegStoreTuple<"vsseg">; } let UnMaskedPolicyScheme = NonePolicy,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits