Author: Hsiangkai Wang Date: 2021-04-25T08:49:19+08:00 New Revision: 108864397d26ffff39267f417cabc7f248431437
URL: https://github.com/llvm/llvm-project/commit/108864397d26ffff39267f417cabc7f248431437 DIFF: https://github.com/llvm/llvm-project/commit/108864397d26ffff39267f417cabc7f248431437.diff LOG: [Clang] Add clang attribute `clang_builtin_alias`. In some cases, we want to provide the alias name for the clang builtins. For example, the arguments must be constant integers for some RISC-V builtins. If we use wrapper functions, we could not constrain the arguments be constant integer. This attribute is used to achieve the purpose. Besides this, use `clang_builtin_alias` is more efficient than using wrapper functions. We use this attribute to deal with test time issue reported in https://bugs.llvm.org/show_bug.cgi?id=49962. In our downstream testing, it could decrease the testing time from 6.3 seconds to 3.7 seconds for vloxei.c test. Differential Revision: https://reviews.llvm.org/D100611 Added: clang/test/CodeGen/RISCV/riscv-attr-builtin-alias-err.c clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c Modified: clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/AST/Decl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/Misc/pragma-attribute-supported-attributes-list.test Removed: ################################################################################ diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 08534ec61620..19ae88757033 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -642,6 +642,15 @@ def Alias : Attr { let Documentation = [Undocumented]; } +def BuiltinAlias : Attr { + let Spellings = [CXX11<"clang", "builtin_alias">, + C2x<"clang", "builtin_alias">, + GNU<"clang_builtin_alias">]; + let Args = [IdentifierArgument<"BuiltinName">]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Documentation = [BuiltinAliasDocs]; +} + def ArmBuiltinAlias : InheritableAttr, TargetSpecificAttr<TargetAnyArm> { let Spellings = [Clang<"__clang_arm_builtin_alias">]; let Args = [IdentifierArgument<"BuiltinName">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 1960596f1bfb..9cc4c837cc49 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -4699,6 +4699,25 @@ the old mangled name and the new code will use the new mangled name with tags. }]; } +def BuiltinAliasDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +This attribute is used in the implementation of the C intrinsics. +It allows the C intrinsic functions to be declared using the names defined +in target builtins, and still be recognized as clang builtins equivalent to the +underlying name. For example, ``riscv_vector.h`` declares the function ``vadd`` +with ``__attribute__((clang_builtin_alias(__builtin_rvv_vadd_vv_i8m1)))``. +This ensures that both functions are recognized as that clang builtin, +and in the latter case, the choice of which builtin to identify the +function as can be deferred until after overload resolution. + +This attribute can only be used to set up the aliases for certain ARM/RISC-V +C intrinsic functions; it is intended for use only inside ``arm_*.h`` and +``riscv_*.h`` and is not a general mechanism for declaring arbitrary aliases +for clang builtin functions. + }]; +} + def PreferredNameDocs : Documentation { let Category = DocCatDecl; let Content = [{ @@ -5693,6 +5712,10 @@ This attribute can only be used to set up the aliases for certain Arm intrinsic functions; it is intended for use only inside ``arm_*.h`` and is not a general mechanism for declaring arbitrary aliases for clang builtin functions. + +In order to avoid duplicating the attribute definitions for similar +purpose for other architecture, there is a general form for the +attribute `clang_builtin_alias`. }]; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3a58d3dc5c4a..639565feb576 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4026,6 +4026,8 @@ def note_protocol_decl_undefined : Note< def err_attribute_preferred_name_arg_invalid : Error< "argument %0 to 'preferred_name' attribute is not a typedef for " "a specialization of %1">; +def err_attribute_builtin_alias : Error< + "%0 attribute can only be applied to a ARM or RISC-V builtin">; // called-once attribute diagnostics. def err_called_once_attribute_wrong_type : Error< diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index fcda07dab604..f77acefb1781 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3265,6 +3265,8 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { if (const auto *ABAA = getAttr<ArmBuiltinAliasAttr>()) { BuiltinID = ABAA->getBuiltinName()->getBuiltinID(); + } else if (const auto *BAA = getAttr<BuiltinAliasAttr>()) { + BuiltinID = BAA->getBuiltinName()->getBuiltinID(); } else if (const auto *A = getAttr<BuiltinAttr>()) { BuiltinID = A->getID(); } @@ -3275,7 +3277,7 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const { // If the function is marked "overloadable", it has a diff erent mangled name // and is not the C library function. if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>() && - !hasAttr<ArmBuiltinAliasAttr>()) + (!hasAttr<ArmBuiltinAliasAttr>() && !hasAttr<BuiltinAliasAttr>())) return 0; ASTContext &Context = getASTContext(); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 43ca644ed21e..b31f9ecb2ace 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5120,6 +5120,7 @@ static bool ArmSveAliasValid(unsigned BuiltinID, StringRef AliasName) { #define GET_SVE_BUILTINS #define BUILTIN(name, types, attr) case SVE::BI##name: #include "clang/Basic/arm_sve_builtins.inc" +#undef BUILTIN return true; } } @@ -5146,6 +5147,44 @@ static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(::new (S.Context) ArmBuiltinAliasAttr(S.Context, AL, Ident)); } +static bool RISCVAliasValid(unsigned BuiltinID, StringRef AliasName) { + switch (BuiltinID) { + default: + return false; +#define BUILTIN(ID, TYPE, ATTRS) case RISCV::BI##ID: +#include "clang/Basic/BuiltinsRISCV.def" +#undef BUILTIN + return true; + } +} + +static void handleBuiltinAliasAttr(Sema &S, Decl *D, + const ParsedAttr &AL) { + if (!AL.isArgIdent(0)) { + S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) + << AL << 1 << AANT_ArgumentIdentifier; + return; + } + + IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident; + unsigned BuiltinID = Ident->getBuiltinID(); + StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName(); + + bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64(); + bool IsARM = S.Context.getTargetInfo().getTriple().isARM(); + bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV(); + if ((IsAArch64 && !ArmSveAliasValid(BuiltinID, AliasName)) || + (IsARM && !ArmMveAliasValid(BuiltinID, AliasName) && + !ArmCdeAliasValid(BuiltinID, AliasName)) || + (IsRISCV && !RISCVAliasValid(BuiltinID, AliasName)) || + (!IsAArch64 && !IsARM && !IsRISCV)) { + S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL; + return; + } + + D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident)); +} + //===----------------------------------------------------------------------===// // Checker-specific attribute handlers. //===----------------------------------------------------------------------===// @@ -8243,6 +8282,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_EnforceTCBLeaf: handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL); break; + + case ParsedAttr::AT_BuiltinAlias: + handleBuiltinAliasAttr(S, D, AL); + break; } } diff --git a/clang/test/CodeGen/RISCV/riscv-attr-builtin-alias-err.c b/clang/test/CodeGen/RISCV/riscv-attr-builtin-alias-err.c new file mode 100644 index 000000000000..9ee8ce68ebc5 --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-attr-builtin-alias-err.c @@ -0,0 +1,19 @@ +// REQUIRES: riscv-registered-target +// RUN: not %clang_cc1 -triple riscv64 -fsyntax-only -verify \ +// RUN: -target-feature +experimental-v %s 2>&1 \ +// RUN: | FileCheck %s + +#include <riscv_vector.h> + +#define __rvv_generic \ +static inline __attribute__((__always_inline__, __nodebug__)) + +__rvv_generic +__attribute__((clang_builtin_alias(__builtin_rvv_vadd_vv_i8m1))) +vint8m1_t vadd_generic (vint8m1_t op0, vint8m1_t op1, size_t op2); + +// CHECK: passing 'vint8m2_t' (aka '__rvv_int8m2_t') to parameter of incompatible type 'vint8m1_t' +vint8m2_t test(vint8m2_t op0, vint8m2_t op1, size_t vl) { + vint8m2_t ret = vadd_generic(op0, op1, vl); + return ret; +} diff --git a/clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c b/clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c new file mode 100644 index 000000000000..e3ff4e4d7dd5 --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-attr-builtin-alias.c @@ -0,0 +1,36 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -emit-llvm -target-feature +experimental-v \ +// RUN: %s -o - \ +// RUN: | FileCheck %s + +#include <riscv_vector.h> + +#define __rvv_generic \ +static inline __attribute__((__always_inline__, __nodebug__)) + +__rvv_generic +__attribute__((clang_builtin_alias(__builtin_rvv_vadd_vv_i8m1))) +vint8m1_t vadd_generic (vint8m1_t op0, vint8m1_t op1, size_t op2); + +// CHECK-LABEL: @test( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OP0_ADDR:%.*]] = alloca <vscale x 8 x i8>, align 1 +// CHECK-NEXT: [[OP1_ADDR:%.*]] = alloca <vscale x 8 x i8>, align 1 +// CHECK-NEXT: [[VL_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[RET:%.*]] = alloca <vscale x 8 x i8>, align 1 +// CHECK-NEXT: store <vscale x 8 x i8> [[OP0:%.*]], <vscale x 8 x i8>* [[OP0_ADDR]], align 1 +// CHECK-NEXT: store <vscale x 8 x i8> [[OP1:%.*]], <vscale x 8 x i8>* [[OP1_ADDR]], align 1 +// CHECK-NEXT: store i64 [[VL:%.*]], i64* [[VL_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <vscale x 8 x i8>, <vscale x 8 x i8>* [[OP0_ADDR]], align 1 +// CHECK-NEXT: [[TMP1:%.*]] = load <vscale x 8 x i8>, <vscale x 8 x i8>* [[OP1_ADDR]], align 1 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* [[VL_ADDR]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = call <vscale x 8 x i8> @llvm.riscv.vadd.nxv8i8.nxv8i8.i64(<vscale x 8 x i8> [[TMP0]], <vscale x 8 x i8> [[TMP1]], i64 [[TMP2]]) +// CHECK-NEXT: store <vscale x 8 x i8> [[TMP3]], <vscale x 8 x i8>* [[RET]], align 1 +// CHECK-NEXT: [[TMP4:%.*]] = load <vscale x 8 x i8>, <vscale x 8 x i8>* [[RET]], align 1 +// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP4]] +// +vint8m1_t test(vint8m1_t op0, vint8m1_t op1, size_t vl) { + vint8m1_t ret = vadd_generic(op0, op1, vl); + return ret; +} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index ddc4f73f1fd7..473ac1e530fd 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -22,6 +22,7 @@ // CHECK-NEXT: Assumption (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: Availability ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_implementation, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable)) // CHECK-NEXT: BPFPreserveAccessIndex (SubjectMatchRule_record) +// CHECK-NEXT: BuiltinAlias (SubjectMatchRule_function) // CHECK-NEXT: CFAuditedTransfer (SubjectMatchRule_function) // CHECK-NEXT: CFConsumed (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: CFICanonicalJumpTable (SubjectMatchRule_function) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits