Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -5912,6 +5912,7 @@ if (CGM.getLangOpts().OpenMPIsDevice) { OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.Int8PtrTy); OutlinedFn->setLinkage(llvm::GlobalValue::ExternalLinkage); + OutlinedFn->setDSOLocal(false); } else OutlinedFnID = new llvm::GlobalVariable( CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true, Index: clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp =================================================================== --- clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp +++ clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -28,11 +28,11 @@ // See @llvm.global_ctors above. __declspec(selectany) S selectany1; __declspec(selectany) S selectany2; -// CHECK: define linkonce_odr void @"\01??__Eselectany1@@YAXXZ"() {{.*}} comdat +// CHECK: define linkonce_odr dso_local void @"\01??__Eselectany1@@YAXXZ"() {{.*}} comdat // CHECK-NOT: @"\01??_Bselectany1 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" // CHECK: ret void -// CHECK: define linkonce_odr void @"\01??__Eselectany2@@YAXXZ"() {{.*}} comdat +// CHECK: define linkonce_odr dso_local void @"\01??__Eselectany2@@YAXXZ"() {{.*}} comdat // CHECK-NOT: @"\01??_Bselectany2 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" // CHECK: ret void @@ -231,7 +231,7 @@ DynamicDLLImportInitVSMangling::switch_test3(); } -// CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"() {{.*}} comdat +// CHECK: define linkonce_odr dso_local void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"() {{.*}} comdat // CHECK-NOT: and // CHECK-NOT: ?_Bfoo@ // CHECK: call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" Index: clang/test/OpenMP/target_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_codegen_registration.cpp +++ clang/test/OpenMP/target_codegen_registration.cpp @@ -393,7 +393,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: clang/test/OpenMP/target_parallel_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_parallel_codegen_registration.cpp +++ clang/test/OpenMP/target_parallel_codegen_registration.cpp @@ -393,7 +393,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: clang/test/OpenMP/target_parallel_for_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_parallel_for_codegen_registration.cpp +++ clang/test/OpenMP/target_parallel_for_codegen_registration.cpp @@ -402,7 +402,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: clang/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp +++ clang/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp @@ -402,7 +402,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: clang/test/OpenMP/target_simd_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_simd_codegen_registration.cpp +++ clang/test/OpenMP/target_simd_codegen_registration.cpp @@ -402,7 +402,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: clang/test/OpenMP/target_teams_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_teams_codegen_registration.cpp +++ clang/test/OpenMP/target_teams_codegen_registration.cpp @@ -393,7 +393,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: clang/test/OpenMP/target_teams_distribute_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_teams_distribute_codegen_registration.cpp +++ clang/test/OpenMP/target_teams_distribute_codegen_registration.cpp @@ -402,7 +402,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: clang/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp =================================================================== --- clang/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp +++ clang/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp @@ -402,7 +402,7 @@ //CHECK: ret void //CHECK: declare i32 @__tgt_unregister_lib([[DSCTY]]*) -//CHECK: define linkonce hidden void @[[REGFN]](i8*) +//CHECK: define linkonce dso_local hidden void @[[REGFN]](i8*) //CHECK-SAME: comdat { //CHECK: call i32 @__tgt_register_lib([[DSCTY]]* [[DESC]]) //CHECK: call i32 @__cxa_atexit(void (i8*)* @[[UNREGFN]], i8* bitcast ([[DSCTY]]* [[DESC]] to i8*), Index: llvm/include/llvm/IR/GlobalValue.h =================================================================== --- llvm/include/llvm/IR/GlobalValue.h +++ llvm/include/llvm/IR/GlobalValue.h @@ -77,11 +77,12 @@ GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace) : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps), - ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility), + ValueType(Ty), Visibility(DefaultVisibility), UnnamedAddrVal(unsigned(UnnamedAddr::None)), DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal), - HasLLVMReservedName(false), IsDSOLocal(false), - IntID((Intrinsic::ID)0U), Parent(nullptr) { + HasLLVMReservedName(false), IsDSOLocal(false), IntID((Intrinsic::ID)0U), + Parent(nullptr) { + setLinkage(Linkage); setName(Name); } @@ -434,8 +435,11 @@ } void setLinkage(LinkageTypes LT) { - if (isLocalLinkage(LT)) + if (isLocalLinkage(LT)) { Visibility = DefaultVisibility; + if (getValueID() != Value::GlobalIFuncVal) + setDSOLocal(true); + } Linkage = LT; } LinkageTypes getLinkage() const { return LinkageTypes(Linkage); } Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -826,7 +826,8 @@ GA->setVisibility((GlobalValue::VisibilityTypes)Visibility); GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); GA->setUnnamedAddr(UnnamedAddr); - GA->setDSOLocal(DSOLocal); + if (DSOLocal) + GA->setDSOLocal(true); if (Name.empty()) NumberedVals.push_back(GA.get()); @@ -947,7 +948,8 @@ GV->setInitializer(Init); GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); - GV->setDSOLocal(DSOLocal); + if (DSOLocal) + GV->setDSOLocal(true); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); GV->setExternallyInitialized(IsExternallyInitialized); @@ -4923,7 +4925,8 @@ NumberedVals.push_back(Fn); Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); - Fn->setDSOLocal(DSOLocal); + if (DSOLocal) + Fn->setDSOLocal(true); Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); Fn->setCallingConv(CC); Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -2497,8 +2497,10 @@ } } -static void PrintDSOLocation(bool IsDSOLocal, formatted_raw_ostream &Out){ - if (IsDSOLocal) +static void PrintDSOLocation(const GlobalValue &GV, + formatted_raw_ostream &Out) { + // GVs with local linkage are implicitly dso_local, so we don't print it. + if (GV.isDSOLocal() && !GV.hasLocalLinkage()) Out << "dso_local "; } @@ -2572,7 +2574,7 @@ Out << "external "; Out << getLinkagePrintName(GV->getLinkage()); - PrintDSOLocation(GV->isDSOLocal(), Out); + PrintDSOLocation(*GV, Out); PrintVisibility(GV->getVisibility(), Out); PrintDLLStorageClass(GV->getDLLStorageClass(), Out); PrintThreadLocalModel(GV->getThreadLocalMode(), Out); @@ -2619,7 +2621,7 @@ Out << " = "; Out << getLinkagePrintName(GIS->getLinkage()); - PrintDSOLocation(GIS->isDSOLocal(), Out); + PrintDSOLocation(*GIS, Out); PrintVisibility(GIS->getVisibility(), Out); PrintDLLStorageClass(GIS->getDLLStorageClass(), Out); PrintThreadLocalModel(GIS->getThreadLocalMode(), Out); @@ -2731,7 +2733,7 @@ Out << "define "; Out << getLinkagePrintName(F->getLinkage()); - PrintDSOLocation(F->isDSOLocal(), Out); + PrintDSOLocation(*F, Out); PrintVisibility(F->getVisibility(), Out); PrintDLLStorageClass(F->getDLLStorageClass(), Out); Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -569,6 +569,11 @@ Assert(!GV.isDSOLocal(), "GlobalValue with DLLImport Storage is dso_local!", &GV); + if (GV.hasLocalLinkage()) + Assert(GV.isDSOLocal(), + "GlobalValue with private or internal linkage must be dso_local!", + &GV); + forEachUser(&GV, GlobalValueVisited, [&](const Value *V) -> bool { if (const Instruction *I = dyn_cast(V)) { if (!I->getParent() || !I->getParent()->getParent()) Index: llvm/lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -265,6 +265,7 @@ SmallVector Returns; CloneFunctionInto(NewF, &F, VMap, /*ModuleLevelChanges=*/true, Returns); + NewF->setDSOLocal(true); // Remove old returns. for (ReturnInst *Return : Returns) Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -2486,6 +2486,7 @@ // Give the aliasee the name, linkage and other attributes of the alias. Target->takeName(&*J); Target->setLinkage(J->getLinkage()); + Target->setDSOLocal(J->isDSOLocal()); Target->setVisibility(J->getVisibility()); Target->setDLLStorageClass(J->getDLLStorageClass()); Index: llvm/test/Bitcode/thinlto-function-summary-refgraph.ll =================================================================== --- llvm/test/Bitcode/thinlto-function-summary-refgraph.ll +++ llvm/test/Bitcode/thinlto-function-summary-refgraph.ll @@ -50,7 +50,7 @@ ; a reference to it when reached while earlier analyzing the phi using its ; return value: ; op0=Y op4=func2 -; CHECK-DAG: +; CHECK-DAG: ; Function Z contains call to func2, and ensures we don't incorrectly add ; a reference to it when reached while analyzing subsequent use of its return ; value: Index: llvm/test/Bitcode/thinlto-summary-linkage-types.ll =================================================================== --- llvm/test/Bitcode/thinlto-summary-linkage-types.ll +++ llvm/test/Bitcode/thinlto-summary-linkage-types.ll @@ -5,8 +5,8 @@ ; RUN: llvm-bcanalyzer -dump %t2.thinlto.bc | FileCheck %s --check-prefix=COMBINED define private void @private() -; CHECK: %arg) #0 !kernel_arg_addr_space !14 !kernel_arg_access_qual !15 !kernel_arg_type !16 !kernel_arg_base_type !16 !kernel_arg_type_qual !17 { entry: @@ -77,7 +77,7 @@ declare i32 @__enqueue_kernel_basic(%opencl.queue_t addrspace(1)*, i32, %struct.ndrange_t*, i8 addrspace(4)*) local_unnamed_addr -; CHECK: define amdgpu_kernel void @__test_block_invoke_2_kernel({{.*}}) #[[AT2:[0-9]+]] +; CHECK: define dso_local amdgpu_kernel void @__test_block_invoke_2_kernel({{.*}}) #[[AT2:[0-9]+]] define internal amdgpu_kernel void @__test_block_invoke_2_kernel(<{ i32, i32, i8 addrspace(4)*, i8 addrspace(1)*, i64 addrspace(1)*, i64, i8 }> %arg) #0 !kernel_arg_addr_space !14 !kernel_arg_access_qual !15 !kernel_arg_type !16 !kernel_arg_base_type !16 !kernel_arg_type_qual !17 { Index: llvm/test/LTO/Resolution/X86/comdat.ll =================================================================== --- llvm/test/LTO/Resolution/X86/comdat.ll +++ llvm/test/LTO/Resolution/X86/comdat.ll @@ -77,7 +77,7 @@ ; CHECK-NEXT: ret i32 42 ; CHECK-NEXT: } -; CHECK: define internal dso_local i32 @f1.2(i8* %this) comdat($c2) { +; CHECK: define internal i32 @f1.2(i8* %this) comdat($c2) { ; CHECK-NEXT: bb20: ; CHECK-NEXT: store i8* %this, i8** null ; CHECK-NEXT: br label %bb21 Index: llvm/test/Linker/funcimport.ll =================================================================== --- llvm/test/Linker/funcimport.ll +++ llvm/test/Linker/funcimport.ll @@ -13,12 +13,12 @@ ; Ensure statics are promoted/renamed correctly from this file (all but ; constant variable need promotion). ; RUN: llvm-link %t.bc -summary-index=%t3.thinlto.bc -S | FileCheck %s --check-prefix=EXPORTSTATIC -; EXPORTSTATIC-DAG: @staticvar.llvm.{{.*}} = hidden global +; EXPORTSTATIC-DAG: @staticvar.llvm.{{.*}} = dso_local hidden global ; Eventually @staticconstvar can be exported as a copy and not promoted -; EXPORTSTATIC-DAG: @staticconstvar.llvm.0 = hidden unnamed_addr constant -; EXPORTSTATIC-DAG: @P.llvm.{{.*}} = hidden global void ()* null -; EXPORTSTATIC-DAG: define hidden i32 @staticfunc.llvm. -; EXPORTSTATIC-DAG: define hidden void @staticfunc2.llvm. +; EXPORTSTATIC-DAG: @staticconstvar.llvm.0 = dso_local hidden unnamed_addr constant +; EXPORTSTATIC-DAG: @P.llvm.{{.*}} = dso_local hidden global void ()* null +; EXPORTSTATIC-DAG: define dso_local hidden i32 @staticfunc.llvm. +; EXPORTSTATIC-DAG: define dso_local hidden void @staticfunc2.llvm. ; Ensure that both weak alias to an imported function and strong alias to a ; non-imported function are correctly turned into declarations. @@ -67,13 +67,13 @@ ; Ensure that imported static variable and function references are correctly ; promoted and renamed (including static constant variable). ; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=referencestatics:%t.bc -S | FileCheck %s --check-prefix=IMPORTSTATIC -; IMPORTSTATIC-DAG: @staticvar.llvm.{{.*}} = external hidden global +; IMPORTSTATIC-DAG: @staticvar.llvm.{{.*}} = external dso_local hidden global ; Eventually @staticconstvar can be imported as a copy -; IMPORTSTATIC-DAG: @staticconstvar.llvm.{{.*}} = external hidden unnamed_addr constant +; IMPORTSTATIC-DAG: @staticconstvar.llvm.{{.*}} = external dso_local hidden unnamed_addr constant ; IMPORTSTATIC-DAG: define available_externally i32 @referencestatics ; IMPORTSTATIC-DAG: %call = call i32 @staticfunc.llvm. ; IMPORTSTATIC-DAG: %0 = load i32, i32* @staticvar.llvm. -; IMPORTSTATIC-DAG: declare hidden i32 @staticfunc.llvm. +; IMPORTSTATIC-DAG: declare dso_local hidden i32 @staticfunc.llvm. ; Ensure that imported global (external) function and variable references ; are handled correctly (including referenced variable imported as @@ -90,7 +90,7 @@ ; Ensure that imported static function pointer correctly promoted and renamed. ; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=callfuncptr:%t.bc -S | FileCheck %s --check-prefix=IMPORTFUNCPTR -; IMPORTFUNCPTR-DAG: @P.llvm.{{.*}} = external hidden global void ()* +; IMPORTFUNCPTR-DAG: @P.llvm.{{.*}} = external dso_local hidden global void ()* ; IMPORTFUNCPTR-DAG: define available_externally void @callfuncptr ; IMPORTFUNCPTR-DAG: %0 = load void ()*, void ()** @P.llvm. Index: llvm/test/Other/extract.ll =================================================================== --- llvm/test/Other/extract.ll +++ llvm/test/Other/extract.ll @@ -7,13 +7,13 @@ ; llvm-extract uses lazy bitcode loading, so make sure it correctly reads ; from bitcode files in addition to assembly files. -; CHECK: define hidden void @foo() comdat($x) { +; CHECK: define dso_local hidden void @foo() comdat($x) { ; CHECK: ret void ; CHECK: } ; The private linkage for foo() should be changed to external linkage and ; hidden visibility added. -; DELETE: declare hidden void @foo() +; DELETE: declare dso_local hidden void @foo() ; DELETE-NOT: comdat ; DELETE: define void @bar() { ; DELETE: call void @foo() Index: llvm/test/ThinLTO/X86/alias_import.ll =================================================================== --- llvm/test/ThinLTO/X86/alias_import.ll +++ llvm/test/ThinLTO/X86/alias_import.ll @@ -57,11 +57,11 @@ ; IMPORT-DAG: declare void @globalfuncLinkonceAlias() ; IMPORT-DAG: define available_externally void @globalfuncWeakODRAlias() ; IMPORT-DAG: define available_externally void @globalfuncLinkonceODRAlias() -; IMPORT-DAG: define available_externally void @internalfuncAlias() +; IMPORT-DAG: define available_externally dso_local void @internalfuncAlias() ; IMPORT-DAG: declare void @internalfuncWeakAlias() ; IMPORT-DAG: declare void @internalfuncLinkonceAlias() -; IMPORT-DAG: define available_externally void @internalfuncWeakODRAlias() -; IMPORT-DAG: define available_externally void @internalfuncLinkonceODRAlias() +; IMPORT-DAG: define available_externally dso_local void @internalfuncWeakODRAlias() +; IMPORT-DAG: define available_externally dso_local void @internalfuncLinkonceODRAlias() ; IMPORT-DAG: define available_externally void @weakODRfuncAlias() ; IMPORT-DAG: declare void @weakODRfuncWeakAlias() ; IMPORT-DAG: declare void @weakODRfuncLinkonceAlias() Index: llvm/test/ThinLTO/X86/deadstrip.ll =================================================================== --- llvm/test/ThinLTO/X86/deadstrip.ll +++ llvm/test/ThinLTO/X86/deadstrip.ll @@ -23,10 +23,10 @@ ; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK2-NM ; RUN: llvm-bcanalyzer -dump %t.out.index.bc | FileCheck %s --check-prefix=COMBINED -; Live, NotEligibleForImport, Internal -; COMBINED-DAG: