Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -544,9 +544,25 @@ if (S->isLive()) return; - // We do not keep live symbols that are known to be non-prevailing. - if (isPrevailing(VI.getGUID()) == PrevailingType::No) - 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). + if (isPrevailing(VI.getGUID()) == PrevailingType::No) { + bool AvailableExternally = false; + bool Interposable = false; + for (auto &S : VI.getSummaryList()) { + if (S->linkage() == GlobalValue::AvailableExternallyLinkage) + AvailableExternally = true; + if (GlobalValue::isInterposableLinkage(S->linkage())) + Interposable = true; + } + + if (!AvailableExternally) + return; + + assert(!Interposable && "Interposable and available_externally symbol"); + } for (auto &S : VI.getSummaryList()) S->setLive(true); Index: test/ThinLTO/X86/deadstrip.ll =================================================================== --- test/ThinLTO/X86/deadstrip.ll +++ test/ThinLTO/X86/deadstrip.ll @@ -14,6 +14,7 @@ ; RUN: -r %t1.bc,_dead_func,pl \ ; RUN: -r %t1.bc,_baz,l \ ; RUN: -r %t1.bc,_boo,l \ +; RUN: -r %t1.bc,_live_available_externally_func,l \ ; RUN: -r %t2.bc,_baz,pl \ ; RUN: -r %t2.bc,_boo,pl \ ; RUN: -r %t2.bc,_dead_func,l \ @@ -27,6 +28,8 @@ ; COMBINED-DAG: &1 | FileCheck %s + +; CHECK: Assertion `!Interposable + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define available_externally i32 @foo() { + ret i32 1 +} + +define i32 @bar() { + %1 = call i32 @foo() + ret i32 %1 +}