Index: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp +++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp @@ -741,24 +741,28 @@ return; // We only keep live symbols that are known to be non-prevailing if any are - // available_externally. Those symbols are discarded later in the - // EliminateAvailableExternally pass and setting them to not-live breaks - // downstreams users of liveness information (PR36483). + // available_externally, linkonceodr, weakodr. Those symbols are discarded + // later in the EliminateAvailableExternally pass and setting them to + // not-live could break downstreams users of liveness information (PR36483) + // or limit optimization opportunities. if (isPrevailing(VI.getGUID()) == PrevailingType::No) { - bool AvailableExternally = false; + bool KeepAliveLinkage = false; bool Interposable = false; for (auto &S : VI.getSummaryList()) { - if (S->linkage() == GlobalValue::AvailableExternallyLinkage) - AvailableExternally = true; + if (S->linkage() == GlobalValue::AvailableExternallyLinkage || + S->linkage() == GlobalValue::WeakODRLinkage || + S->linkage() == GlobalValue::LinkOnceODRLinkage) + KeepAliveLinkage = true; else if (GlobalValue::isInterposableLinkage(S->linkage())) Interposable = true; } - if (!AvailableExternally) + if (!KeepAliveLinkage) return; if (Interposable) - report_fatal_error("Interposable and available_externally symbol"); + report_fatal_error( + "Interposable and available_externally/linkonce_odr/weak_odr symbol"); } for (auto &S : VI.getSummaryList()) Index: llvm/trunk/test/LTO/Resolution/X86/cache-prevailing.ll =================================================================== --- llvm/trunk/test/LTO/Resolution/X86/cache-prevailing.ll +++ llvm/trunk/test/LTO/Resolution/X86/cache-prevailing.ll @@ -10,7 +10,7 @@ target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc19.11.0" -@foo = linkonce_odr constant i32 1, comdat +@foo = linkonce constant i32 1, comdat $foo = comdat any define i32* @bar() { Index: llvm/trunk/test/ThinLTO/X86/deadstrip.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/deadstrip.ll +++ llvm/trunk/test/ThinLTO/X86/deadstrip.ll @@ -18,6 +18,8 @@ ; RUN: -r %t1.bc,_baz,l \ ; RUN: -r %t1.bc,_boo,l \ ; RUN: -r %t1.bc,_live_available_externally_func,l \ +; RUN: -r %t1.bc,_live_linkonce_odr_func,l \ +; RUN: -r %t1.bc,_live_weak_odr_func,l \ ; RUN: -r %t2.bc,_baz,pl \ ; RUN: -r %t2.bc,_boo,pl \ ; RUN: -r %t2.bc,_dead_func,l \ @@ -33,12 +35,16 @@ ; COMBINED-DAG: &1 | FileCheck %s -; CHECK: Interposable and available_externally symbol +; CHECK: Interposable and available_externally/linkonce_odr/weak_odr symbol target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu"