diff options
author | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2020-01-27 10:40:14 -0800 |
---|---|---|
committer | Francis Visoiu Mistrih <francisvm@yahoo.com> | 2020-01-28 13:59:08 -0800 |
commit | 4e799ada5860d1029ea89226b9b867302e792251 (patch) | |
tree | 29962204554680eaef2136012bb21eb67968e6f1 | |
parent | c4f6fbe971351273b19a4a819bf6ceae2b70b37e (diff) | |
download | llvm-4e799ada5860d1029ea89226b9b867302e792251.zip llvm-4e799ada5860d1029ea89226b9b867302e792251.tar.gz llvm-4e799ada5860d1029ea89226b9b867302e792251.tar.bz2 |
[CodeGen] Attach no-builtin attributes to function definitions with no Decl
When using -fno-builtin[-<name>], we don't attach the IR attributes to
function definitions with no Decl, like the ones created through
`CreateGlobalInitOrDestructFunction`.
This results in projects using -fno-builtin or -ffreestanding to start
seeing symbols like _memset_pattern16.
The fix changes the behavior to always add the attribute if LangOptions
requests it.
Differential Revision: https://reviews.llvm.org/D73495
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 63 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/global-init.cpp | 7 |
2 files changed, 53 insertions, 17 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 3a50e2b..d633b3d 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1832,6 +1832,42 @@ void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) { F.addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs); } +static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs, + const LangOptions &LangOpts, + const NoBuiltinAttr *NBA = nullptr) { + auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) { + SmallString<32> AttributeName; + AttributeName += "no-builtin-"; + AttributeName += BuiltinName; + FuncAttrs.addAttribute(AttributeName); + }; + + // First, handle the language options passed through -fno-builtin[-<name>] + if (LangOpts.NoBuiltin) { + // -fno-builtin disables them all. + FuncAttrs.addAttribute("no-builtins"); + return; + } + + // Then, add attributes for builtins specified through -fno-builtin-<name>. + llvm::for_each(LangOpts.NoBuiltinFuncs, AddNoBuiltinAttr); + + // Now, let's check the __attribute__((no_builtin("...")) attribute added to + // the source. + if (!NBA) + return; + + // If there is a wildcard in the builtin names specified through the + // attribute, disable them all. + if (llvm::is_contained(NBA->builtinNames(), "*")) { + FuncAttrs.addAttribute("no-builtins"); + return; + } + + // And last, add the rest of the builtin names. + llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr); +} + void CodeGenModule::ConstructAttributeList( StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo, llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) { @@ -1850,6 +1886,8 @@ void CodeGenModule::ConstructAttributeList( const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl(); bool HasOptnone = false; + // The NoBuiltinAttr attached to a TargetDecl (only allowed on FunctionDecls). + const NoBuiltinAttr *NBA = nullptr; // FIXME: handle sseregparm someday... if (TargetDecl) { if (TargetDecl->hasAttr<ReturnsTwiceAttr>()) @@ -1875,22 +1913,7 @@ void CodeGenModule::ConstructAttributeList( if (!(AttrOnCallSite && IsVirtualCall)) { if (Fn->isNoReturn()) FuncAttrs.addAttribute(llvm::Attribute::NoReturn); - - const auto *NBA = Fn->getAttr<NoBuiltinAttr>(); - bool HasWildcard = NBA && llvm::is_contained(NBA->builtinNames(), "*"); - if (getLangOpts().NoBuiltin || HasWildcard) - FuncAttrs.addAttribute("no-builtins"); - else { - auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) { - SmallString<32> AttributeName; - AttributeName += "no-builtin-"; - AttributeName += BuiltinName; - FuncAttrs.addAttribute(AttributeName); - }; - llvm::for_each(getLangOpts().NoBuiltinFuncs, AddNoBuiltinAttr); - if (NBA) - llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr); - } + NBA = Fn->getAttr<NoBuiltinAttr>(); } } @@ -1925,6 +1948,14 @@ void CodeGenModule::ConstructAttributeList( } } + // Attach "no-builtins" attributes to: + // * call sites: both `nobuiltin` and "no-builtins" or "no-builtin-<name>". + // * definitions: "no-builtins" or "no-builtin-<name>" only. + // The attributes can come from: + // * LangOpts: -ffreestanding, -fno-builtin, -fno-builtin-<name> + // * FunctionDecl attributes: __attribute__((no_builtin(...))) + addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA); + ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs); // This must run after constructing the default function attribute list diff --git a/clang/test/CodeGenCXX/global-init.cpp b/clang/test/CodeGenCXX/global-init.cpp index 1970de8..eaa3745 100644 --- a/clang/test/CodeGenCXX/global-init.cpp +++ b/clang/test/CodeGenCXX/global-init.cpp @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix CHECK-NOEXC %s // RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -mframe-pointer=non-leaf %s -o - \ // RUN: | FileCheck -check-prefix CHECK-FP %s +// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - -fno-builtin \ +// RUN: | FileCheck -check-prefix CHECK-NOBUILTIN %s struct A { A(); @@ -202,9 +204,12 @@ namespace test7 { // rdar://problem/8090834: this should be nounwind // CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { - // CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} } +// Make sure we mark global initializers with the no-builtins attribute. +// CHECK-NOBUILTIN: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK-NOBUILTIN: attributes [[NUW]] = { noinline nounwind{{.*}}"no-builtins"{{.*}} } + // PR21811: attach the appropriate attribute to the global init function // CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { // CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"frame-pointer"="non-leaf"{{.*}} } |