Skip to content

Commit 4e799ad

Browse files
committed
[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
1 parent c4f6fbe commit 4e799ad

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,42 @@ void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
18321832
F.addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs);
18331833
}
18341834

1835+
static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
1836+
const LangOptions &LangOpts,
1837+
const NoBuiltinAttr *NBA = nullptr) {
1838+
auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
1839+
SmallString<32> AttributeName;
1840+
AttributeName += "no-builtin-";
1841+
AttributeName += BuiltinName;
1842+
FuncAttrs.addAttribute(AttributeName);
1843+
};
1844+
1845+
// First, handle the language options passed through -fno-builtin[-<name>]
1846+
if (LangOpts.NoBuiltin) {
1847+
// -fno-builtin disables them all.
1848+
FuncAttrs.addAttribute("no-builtins");
1849+
return;
1850+
}
1851+
1852+
// Then, add attributes for builtins specified through -fno-builtin-<name>.
1853+
llvm::for_each(LangOpts.NoBuiltinFuncs, AddNoBuiltinAttr);
1854+
1855+
// Now, let's check the __attribute__((no_builtin("...")) attribute added to
1856+
// the source.
1857+
if (!NBA)
1858+
return;
1859+
1860+
// If there is a wildcard in the builtin names specified through the
1861+
// attribute, disable them all.
1862+
if (llvm::is_contained(NBA->builtinNames(), "*")) {
1863+
FuncAttrs.addAttribute("no-builtins");
1864+
return;
1865+
}
1866+
1867+
// And last, add the rest of the builtin names.
1868+
llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
1869+
}
1870+
18351871
void CodeGenModule::ConstructAttributeList(
18361872
StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
18371873
llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) {
@@ -1850,6 +1886,8 @@ void CodeGenModule::ConstructAttributeList(
18501886
const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl();
18511887

18521888
bool HasOptnone = false;
1889+
// The NoBuiltinAttr attached to a TargetDecl (only allowed on FunctionDecls).
1890+
const NoBuiltinAttr *NBA = nullptr;
18531891
// FIXME: handle sseregparm someday...
18541892
if (TargetDecl) {
18551893
if (TargetDecl->hasAttr<ReturnsTwiceAttr>())
@@ -1875,22 +1913,7 @@ void CodeGenModule::ConstructAttributeList(
18751913
if (!(AttrOnCallSite && IsVirtualCall)) {
18761914
if (Fn->isNoReturn())
18771915
FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
1878-
1879-
const auto *NBA = Fn->getAttr<NoBuiltinAttr>();
1880-
bool HasWildcard = NBA && llvm::is_contained(NBA->builtinNames(), "*");
1881-
if (getLangOpts().NoBuiltin || HasWildcard)
1882-
FuncAttrs.addAttribute("no-builtins");
1883-
else {
1884-
auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
1885-
SmallString<32> AttributeName;
1886-
AttributeName += "no-builtin-";
1887-
AttributeName += BuiltinName;
1888-
FuncAttrs.addAttribute(AttributeName);
1889-
};
1890-
llvm::for_each(getLangOpts().NoBuiltinFuncs, AddNoBuiltinAttr);
1891-
if (NBA)
1892-
llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
1893-
}
1916+
NBA = Fn->getAttr<NoBuiltinAttr>();
18941917
}
18951918
}
18961919

@@ -1925,6 +1948,14 @@ void CodeGenModule::ConstructAttributeList(
19251948
}
19261949
}
19271950

1951+
// Attach "no-builtins" attributes to:
1952+
// * call sites: both `nobuiltin` and "no-builtins" or "no-builtin-<name>".
1953+
// * definitions: "no-builtins" or "no-builtin-<name>" only.
1954+
// The attributes can come from:
1955+
// * LangOpts: -ffreestanding, -fno-builtin, -fno-builtin-<name>
1956+
// * FunctionDecl attributes: __attribute__((no_builtin(...)))
1957+
addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA);
1958+
19281959
ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
19291960

19301961
// This must run after constructing the default function attribute list

clang/test/CodeGenCXX/global-init.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix CHECK-NOEXC %s
33
// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -mframe-pointer=non-leaf %s -o - \
44
// RUN: | FileCheck -check-prefix CHECK-FP %s
5+
// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - -fno-builtin \
6+
// RUN: | FileCheck -check-prefix CHECK-NOBUILTIN %s
57

68
struct A {
79
A();
@@ -202,9 +204,12 @@ namespace test7 {
202204

203205
// rdar://problem/8090834: this should be nounwind
204206
// CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
205-
206207
// CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} }
207208

209+
// Make sure we mark global initializers with the no-builtins attribute.
210+
// CHECK-NOBUILTIN: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
211+
// CHECK-NOBUILTIN: attributes [[NUW]] = { noinline nounwind{{.*}}"no-builtins"{{.*}} }
212+
208213
// PR21811: attach the appropriate attribute to the global init function
209214
// CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
210215
// CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"frame-pointer"="non-leaf"{{.*}} }

0 commit comments

Comments
 (0)