From dc042ebfe548dbf8b19ff0d896b49391f05409c5 Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Thu, 8 Mar 2018 18:48:03 +0000 Subject: [PATCH] [ThinLTO] Keep available_externally symbols live Summary: This change fixes PR36483. The bug was originally introduced by a change that marked non-prevailing symbols dead. This broke LowerTypeTests handling of available_externally functions, which are non-prevailing. LowerTypeTests uses liveness information to avoid emitting thunks for unused functions. Marking available_externally functions dead is incorrect, the functions are used though the function definitions are not. This change keeps them live, and lets the EliminateAvailableExternally/GlobalDCE passes remove them later instead. I've also enabled EliminateAvailableExternally for all optimization levels, I believe it being disabled for O1 was an oversight. Reviewers: pcc, tejohnson Reviewed By: tejohnson Subscribers: grimar, mehdi_amini, inglorion, eraman, llvm-commits Differential Revision: https://reviews.llvm.org/D43690 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327041 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/FunctionImport.cpp | 22 ++++++++++++++++--- test/ThinLTO/X86/deadstrip.ll | 9 ++++++++ .../FunctionImport/Inputs/not-prevailing.ll | 6 +++++ .../FunctionImport/not-prevailing.ll | 18 +++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 test/Transforms/FunctionImport/Inputs/not-prevailing.ll create mode 100644 test/Transforms/FunctionImport/not-prevailing.ll diff --git a/lib/Transforms/IPO/FunctionImport.cpp b/lib/Transforms/IPO/FunctionImport.cpp index b68058cbeea..c106f1105e7 100644 --- a/lib/Transforms/IPO/FunctionImport.cpp +++ b/lib/Transforms/IPO/FunctionImport.cpp @@ -544,9 +544,25 @@ void llvm::computeDeadSymbols( 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; + for (auto &S : VI.getSummaryList()) + if (S->linkage() == GlobalValue::AvailableExternallyLinkage) + AvailableExternally = true; + + if (!AvailableExternally) + return; + +#ifndef NDEBUG + for (auto &S : VI.getSummaryList()) + assert(!GlobalValue::isInterposableLinkage(S->linkage()) && + "Symbol with interposable and available_externally linkages"); +#endif + } for (auto &S : VI.getSummaryList()) S->setLive(true); diff --git a/test/ThinLTO/X86/deadstrip.ll b/test/ThinLTO/X86/deadstrip.ll index e3f16a8e0b3..827ad225eda 100644 --- a/test/ThinLTO/X86/deadstrip.ll +++ b/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 {{.*}} "Symbol with interposable and available_externally linkages"' failed + +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 +}