From: Akira Hatanaka Date: Fri, 15 Jan 2016 03:34:06 +0000 (+0000) Subject: [CodeGen] Attach attributes to thread local wrapper function. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9fd2f7101b1167e44f3a6676619733466db55879;p=clang [CodeGen] Attach attributes to thread local wrapper function. This commit is a follow-up to r251734, r251476, and r249735, which fixes a bug where function attributes were not attached to thread local wrapper functions. rdar://problem/20828324 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@257865 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index e02c8dc3a8..8b6322a4b7 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -2178,17 +2178,29 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out); } + // FIXME: If VD is a definition, we should regenerate the function attributes + // before returning. if (llvm::Value *V = CGM.getModule().getNamedValue(WrapperName)) return cast(V); - llvm::Type *RetTy = Val->getType(); - if (VD->getType()->isReferenceType()) - RetTy = RetTy->getPointerElementType(); + QualType RetQT = VD->getType(); + if (RetQT->isReferenceType()) + RetQT = RetQT.getNonReferenceType(); + + const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( + getContext().getPointerType(RetQT), FunctionArgList(), + FunctionType::ExtInfo(), false); - llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false); + llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI); llvm::Function *Wrapper = llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM), WrapperName.str(), &CGM.getModule()); + + CGM.SetLLVMFunctionAttributes(nullptr, FI, Wrapper); + + if (VD->hasDefinition()) + CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper); + // Always resolve references to the wrapper at link time. if (!Wrapper->hasLocalLinkage() && !(isThreadWrapperReplaceable(VD, CGM) && !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) && @@ -2264,6 +2276,10 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs( Init = llvm::Function::Create( FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(), &CGM.getModule()); + const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration( + CGM.getContext().VoidTy, FunctionArgList(), FunctionType::ExtInfo(), + false); + CGM.SetLLVMFunctionAttributes(nullptr, FI, cast(Init)); } if (Init) diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp index 8b2ac5eed8..048a0bd45a 100644 --- a/test/CodeGenCXX/cxx11-thread-local-reference.cpp +++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp @@ -21,8 +21,8 @@ int &g() { return r; } // DARWIN: call cxx_fast_tlscc i32* @_ZTW1r() // CHECK: ret i32* %{{.*}} -// LINUX: define weak_odr hidden i32* @_ZTW1r() { -// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR:#[0-9]+]] { +// LINUX: define weak_odr hidden i32* @_ZTW1r() [[ATTR0:#[0-9]+]] { +// DARWIN: define cxx_fast_tlscc i32* @_ZTW1r() [[ATTR1:#[0-9]+]] { // CHECK: call void @_ZTH1r() // CHECK: load i32*, i32** @r, align 8 // CHECK: ret i32* %{{.*}} @@ -30,4 +30,5 @@ int &g() { return r; } // CHECK-LABEL: define internal void @__tls_init() // CHECK: call void @[[R_INIT]]() -// DARWIN: attributes [[ATTR]] = { nounwind } +// LINUX: attributes [[ATTR0]] = { {{.*}}"target-features"{{.*}} } +// DARWIN: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}}"target-features"{{.*}} } diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp index b5bcc5e23e..40f33e0848 100644 --- a/test/CodeGenCXX/cxx11-thread-local.cpp +++ b/test/CodeGenCXX/cxx11-thread-local.cpp @@ -217,7 +217,7 @@ void set_anon_i() { // CHECK: } -// LINUX: declare extern_weak void @_ZTH1b() +// LINUX: declare extern_weak void @_ZTH1b() [[ATTR:#[0-9]+]] // LINUX-LABEL: define internal i32* @_ZTWL1d() @@ -229,3 +229,5 @@ void set_anon_i() { // DARWIN-LABEL: define cxx_fast_tlscc i32* @_ZTWN1U1mE() // CHECK: call void @_ZTHN1U1mE() // CHECK: ret i32* @_ZN1U1mE + +// LINUX: attributes [[ATTR]] = { {{.+}} } diff --git a/test/OpenMP/threadprivate_codegen.cpp b/test/OpenMP/threadprivate_codegen.cpp index 53d7ef7083..793f6c5808 100644 --- a/test/OpenMP/threadprivate_codegen.cpp +++ b/test/OpenMP/threadprivate_codegen.cpp @@ -617,7 +617,7 @@ int main() { // CHECK-DEBUG: call {{.*}} [[SMAIN_DTOR:@.+]]([[SMAIN]]* // CHECK-DEBUG: } // CHECK-DEBUG: define {{.*}} [[SMAIN_DTOR]]([[SMAIN]]* {{.*}}) -// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] { +// CHECK-TLS: define internal [[S1]]* [[GS1_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS-NEXT: call void [[GS1_TLS_INIT]] // CHECK-TLS-NEXT: ret [[S1]]* [[GS1]] // CHECK-TLS-NEXT: } @@ -639,15 +639,15 @@ int main() { // CHECK-TLS: call void [[ARR_X_TLS_INIT]] // CHECK-TLS: ret [2 x [3 x [[S1]]]]* [[ARR_X]] // CHECK-TLS: } -// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] { +// CHECK-TLS: define {{.*}} i32* [[ST_INT_ST_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS: call void [[ST_INT_ST_TLS_INIT]] // CHECK-TLS: ret i32* [[ST_INT_ST]] // CHECK-TLS: } -// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] { +// CHECK-TLS: define {{.*}} float* [[ST_FLOAT_ST_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS: call void [[ST_FLOAT_ST_TLS_INIT]] // CHECK-TLS: ret float* [[ST_FLOAT_ST]] // CHECK-TLS: } -// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] { +// CHECK-TLS: define {{.*}} [[S4]]* [[ST_S4_ST_TLS_INITD]] {{#[0-9]+}} { // CHECK-TLS: call void [[ST_S4_ST_TLS_INIT]] // CHECK-TLS: ret [[S4]]* [[ST_S4_ST]] // CHECK-TLS: }