sdesmalen created this revision. sdesmalen added reviewers: SjoerdMeijer, efriedma, rovka. Herald added a subscriber: tschuett. Herald added a project: clang. sdesmalen added a parent revision: D77595: [SveEmitter] Add NoAuto flag and builtins for svwhile.. sdesmalen added a child revision: D77597: [SveEmitter] Add ExpandOp1SVALL and builtin for svptrue.
Add the NoOverload flag to tell CGBuiltin that it does not have an overloaded type. This is used for e.g. svpfalse which does not take any arguments and always returns a svbool_t. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77596 Files: clang/include/clang/Basic/TargetBuiltins.h clang/include/clang/Basic/arm_sve.td clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfalse.c clang/utils/TableGen/SveEmitter.cpp
Index: clang/utils/TableGen/SveEmitter.cpp =================================================================== --- clang/utils/TableGen/SveEmitter.cpp +++ clang/utils/TableGen/SveEmitter.cpp @@ -261,6 +261,14 @@ llvm_unreachable("Unsupported imm check"); } + /// Returns the enum value for the flag type + uint64_t getEnumValueForFlag(StringRef C) const { + auto Res = FlagTypes.find(C); + if (Res != FlagTypes.end()) + return Res->getValue(); + llvm_unreachable("Unsupported flag"); + } + // Returns the SVETypeFlags for a given value and mask. uint64_t encodeFlag(uint64_t V, StringRef MaskName) const { auto It = FlagTypes.find(MaskName); @@ -844,6 +852,13 @@ for (auto FlagRec : FlagsList) Flags |= FlagRec->getValueAsInt("Value"); + // Create a dummy TypeSpec for non-overloaded builtins. + if (Types.empty()) { + assert((Flags & getEnumValueForFlag("NoOverloadTy")) && + "Expect TypeSpec for overloaded builtin!"); + Types = "i"; + } + // Extract type specs from string SmallVector<TypeSpec, 8> TypeSpecs; TypeSpec Acc; Index: clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfalse.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_pfalse.c @@ -0,0 +1,18 @@ +// 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 + +svbool_t test_svpfalse_b() +{ + // CHECK-LABEL: test_svpfalse_b + // CHECK: ret <vscale x 16 x i1> zeroinitializer + return SVE_ACLE_FUNC(svpfalse,_b,,)(); +} Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -7655,14 +7655,25 @@ Ops[1] = Builder.CreateSelect(Ops[0], Ops[1], SplatZero); } - Function *F = CGM.getIntrinsic(Builtin->LLVMIntrinsic, OverloadedTy); + Function *F = TypeFlags.isNotOverloaded() + ? CGM.getIntrinsic(Builtin->LLVMIntrinsic) + : CGM.getIntrinsic(Builtin->LLVMIntrinsic, OverloadedTy); Value *Call = Builder.CreateCall(F, Ops); - return Call; + + // Predicate results must be converted to svbool_t. + if (auto PredTy = dyn_cast<llvm::VectorType>(Call->getType())) + if (PredTy->getScalarType()->isIntegerTy(1)) + Call = EmitSVEPredicateCast(Call, cast<llvm::VectorType>(Ty)); + + return Call; } switch (BuiltinID) { default: return nullptr; + case SVE::BI__builtin_sve_svpfalse_b: + return ConstantInt::getFalse(Ty); + case SVE::BI__builtin_sve_svwhilele_b8_s32: case SVE::BI__builtin_sve_svwhilele_b8_s64: case SVE::BI__builtin_sve_svwhilele_b8_u32: Index: clang/include/clang/Basic/arm_sve.td =================================================================== --- clang/include/clang/Basic/arm_sve.td +++ clang/include/clang/Basic/arm_sve.td @@ -167,6 +167,7 @@ def IsStructStore : FlagType<0x00040000>; def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default def NoAuto : FlagType<0x00100000>; +def NoOverloadTy : FlagType<0x00200000>; // These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h class ImmCheckType<int val> { @@ -392,6 +393,7 @@ def SVCMLA_LANE : SInst<"svcmla_lane[_{d}]", "ddddii", "hf", MergeNone, "aarch64_sve_fcmla_lane", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, ImmCheck<4, ImmCheckComplexRotAll90>]>; + def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; def SVCMLA_M : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeOp1, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; @@ -400,6 +402,12 @@ def SVQDECH_S : SInst<"svqdech_pat[_{d}]", "ddIi", "s", MergeNone, "aarch64_sve_sqdech", [], [ImmCheck<2, ImmCheck1_16>]>; def SVQDECH_U : SInst<"svqdech_pat[_{d}]", "ddIi", "Us", MergeNone, "aarch64_sve_uqdech", [], [ImmCheck<2, ImmCheck1_16>]>; + +//////////////////////////////////////////////////////////////////////////////// +// Predicate creation + +def SVPFALSE : SInst<"svpfalse[_b]", "P", "", MergeNone, "", [NoOverloadTy]>; + //////////////////////////////////////////////////////////////////////////////// // Integer arithmetic def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; Index: clang/include/clang/Basic/TargetBuiltins.h =================================================================== --- clang/include/clang/Basic/TargetBuiltins.h +++ clang/include/clang/Basic/TargetBuiltins.h @@ -233,6 +233,7 @@ bool isStructStore() const { return Flags & IsStructStore; } bool isZExtReturn() const { return Flags & IsZExtReturn; } bool isNoAuto() const { return Flags & NoAuto; } + bool isNotOverloaded() const { return Flags & NoOverloadTy; } uint64_t getBits() const { return Flags; } bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits