Author: Cullen Rhodes Date: 2020-07-17T10:06:54Z New Revision: bb160e769dbef25fe0aa130c71458a8f686ccf80
URL: https://github.com/llvm/llvm-project/commit/bb160e769dbef25fe0aa130c71458a8f686ccf80 DIFF: https://github.com/llvm/llvm-project/commit/bb160e769dbef25fe0aa130c71458a8f686ccf80.diff LOG: [Sema][AArch64] Add parsing support for arm_sve_vector_bits attribute Summary: This patch implements parsing support for the 'arm_sve_vector_bits' type attribute, defined by the Arm C Language Extensions (ACLE, version 00bet5, section 3.7.3) for SVE [1]. The purpose of this attribute is to define fixed-length (VLST) versions of existing sizeless types (VLAT). For example: #if __ARM_FEATURE_SVE_BITS==512 typedef svint32_t fixed_svint32_t __attribute__((arm_sve_vector_bits(512))); #endif Creates a type 'fixed_svint32_t' that is a fixed-length version of 'svint32_t' that is normal-sized (rather than sizeless) and contains exactly 512 bits. Unlike 'svint32_t', this type can be used in places such as structs and arrays where sizeless types can't. Implemented in this patch is the following: * Defined and tested attribute taking single argument. * Checks the argument is an integer constant expression. * Attribute can only be attached to a single SVE vector or predicate type, excluding tuple types such as svint32x4_t. * Added the `-msve-vector-bits=<bits>` flag. When specified the `__ARM_FEATURE_SVE_BITS__EXPERIMENTAL` macro is defined. * Added a language option to store the vector size specified by the `-msve-vector-bits=<bits>` flag. This is used to validate `N == __ARM_FEATURE_SVE_BITS`, where N is the number of bits passed to the attribute and `__ARM_FEATURE_SVE_BITS` is the feature macro defined under the same flag. The `__ARM_FEATURE_SVE_BITS` macro will be made non-experimental in the final patch of the series. [1] https://developer.arm.com/documentation/100987/latest This is patch 1/4 of a patch series. Reviewers: sdesmalen, rsandifo-arm, efriedma, ctetreau, cameron.mcinally, rengolin, aaron.ballman Reviewed By: sdesmalen, aaron.ballman Differential Revision: https://reviews.llvm.org/D83550 Added: clang/test/Driver/aarch64-sve-vector-bits.c clang/test/Sema/attr-arm-sve-vector-bits.c Modified: clang/include/clang/AST/Type.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/AST/Type.cpp clang/lib/AST/TypePrinter.cpp clang/lib/Basic/Targets/AArch64.cpp clang/lib/Driver/ToolChains/Arch/AArch64.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Sema/SemaType.cpp clang/test/Preprocessor/aarch64-target-features.c Removed: ################################################################################ diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 0fc50e0e799f..131658fbc8c4 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1925,6 +1925,11 @@ class alignas(8) Type : public ExtQualsTypeCommonBase { bool isSizelessType() const; bool isSizelessBuiltinType() const; + /// Determines if this is a sizeless type supported by the + /// 'arm_sve_vector_bits' type attribute, which can be applied to a single + /// SVE vector or predicate, excluding tuple types such as svint32x4_t. + bool isVLSTBuiltinType() const; + /// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// object types, function types, and incomplete types. diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index bc4a380545af..8e0c57bd2efd 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1532,6 +1532,12 @@ def NeonVectorType : TypeAttr { let ASTNode = 0; } +def ArmSveVectorBits : TypeAttr { + let Spellings = [GNU<"arm_sve_vector_bits">]; + let Args = [IntArgument<"NumBits">]; + let Documentation = [ArmSveVectorBitsDocs]; +} + def ArmMveStrictPolymorphism : TypeAttr, TargetSpecificAttr<TargetARM> { let Spellings = [Clang<"__clang_arm_mve_strict_polymorphism">]; let Documentation = [ArmMveStrictPolymorphismDocs]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 3cba3a3d96f9..c835e6da04d5 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -4855,6 +4855,43 @@ close the handle. It is also assumed to require an open handle to work with. }]; } +def ArmSveVectorBitsDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The ``arm_sve_vector_bits(N)`` attribute is defined by the Arm C Language +Extensions (ACLE) for SVE. It is used to define fixed-length (VLST) variants of +sizeless types (VLAT). + +For example: + +.. code-block:: c + + #include <arm_sve.h> + + #if __ARM_FEATURE_SVE_BITS==512 + typedef svint32_t fixed_svint32_t __attribute__((arm_sve_vector_bits(512))); + #endif + +Creates a type ``fixed_svint32_t`` that is a fixed-length variant of +``svint32_t`` that contains exactly 512-bits. Unlike ``svint32_t``, this type +can be used in globals, structs, unions, and arrays, all of which are +unsupported for sizeless types. + +The attribute can be attached to a single SVE vector (such as ``svint32_t``) or +to the SVE predicate type ``svbool_t``, this excludes tuple types such as +``svint32x4_t``. The behavior of the attribute is undefined unless +``N==__ARM_FEATURE_SVE_BITS``, the implementation defined feature macro that is +enabled under the ``-msve-vector-bits`` flag. + +NOTE: This feature is currently WIP, the ``-msve-vector-bits=`` flag defines +the ``__ARM_FEATURE_SVE_BITS_EXPERIMENTAL`` macro. This feature is complete +when experimental is dropped. + +For more information See `Arm C Language Extensions for SVE +<https://developer.arm.com/documentation/100987/latest>`_ for more information. +}]; +} + def ArmMveStrictPolymorphismDocs : Documentation { let Category = DocCatType; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 558639ecad6a..3c266846c689 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -511,4 +511,7 @@ def warn_drv_libstdcxx_not_found : Warning< def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">; def err_drv_invalid_object_mode : Error<"OBJECT_MODE setting %0 is not recognized and is not a valid setting.">; + +def err_drv_invalid_sve_vector_bits : Error< + "'-msve-vector-bits' is not supported without SVE enabled">; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index aa4de2812312..d1de4e0488d3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2810,6 +2810,13 @@ def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">; def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; +def err_attribute_invalid_sve_type : Error< + "%0 attribute applied to non-SVE type %1">; +def err_attribute_bad_sve_vector_size : Error< + "invalid SVE vector size '%0', must match value set by " + "'-msve-vector-bits' ('%1')">; +def err_attribute_arm_feature_sve_bits_unsupported : Error< + "%0 is not supported when '-msve-vector-bits=<bits>' is not specified">; def err_attribute_requires_positive_integer : Error< "%0 attribute requires a %select{positive|non-negative}1 " "integral compile time constant expression">; diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 70f68d664bb7..c458e7014d62 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -382,6 +382,8 @@ LANGOPT(SpeculativeLoadHardening, 1, 0, "Speculative load hardening enabled") LANGOPT(RelativeCXXABIVTables, 1, 0, "Use an ABI-incompatible v-table layout that uses relative references") +LANGOPT(ArmSveVectorBits, 32, 0, "SVE vector size in bits") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f4556c15d744..85ff0e6857d7 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2343,6 +2343,11 @@ foreach i = {8-15,18} in def fcall_saved_x#i : Flag<["-"], "fcall-saved-x"#i>, Group<m_aarch64_Features_Group>, HelpText<"Make the x"#i#" register call-saved (AArch64 only)">; +def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">, + Group<m_aarch64_Features_Group>, Flags<[DriverOption,CC1Option]>, + HelpText<"Set the size of fixed-length SVE vectors in bits.">, + Values<"128,256,512,1024,2048">; + def msign_return_address_EQ : Joined<["-"], "msign-return-address=">, Flags<[CC1Option]>, Group<m_Group>, Values<"none,all,non-leaf">, HelpText<"Select return address signing scope">; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 10a6a2610130..068c355d48bc 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2294,6 +2294,30 @@ bool Type::isSizelessBuiltinType() const { bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isVLSTBuiltinType() const { + if (const BuiltinType *BT = getAs<BuiltinType>()) { + switch (BT->getKind()) { + case BuiltinType::SveInt8: + case BuiltinType::SveInt16: + case BuiltinType::SveInt32: + case BuiltinType::SveInt64: + case BuiltinType::SveUint8: + case BuiltinType::SveUint16: + case BuiltinType::SveUint32: + case BuiltinType::SveUint64: + case BuiltinType::SveFloat16: + case BuiltinType::SveFloat32: + case BuiltinType::SveFloat64: + case BuiltinType::SveBFloat16: + case BuiltinType::SveBool: + return true; + default: + return false; + } + } + return false; +} + bool QualType::isPODType(const ASTContext &Context) const { // C++11 has a more relaxed definition of POD. if (Context.getLangOpts().CPlusPlus11) diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 6f6932e65214..eff8e9976435 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1632,6 +1632,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::ArmMveStrictPolymorphism: OS << "__clang_arm_mve_strict_polymorphism"; break; + case attr::ArmSveVectorBits: + OS << "arm_sve_vector_bits"; + break; } OS << "))"; } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 25c02cb888c1..6fd97d4e5786 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -376,6 +376,10 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); + + if (Opts.ArmSveVectorBits) + Builder.defineMacro("__ARM_FEATURE_SVE_BITS_EXPERIMENTAL", + Twine(Opts.ArmSveVectorBits)); } ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 487c50dfc466..428b72a48904 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -369,6 +369,12 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, if (V8_6Pos != std::end(Features)) V8_6Pos = Features.insert(std::next(V8_6Pos), {"+i8mm", "+bf16"}); + bool HasSve = llvm::is_contained(Features, "+sve"); + // -msve_vector_bits=<bits> flag is valid only if SVE is enabled. + if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) + if (!HasSve) + D.Diag(diag::err_drv_invalid_sve_vector_bits); + if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) if (A->getOption().matches(options::OPT_mno_unaligned_access)) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 9d6333bb5f1d..91f133897271 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1715,6 +1715,21 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); } + + // Handle -msve_vector_bits=<bits> + if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { + StringRef Val = A->getValue(); + const Driver &D = getToolChain().getDriver(); + if (!Val.equals("128") && !Val.equals("256") && !Val.equals("512") && + !Val.equals("1024") && !Val.equals("2048")) { + // Handle the unsupported values passed to msve-vector-bits. + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } else if (A->getOption().matches(options::OPT_msve_vector_bits_EQ)) { + CmdArgs.push_back( + Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val)); + } + } } void Clang::AddMIPSTargetArgs(const ArgList &Args, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 75d7cf5d26d3..c34c2a18b048 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2997,6 +2997,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm); Opts.Cmse = Args.hasArg(OPT_mcmse); // Armv8-M Security Extensions + Opts.ArmSveVectorBits = + getLastArgIntValue(Args, options::OPT_msve_vector_bits_EQ, 0, Diags); + // __declspec is enabled by default for the PS4 by the driver, and also // enabled for Microsoft Extensions or Borland Extensions, here. // diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index b8f7f1a58159..629fdff5ccf9 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -7686,6 +7686,19 @@ static bool isPermittedNeonBaseType(QualType &Ty, BTy->getKind() == BuiltinType::BFloat16; } +bool verifyValidIntegerConstantExpr(Sema &S, const ParsedAttr &Attr, + llvm::APSInt &Result) { + const auto *AttrExpr = Attr.getArgAsExpr(0); + if (AttrExpr->isTypeDependent() || AttrExpr->isValueDependent() || + !AttrExpr->isIntegerConstantExpr(Result, S.Context)) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) + << Attr << AANT_ArgumentIntegerConstant << AttrExpr->getSourceRange(); + Attr.setInvalid(); + return false; + } + return true; +} + /// HandleNeonVectorTypeAttr - The "neon_vector_type" and /// "neon_polyvector_type" attributes are used to create vector types that /// are mangled according to ARM's ABI. Otherwise, these types are identical @@ -7711,16 +7724,10 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, return; } // The number of elements must be an ICE. - Expr *numEltsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0)); llvm::APSInt numEltsInt(32); - if (numEltsExpr->isTypeDependent() || numEltsExpr->isValueDependent() || - !numEltsExpr->isIntegerConstantExpr(numEltsInt, S.Context)) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) - << Attr << AANT_ArgumentIntegerConstant - << numEltsExpr->getSourceRange(); - Attr.setInvalid(); + if (!verifyValidIntegerConstantExpr(S, Attr, numEltsInt)) return; - } + // Only certain element types are supported for Neon vectors. if (!isPermittedNeonBaseType(CurType, VecKind, S)) { S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; @@ -7741,6 +7748,58 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr, CurType = S.Context.getVectorType(CurType, numElts, VecKind); } +/// HandleArmSveVectorBitsTypeAttr - The "arm_sve_vector_bits" attribute is +/// used to create fixed-length versions of sizeless SVE types defined by +/// the ACLE, such as svint32_t and svbool_t. +static void HandleArmSveVectorBitsTypeAttr(QualType &CurType, + const ParsedAttr &Attr, Sema &S) { + // Target must have SVE. + if (!S.Context.getTargetInfo().hasFeature("sve")) { + S.Diag(Attr.getLoc(), diag::err_attribute_unsupported) << Attr; + Attr.setInvalid(); + return; + } + + // Attribute is unsupported if '-msve-vector-bits=<bits>' isn't specified. + if (!S.getLangOpts().ArmSveVectorBits) { + S.Diag(Attr.getLoc(), diag::err_attribute_arm_feature_sve_bits_unsupported) + << Attr; + Attr.setInvalid(); + return; + } + + // Check the attribute arguments. + if (Attr.getNumArgs() != 1) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) + << Attr << 1; + Attr.setInvalid(); + return; + } + + // The vector size must be an integer constant expression. + llvm::APSInt SveVectorSizeInBits(32); + if (!verifyValidIntegerConstantExpr(S, Attr, SveVectorSizeInBits)) + return; + + unsigned VecSize = static_cast<unsigned>(SveVectorSizeInBits.getZExtValue()); + + // The attribute vector size must match -msve-vector-bits. + if (VecSize != S.getLangOpts().ArmSveVectorBits) { + S.Diag(Attr.getLoc(), diag::err_attribute_bad_sve_vector_size) + << VecSize << S.getLangOpts().ArmSveVectorBits; + Attr.setInvalid(); + return; + } + + // Attribute can only be attached to a single SVE vector or predicate type. + if (!CurType->isVLSTBuiltinType()) { + S.Diag(Attr.getLoc(), diag::err_attribute_invalid_sve_type) + << Attr << CurType; + Attr.setInvalid(); + return; + } +} + static void HandleArmMveStrictPolymorphismAttr(TypeProcessingState &State, QualType &CurType, ParsedAttr &Attr) { @@ -8004,6 +8063,10 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, VectorType::NeonPolyVector); attr.setUsedAsTypeAttr(); break; + case ParsedAttr::AT_ArmSveVectorBits: + HandleArmSveVectorBitsTypeAttr(type, attr, state.getSema()); + attr.setUsedAsTypeAttr(); + break; case ParsedAttr::AT_ArmMveStrictPolymorphism: { HandleArmMveStrictPolymorphismAttr(state, type, attr); attr.setUsedAsTypeAttr(); diff --git a/clang/test/Driver/aarch64-sve-vector-bits.c b/clang/test/Driver/aarch64-sve-vector-bits.c new file mode 100644 index 000000000000..b7138d4a0772 --- /dev/null +++ b/clang/test/Driver/aarch64-sve-vector-bits.c @@ -0,0 +1,63 @@ +// ----------------------------------------------------------------------------- +// Tests for the -msve-vector-bits flag +// ----------------------------------------------------------------------------- + +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=128 2>&1 | FileCheck --check-prefix=CHECK-128 %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=256 2>&1 | FileCheck --check-prefix=CHECK-256 %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=512 2>&1 | FileCheck --check-prefix=CHECK-512 %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=1024 2>&1 | FileCheck --check-prefix=CHECK-1024 %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=2048 2>&1 | FileCheck --check-prefix=CHECK-2048 %s + +// CHECK-128: "-msve-vector-bits=128" +// CHECK-256: "-msve-vector-bits=256" +// CHECK-512: "-msve-vector-bits=512" +// CHECK-1024: "-msve-vector-bits=1024" +// CHECK-2048: "-msve-vector-bits=2048" + +// Bail out if -msve-vector-bits is specified without SVE enabled +// ----------------------------------------------------------------------------- +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -msve-vector-bits=128 \ +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-SVE-ERROR %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -msve-vector-bits=256 \ +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-SVE-ERROR %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -msve-vector-bits=512 \ +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-SVE-ERROR %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -msve-vector-bits=1024 \ +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-SVE-ERROR %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -msve-vector-bits=2048 \ +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-SVE-ERROR %s + +// CHECK-NO-SVE-ERROR: error: '-msve-vector-bits' is not supported without SVE enabled + +// Error out if an unsupported value is passed to -msve-vector-bits. +// ----------------------------------------------------------------------------- +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=64 2>&1 | FileCheck --check-prefix=CHECK-BAD-VALUE-ERROR %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=A 2>&1 | FileCheck --check-prefix=CHECK-BAD-VALUE-ERROR %s + +// CHECK-BAD-VALUE-ERROR: error: unsupported argument '{{.*}}' to option 'msve-vector-bits=' + +// Error if using attribute without -msve-vector-bits +// ----------------------------------------------------------------------------- +// RUN: not %clang -c %s -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s + +typedef __SVInt32_t svint32_t; +typedef svint32_t noflag __attribute__((arm_sve_vector_bits(256))); + +// CHECK-NO-FLAG-ERROR: error: 'arm_sve_vector_bits' is not supported when '-msve-vector-bits=<bits>' is not specified + +// Error if attribute vector size != -msve-vector-bits +// ----------------------------------------------------------------------------- +// RUN: not %clang -c %s -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=128 2>&1 | FileCheck --check-prefix=CHECK-BAD-VECTOR-SIZE-ERROR %s + +typedef svint32_t bad_vector_size __attribute__((arm_sve_vector_bits(256))); + +// CHECK-BAD-VECTOR-SIZE-ERROR: error: invalid SVE vector size '256', must match value set by '-msve-vector-bits' ('128') diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 12af9e043c75..905a77785a9d 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -44,6 +44,12 @@ // CHECK-NOT: __ARM_BF16_FORMAT_ALTERNATIVE 1 // CHECK-NOT: __ARM_FEATURE_BF16 1 // CHECK-NOT: __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 0 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 128 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 256 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 512 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 1024 +// CHECK-NOT: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 2048 // RUN: %clang -target aarch64_be-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-BIGENDIAN // CHECK-BIGENDIAN: __ARM_BIG_ENDIAN 1 @@ -431,3 +437,17 @@ // CHECK-BFLOAT: __ARM_FEATURE_BF16 1 // CHECK-BFLOAT: __ARM_FEATURE_BF16_VECTOR_ARITHMETIC 1 +// ================== Check sve-vector-bits flag. +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=128 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-128 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=256 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-256 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=512 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-512 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=1024 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-1024 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=2048 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-2048 %s +// RUN: %clang -target aarch64-arm-none-eabi -march=armv8-a+sve -msve-vector-bits=2048 -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-SVE-VECTOR-BITS-2048 %s +// NOTE: The __ARM_FEATURE_SVE_BITS feature macro is experimental until the +// feature is complete. +// CHECK-SVE-VECTOR-BITS-128: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 128 +// CHECK-SVE-VECTOR-BITS-256: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 256 +// CHECK-SVE-VECTOR-BITS-512: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 512 +// CHECK-SVE-VECTOR-BITS-1024: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 1024 +// CHECK-SVE-VECTOR-BITS-2048: __ARM_FEATURE_SVE_BITS_EXPERIMENTAL 2048 diff --git a/clang/test/Sema/attr-arm-sve-vector-bits.c b/clang/test/Sema/attr-arm-sve-vector-bits.c new file mode 100644 index 000000000000..48ca7d8fa812 --- /dev/null +++ b/clang/test/Sema/attr-arm-sve-vector-bits.c @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -msve-vector-bits=128 -fallow-half-arguments-and-returns %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -msve-vector-bits=256 -fallow-half-arguments-and-returns %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -msve-vector-bits=512 -fallow-half-arguments-and-returns %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -msve-vector-bits=1024 -fallow-half-arguments-and-returns %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -fsyntax-only -verify -msve-vector-bits=2048 -fallow-half-arguments-and-returns %s + +#define N __ARM_FEATURE_SVE_BITS_EXPERIMENTAL + +typedef __SVInt8_t svint8_t; +typedef __SVInt16_t svint16_t; +typedef __SVInt32_t svint32_t; +typedef __SVInt64_t svint64_t; +typedef __SVUint8_t svuint8_t; +typedef __SVUint16_t svuint16_t; +typedef __SVUint32_t svuint32_t; +typedef __SVUint64_t svuint64_t; +typedef __SVFloat16_t svfloat16_t; +typedef __SVFloat32_t svfloat32_t; +typedef __SVFloat64_t svfloat64_t; + +#if defined(__ARM_FEATURE_SVE_BF16) +typedef __SVBFloat16_t svbfloat16_t; +#endif + +typedef __SVBool_t svbool_t; + +// Define valid fixed-width SVE types +typedef svint8_t fixed_int8_t __attribute__((arm_sve_vector_bits(N))); +typedef svint16_t fixed_int16_t __attribute__((arm_sve_vector_bits(N))); +typedef svint32_t fixed_int32_t __attribute__((arm_sve_vector_bits(N))); +typedef svint64_t fixed_int64_t __attribute__((arm_sve_vector_bits(N))); + +typedef svuint8_t fixed_uint8_t __attribute__((arm_sve_vector_bits(N))); +typedef svuint16_t fixed_uint16_t __attribute__((arm_sve_vector_bits(N))); +typedef svuint32_t fixed_uint32_t __attribute__((arm_sve_vector_bits(N))); +typedef svuint64_t fixed_uint64_t __attribute__((arm_sve_vector_bits(N))); + +typedef svfloat16_t fixed_float16_t __attribute__((arm_sve_vector_bits(N))); +typedef svfloat32_t fixed_float32_t __attribute__((arm_sve_vector_bits(N))); +typedef svfloat64_t fixed_float64_t __attribute__((arm_sve_vector_bits(N))); + +typedef svbfloat16_t fixed_bfloat16_t __attribute__((arm_sve_vector_bits(N))); + +typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(N))); + +// Attribute must have a single argument +typedef svint8_t no_argument __attribute__((arm_sve_vector_bits)); // expected-error {{'arm_sve_vector_bits' attribute takes one argument}} +typedef svint8_t two_arguments __attribute__((arm_sve_vector_bits(2, 4))); // expected-error {{'arm_sve_vector_bits' attribute takes one argument}} + +// The number of SVE vector bits must be an integer constant expression +typedef svint8_t non_int_size1 __attribute__((arm_sve_vector_bits(2.0))); // expected-error {{'arm_sve_vector_bits' attribute requires an integer constant}} +typedef svint8_t non_int_size2 __attribute__((arm_sve_vector_bits("256"))); // expected-error {{'arm_sve_vector_bits' attribute requires an integer constant}} + +typedef __clang_svint8x2_t svint8x2_t; +typedef __clang_svfloat32x3_t svfloat32x3_t; + +// Attribute must be attached to a single SVE vector or predicate type. +typedef void *badtype1 __attribute__((arm_sve_vector_bits(N))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'void *'}} +typedef int badtype2 __attribute__((arm_sve_vector_bits(N))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'int'}} +typedef float badtype3 __attribute__((arm_sve_vector_bits(N))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'float'}} +typedef svint8x2_t badtype4 __attribute__((arm_sve_vector_bits(N))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'svint8x2_t' (aka '__clang_svint8x2_t')}} +typedef svfloat32x3_t badtype5 __attribute__((arm_sve_vector_bits(N))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'svfloat32x3_t' (aka '__clang_svfloat32x3_t')}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits