Author: Sander de Smalen Date: 2020-04-24T11:35:59+01:00 New Revision: 823e2a670a9da8e5cd8beed108355a168ca1a23b
URL: https://github.com/llvm/llvm-project/commit/823e2a670a9da8e5cd8beed108355a168ca1a23b DIFF: https://github.com/llvm/llvm-project/commit/823e2a670a9da8e5cd8beed108355a168ca1a23b.diff LOG: [SveEmitter] Add builtins for contiguous prefetches This patch also adds the enum `sv_prfop` for the prefetch operation specifier and checks to ensure the passed enum values are valid. Reviewers: SjoerdMeijer, efriedma, ctetreau Reviewed By: efriedma Tags: #clang Differential Revision: https://reviews.llvm.org/D78674 Added: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c Modified: clang/include/clang/Basic/TargetBuiltins.h clang/include/clang/Basic/arm_sve.td clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CodeGenFunction.h clang/lib/Sema/SemaChecking.cpp clang/utils/TableGen/SveEmitter.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 5ef1a58fbb0f..1a9cb4cda1a4 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -238,6 +238,7 @@ namespace clang { bool isOverloadDefault() const { return !(Flags & OverloadKindMask); } bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; } bool isOverloadCvt() const { return Flags & IsOverloadCvt; } + bool isPrefetch() const { return Flags & IsPrefetch; } uint64_t getBits() const { return Flags; } bool isFlagSet(uint64_t Flag) const { return Flags & Flag; } diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index 4b69cdcb6468..5709dc8b8781 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -58,6 +58,7 @@ // ------------------- // prototype: return (arg, arg, ...) // +// v: void // x: vector of signed integers // u: vector of unsigned integers // d: default @@ -82,6 +83,7 @@ // M: svfloat32_t // N: svfloat64_t +// J: Prefetch type (sv_prfop) // A: pointer to int8_t // B: pointer to int16_t // C: pointer to int32_t @@ -176,6 +178,7 @@ def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type) def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types. def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type. def IsByteIndexed : FlagType<0x01000000>; +def IsPrefetch : FlagType<0x08000000>; // Contiguous prefetches. // These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h class ImmCheckType<int val> { @@ -193,6 +196,7 @@ def ImmCheckLaneIndexCompRotate : ImmCheckType<8>; // 0..(128/(2*sizeinbits(elt def ImmCheckLaneIndexDot : ImmCheckType<9>; // 0..(128/(4*sizeinbits(elt)) - 1) def ImmCheckComplexRot90_270 : ImmCheckType<10>; // [90,270] def ImmCheckComplexRotAll90 : ImmCheckType<11>; // [0, 90, 180,270] +def ImmCheck0_13 : ImmCheckType<12>; // 0..13 class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> { int Arg = arg; @@ -543,6 +547,21 @@ def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEl // Store one vector, with no truncation, non-temporal (scalar base, VL displacement) def SVSTNT1_VNUM : MInst<"svstnt1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; +//////////////////////////////////////////////////////////////////////////////// +// Prefetches + +// Prefetch (Scalar base) +def SVPRFB : MInst<"svprfb", "vPcJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">; +def SVPRFH : MInst<"svprfh", "vPcJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">; +def SVPRFW : MInst<"svprfw", "vPcJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">; +def SVPRFD : MInst<"svprfd", "vPcJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">; + +// Prefetch (Scalar base, VL displacement) +def SVPRFB_VNUM : MInst<"svprfb_vnum", "vPclJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">; +def SVPRFH_VNUM : MInst<"svprfh_vnum", "vPclJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">; +def SVPRFW_VNUM : MInst<"svprfw_vnum", "vPclJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">; +def SVPRFD_VNUM : MInst<"svprfd_vnum", "vPclJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">; + //////////////////////////////////////////////////////////////////////////////// // Integer arithmetic diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index fb2bbd574306..468bc4eab59d 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -7568,6 +7568,13 @@ llvm::VectorType *CodeGenFunction::getSVEType(const SVETypeFlags &TypeFlags) { } } +constexpr unsigned SVEBitsPerBlock = 128; + +static llvm::VectorType* getSVEVectorForElementType(llvm::Type *EltTy) { + unsigned NumElts = SVEBitsPerBlock / EltTy->getScalarSizeInBits(); + return llvm::VectorType::get(EltTy, { NumElts, true }); +} + // Reinterpret the input predicate so that it can be used to correctly isolate // the elements of the specified datatype. Value *CodeGenFunction::EmitSVEPredicateCast(Value *Pred, @@ -7707,6 +7714,30 @@ Value *CodeGenFunction::EmitSVEScatterStore(SVETypeFlags TypeFlags, return Builder.CreateCall(F, Ops); } +Value *CodeGenFunction::EmitSVEPrefetchLoad(SVETypeFlags TypeFlags, + SmallVectorImpl<Value *> &Ops, + unsigned BuiltinID) { + auto *MemEltTy = SVEBuiltinMemEltTy(TypeFlags); + auto *VectorTy = getSVEVectorForElementType(MemEltTy); + auto *MemoryTy = llvm::VectorType::get(MemEltTy, VectorTy->getElementCount()); + + Value *Predicate = EmitSVEPredicateCast(Ops[0], MemoryTy); + Value *BasePtr = Ops[1]; + + // Implement the index operand if not omitted. + if (Ops.size() > 3) { + BasePtr = Builder.CreateBitCast(BasePtr, MemoryTy->getPointerTo()); + BasePtr = Builder.CreateGEP(MemoryTy, BasePtr, Ops[2]); + } + + // Prefetch intriniscs always expect an i8* + BasePtr = Builder.CreateBitCast(BasePtr, llvm::PointerType::getUnqual(Int8Ty)); + Value *PrfOp = Ops.back(); + + Function *F = CGM.getIntrinsic(BuiltinID, Predicate->getType()); + return Builder.CreateCall(F, {Predicate, BasePtr, PrfOp}); +} + Value *CodeGenFunction::EmitSVEMaskedLoad(const CallExpr *E, llvm::Type *ReturnTy, SmallVectorImpl<Value *> &Ops, @@ -7759,13 +7790,6 @@ Value *CodeGenFunction::EmitSVEMaskedStore(const CallExpr *E, return Builder.CreateCall(F, {Val, Predicate, BasePtr}); } -constexpr unsigned SVEBitsPerBlock = 128; - -static llvm::VectorType* getSVEVectorForElementType(llvm::Type *EltTy) { - unsigned NumElts = SVEBitsPerBlock / EltTy->getScalarSizeInBits(); - return llvm::VectorType::get(EltTy, { NumElts, true }); -} - // Limit the usage of scalable llvm IR generated by the ACLE by using the // sve dup.x intrinsic instead of IRBuilder::CreateVectorSplat. Value *CodeGenFunction::EmitSVEDupX(Value* Scalar) { @@ -7847,6 +7871,8 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, return EmitSVEGatherLoad(TypeFlags, Ops, Builtin->LLVMIntrinsic); else if (TypeFlags.isScatterStore()) return EmitSVEScatterStore(TypeFlags, Ops, Builtin->LLVMIntrinsic); + else if (TypeFlags.isPrefetch()) + return EmitSVEPrefetchLoad(TypeFlags, Ops, Builtin->LLVMIntrinsic); else if (Builtin->LLVMIntrinsic != 0) { if (TypeFlags.getMergeType() == SVETypeFlags::MergeZeroExp) InsertExplicitZeroOperand(Builder, Ty, Ops); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index a16ad1d178ce..53809b693266 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3927,6 +3927,9 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *EmitSVEMaskedStore(const CallExpr *, SmallVectorImpl<llvm::Value *> &Ops, unsigned BuiltinID); + llvm::Value *EmitSVEPrefetchLoad(SVETypeFlags TypeFlags, + SmallVectorImpl<llvm::Value *> &Ops, + unsigned BuiltinID); llvm::Value *EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 126f155b6ad0..a88db3324ef3 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2042,6 +2042,10 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 31)) HasError = true; break; + case SVETypeFlags::ImmCheck0_13: + if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 13)) + HasError = true; + break; case SVETypeFlags::ImmCheck1_16: if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, 16)) HasError = true; diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c new file mode 100644 index 000000000000..f29cb995230c --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfb.c @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svprfb(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 0) + return svprfb(pg, base, SV_PLDL1KEEP); +} + +void test_svprfb_1(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_1 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 1) + return svprfb(pg, base, SV_PLDL1STRM); +} + +void test_svprfb_2(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_2 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 2) + return svprfb(pg, base, SV_PLDL2KEEP); +} + +void test_svprfb_3(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_3 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 3) + return svprfb(pg, base, SV_PLDL2STRM); +} + +void test_svprfb_4(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_4 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 4) + return svprfb(pg, base, SV_PLDL3KEEP); +} + +void test_svprfb_5(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_5 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 5) + return svprfb(pg, base, SV_PLDL3STRM); +} + +void test_svprfb_6(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_6 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 8) + return svprfb(pg, base, SV_PSTL1KEEP); +} + +void test_svprfb_7(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_7 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 9) + return svprfb(pg, base, SV_PSTL1STRM); +} + +void test_svprfb_8(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_8 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 10) + return svprfb(pg, base, SV_PSTL2KEEP); +} + +void test_svprfb_9(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_9 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 11) + return svprfb(pg, base, SV_PSTL2STRM); +} + +void test_svprfb_10(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_10 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 12) + return svprfb(pg, base, SV_PSTL3KEEP); +} + +void test_svprfb_11(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfb_11 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %base, i32 13) + return svprfb(pg, base, SV_PSTL3STRM); +} + +void test_svprfb_vnum(svbool_t pg, const void *base, int64_t vnum) +{ + // CHECK-LABEL: test_svprfb_vnum + // CHECK: %[[BASE:.*]] = bitcast i8* %base to <vscale x 16 x i8>* + // CHECK: %[[GEP:.*]] = getelementptr <vscale x 16 x i8>, <vscale x 16 x i8>* %[[BASE]], i64 %vnum, i64 0 + // CHECK: @llvm.aarch64.sve.prf.nxv16i1(<vscale x 16 x i1> %pg, i8* %[[GEP]], i32 0) + return svprfb_vnum(pg, base, vnum, SV_PLDL1KEEP); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c new file mode 100644 index 000000000000..59d3fbfb7e1b --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfd.c @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svprfd(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 0) + return svprfd(pg, base, SV_PLDL1KEEP); +} + +void test_svprfd_1(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_1 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 1) + return svprfd(pg, base, SV_PLDL1STRM); +} + +void test_svprfd_2(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_2 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 2) + return svprfd(pg, base, SV_PLDL2KEEP); +} + +void test_svprfd_3(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_3 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 3) + return svprfd(pg, base, SV_PLDL2STRM); +} + +void test_svprfd_4(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_4 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 4) + return svprfd(pg, base, SV_PLDL3KEEP); +} + +void test_svprfd_5(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_5 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 5) + return svprfd(pg, base, SV_PLDL3STRM); +} + +void test_svprfd_6(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_6 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 8) + return svprfd(pg, base, SV_PSTL1KEEP); +} + +void test_svprfd_7(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_7 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 9) + return svprfd(pg, base, SV_PSTL1STRM); +} + +void test_svprfd_8(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_8 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 10) + return svprfd(pg, base, SV_PSTL2KEEP); +} + +void test_svprfd_9(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_9 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 11) + return svprfd(pg, base, SV_PSTL2STRM); +} + +void test_svprfd_10(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_10 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 12) + return svprfd(pg, base, SV_PSTL3KEEP); +} + +void test_svprfd_11(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfd_11 + // CHECK: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %base, i32 13) + return svprfd(pg, base, SV_PSTL3STRM); +} + +void test_svprfd_vnum(svbool_t pg, const void *base, int64_t vnum) +{ + // CHECK-LABEL: test_svprfd_vnum + // CHECK-DAG: %[[PG:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %pg) + // CHECK-DAG: %[[BASE:.*]] = bitcast i8* %base to <vscale x 2 x i64>* + // CHECK-DAG: %[[GEP:.*]] = getelementptr <vscale x 2 x i64>, <vscale x 2 x i64>* %[[BASE]], i64 %vnum + // CHECK-DAG: %[[I8_BASE:.*]] = bitcast <vscale x 2 x i64>* %[[GEP]] to i8* + // CHECK: @llvm.aarch64.sve.prf.nxv2i1(<vscale x 2 x i1> %[[PG]], i8* %[[I8_BASE]], i32 0) + return svprfd_vnum(pg, base, vnum, SV_PLDL1KEEP); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c new file mode 100644 index 000000000000..a6290f3f2f0c --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfh.c @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svprfh(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 0) + return svprfh(pg, base, SV_PLDL1KEEP); +} + +void test_svprfh_1(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_1 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 1) + return svprfh(pg, base, SV_PLDL1STRM); +} + +void test_svprfh_2(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_2 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 2) + return svprfh(pg, base, SV_PLDL2KEEP); +} + +void test_svprfh_3(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_3 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 3) + return svprfh(pg, base, SV_PLDL2STRM); +} + +void test_svprfh_4(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_4 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 4) + return svprfh(pg, base, SV_PLDL3KEEP); +} + +void test_svprfh_5(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_5 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 5) + return svprfh(pg, base, SV_PLDL3STRM); +} + +void test_svprfh_6(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_6 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 8) + return svprfh(pg, base, SV_PSTL1KEEP); +} + +void test_svprfh_7(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_7 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 9) + return svprfh(pg, base, SV_PSTL1STRM); +} + +void test_svprfh_8(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_8 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 10) + return svprfh(pg, base, SV_PSTL2KEEP); +} + +void test_svprfh_9(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_9 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 11) + return svprfh(pg, base, SV_PSTL2STRM); +} + +void test_svprfh_10(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_10 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 12) + return svprfh(pg, base, SV_PSTL3KEEP); +} + +void test_svprfh_11(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfh_11 + // CHECK: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %base, i32 13) + return svprfh(pg, base, SV_PSTL3STRM); +} + +void test_svprfh_vnum(svbool_t pg, const void *base, int64_t vnum) +{ + // CHECK-LABEL: test_svprfh_vnum + // CHECK-DAG: %[[PG:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %pg) + // CHECK-DAG: %[[BASE:.*]] = bitcast i8* %base to <vscale x 8 x i16>* + // CHECK-DAG: %[[GEP:.*]] = getelementptr <vscale x 8 x i16>, <vscale x 8 x i16>* %[[BASE]], i64 %vnum + // CHECK-DAG: %[[I8_BASE:.*]] = bitcast <vscale x 8 x i16>* %[[GEP]] to i8* + // CHECK: @llvm.aarch64.sve.prf.nxv8i1(<vscale x 8 x i1> %[[PG]], i8* %[[I8_BASE]], i32 0) + return svprfh_vnum(pg, base, vnum, SV_PLDL1KEEP); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c new file mode 100644 index 000000000000..e6b1b603e475 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_prfw.c @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s + +#include <arm_sve.h> + +#ifdef SVE_OVERLOADED_FORMS +// A simple used,unused... macro, long enough to represent any SVE builtin. +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4 +#endif + +void test_svprfw(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 0) + return svprfw(pg, base, SV_PLDL1KEEP); +} + +void test_svprfw_1(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_1 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 1) + return svprfw(pg, base, SV_PLDL1STRM); +} + +void test_svprfw_2(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_2 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 2) + return svprfw(pg, base, SV_PLDL2KEEP); +} + +void test_svprfw_3(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_3 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 3) + return svprfw(pg, base, SV_PLDL2STRM); +} + +void test_svprfw_4(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_4 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 4) + return svprfw(pg, base, SV_PLDL3KEEP); +} + +void test_svprfw_5(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_5 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 5) + return svprfw(pg, base, SV_PLDL3STRM); +} + +void test_svprfw_6(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_6 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 8) + return svprfw(pg, base, SV_PSTL1KEEP); +} + +void test_svprfw_7(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_7 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 9) + return svprfw(pg, base, SV_PSTL1STRM); +} + +void test_svprfw_8(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_8 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 10) + return svprfw(pg, base, SV_PSTL2KEEP); +} + +void test_svprfw_9(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_9 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 11) + return svprfw(pg, base, SV_PSTL2STRM); +} + +void test_svprfw_10(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_10 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 12) + return svprfw(pg, base, SV_PSTL3KEEP); +} + +void test_svprfw_11(svbool_t pg, const void *base) +{ + // CHECK-LABEL: test_svprfw_11 + // CHECK: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %base, i32 13) + return svprfw(pg, base, SV_PSTL3STRM); +} + +void test_svprfw_vnum(svbool_t pg, const void *base, int64_t vnum) +{ + // CHECK-LABEL: test_svprfw_vnum + // CHECK-DAG: %[[PG:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %pg) + // CHECK-DAG: %[[BASE:.*]] = bitcast i8* %base to <vscale x 4 x i32>* + // CHECK-DAG: %[[GEP:.*]] = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %[[BASE]], i64 %vnum + // CHECK-DAG: %[[I8_BASE:.*]] = bitcast <vscale x 4 x i32>* %[[GEP]] to i8* + // CHECK: @llvm.aarch64.sve.prf.nxv4i1(<vscale x 4 x i1> %[[PG]], i8* %[[I8_BASE]], i32 0) + return svprfw_vnum(pg, base, vnum, SV_PLDL1KEEP); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c new file mode 100644 index 000000000000..48fea8c540b7 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfb.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s + +#include <arm_sve.h> + +void test_svprfb(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfb(pg, base, 14); +} + +void test_svprfb_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfb(pg, base, -1); +} + +void test_svprfb_vnum(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfb_vnum(pg, base, 0, 14); +} + +void test_svprfb_vnum_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfb_vnum(pg, base, 0, -1); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c new file mode 100644 index 000000000000..2efa9b6c9e13 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfd.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s + +#include <arm_sve.h> + +void test_svprfd(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfd(pg, base, 14); +} + +void test_svprfd_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfd(pg, base, -1); +} + +void test_svprfd_vnum(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfd_vnum(pg, base, 0, 14); +} + +void test_svprfd_vnum_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfd_vnum(pg, base, 0, -1); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c new file mode 100644 index 000000000000..16b19203cdc5 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfh.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s + +#include <arm_sve.h> + +void test_svprfh(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfh(pg, base, 14); +} + +void test_svprfh_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfh(pg, base, -1); +} + +void test_svprfh_vnum(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfh_vnum(pg, base, 0, 14); +} + +void test_svprfh_vnum_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfh_vnum(pg, base, 0, -1); +} diff --git a/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c new file mode 100644 index 000000000000..ea1d6e24419b --- /dev/null +++ b/clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_prfw.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify %s + +#include <arm_sve.h> + +void test_svprfw(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfw(pg, base, 14); +} + +void test_svprfw_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfw(pg, base, -1); +} + +void test_svprfw_vnum(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value 14 is outside the valid range [0, 13]}} + return svprfw_vnum(pg, base, 0, 14); +} + +void test_svprfw_vnum_1(svbool_t pg, const void *base) +{ + // expected-error@+1 {{argument value -1 is outside the valid range [0, 13]}} + return svprfw_vnum(pg, base, 0, -1); +} diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index 13e1be6ec50f..8c8b415df914 100644 --- a/clang/utils/TableGen/SveEmitter.cpp +++ b/clang/utils/TableGen/SveEmitter.cpp @@ -536,6 +536,15 @@ void SVEType::applyModifier(char Mod) { Immediate = true; PredicatePattern = true; break; + case 'J': + Predicate = false; + Float = false; + ElementBitwidth = Bitwidth = 32; + NumVectors = 0; + Signed = true; + Immediate = true; + PrefetchOp = true; + break; case 'k': Predicate = false; Signed = true; @@ -703,6 +712,9 @@ Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy, if (T.isPredicatePattern()) ImmChecks.emplace_back( I - 1, Emitter.getEnumValueForImmCheck("ImmCheck0_31")); + else if (T.isPrefetchOp()) + ImmChecks.emplace_back( + I - 1, Emitter.getEnumValueForImmCheck("ImmCheck0_13")); } } @@ -1005,6 +1017,22 @@ void SVEEmitter::createHeader(raw_ostream &OS) { OS << " SV_ALL = 31\n"; OS << "} sv_pattern;\n\n"; + OS << "typedef enum\n"; + OS << "{\n"; + OS << " SV_PLDL1KEEP = 0,\n"; + OS << " SV_PLDL1STRM = 1,\n"; + OS << " SV_PLDL2KEEP = 2,\n"; + OS << " SV_PLDL2STRM = 3,\n"; + OS << " SV_PLDL3KEEP = 4,\n"; + OS << " SV_PLDL3STRM = 5,\n"; + OS << " SV_PSTL1KEEP = 8,\n"; + OS << " SV_PSTL1STRM = 9,\n"; + OS << " SV_PSTL2KEEP = 10,\n"; + OS << " SV_PSTL2STRM = 11,\n"; + OS << " SV_PSTL3KEEP = 12,\n"; + OS << " SV_PSTL3STRM = 13\n"; + OS << "} sv_prfop;\n\n"; + OS << "/* Function attributes */\n"; OS << "#define __aio static inline __attribute__((__always_inline__, " "__nodebug__, __overloadable__))\n\n"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits