From 2c719cc11781bba190687b3a68fea88d88e2fef8 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Wed, 20 Apr 2016 04:17:36 +0000 Subject: [PATCH] FunctionImport: make sure we always select the right callee in presence of alias From: Mehdi Amini llvm-svn: 266854 --- llvm/lib/Transforms/IPO/FunctionImport.cpp | 30 ++++++++++++---------- .../X86/Inputs/select_right_alias_definition1.ll | 6 +++++ .../X86/Inputs/select_right_alias_definition2.ll | 7 +++++ .../ThinLTO/X86/select_right_alias_definition.ll | 27 +++++++++++++++++++ 4 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition1.ll create mode 100644 llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition2.ll create mode 100644 llvm/test/ThinLTO/X86/select_right_alias_definition.ll diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index eef7385..9d7d78a 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -86,12 +86,21 @@ selectCallee(const GlobalValueInfoList &CalleeInfoList, unsigned Threshold) { assert(GlobInfo->summary() && "We should not have a Global Info without summary"); auto *GVSummary = GlobInfo->summary(); - if (auto *AS = dyn_cast(GVSummary)) + if (GlobalValue::isWeakAnyLinkage(GVSummary->linkage())) + // There is no point in importing weak symbols, we can't inline them + return false; + if (auto *AS = dyn_cast(GVSummary)) { GVSummary = &AS->getAliasee(); - auto *Summary = cast(GVSummary); + // Alias can't point to "available_externally". However when we import + // linkOnceODR the linkage does not change. So we import the alias + // and aliasee only in this case. + // FIXME: we should import alias as available_externally *function*, + // the destination module does need to know it is an alias. + if (!GlobalValue::isLinkOnceODRLinkage(GVSummary->linkage())) + return false; + } - if (GlobalValue::isWeakAnyLinkage(Summary->linkage())) - return false; + auto *Summary = cast(GVSummary); if (Summary->instCount() > Threshold) return false; @@ -166,16 +175,9 @@ static void computeImportForFunction( if (isa(CalleeSummary)) { ResolvedCalleeSummary = cast( &cast(CalleeSummary)->getAliasee()); - if (!GlobalValue::isLinkOnceODRLinkage( - ResolvedCalleeSummary->linkage())) { - // Alias can't point to "available_externally". However when we import - // linkOnceODR the linkage does not change. So we import the alias - // and aliasee only in this case. - // FIXME: we should import alias as available_externally *function*, the - // destination module does need to know it is an alias. - DEBUG(dbgs() << "ignored! Aliasee is not linkonce_odr.\n"); - continue; - } + assert( + GlobalValue::isLinkOnceODRLinkage(ResolvedCalleeSummary->linkage()) && + "Unexpected alias to a non-linkonceODR in import list"); } else ResolvedCalleeSummary = cast(CalleeSummary); diff --git a/llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition1.ll b/llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition1.ll new file mode 100644 index 0000000..cc19b03 --- /dev/null +++ b/llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition1.ll @@ -0,0 +1,6 @@ + +@foo = weak alias i32 (...), bitcast (i32 ()* @foo1 to i32 (...)*) + +define i32 @foo1() { + ret i32 42 +} \ No newline at end of file diff --git a/llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition2.ll b/llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition2.ll new file mode 100644 index 0000000..9c5c038 --- /dev/null +++ b/llvm/test/ThinLTO/X86/Inputs/select_right_alias_definition2.ll @@ -0,0 +1,7 @@ + +@foo = alias i32 (...), bitcast (i32 ()* @foo2 to i32 (...)*) + +define linkonce_odr i32 @foo2() { + %ret = add i32 42, 42 + ret i32 %ret +} \ No newline at end of file diff --git a/llvm/test/ThinLTO/X86/select_right_alias_definition.ll b/llvm/test/ThinLTO/X86/select_right_alias_definition.ll new file mode 100644 index 0000000..48ae4cf --- /dev/null +++ b/llvm/test/ThinLTO/X86/select_right_alias_definition.ll @@ -0,0 +1,27 @@ +; RUN: opt -module-summary %s -o %t_main.bc +; RUN: opt -module-summary %p/Inputs/select_right_alias_definition1.ll -o %t1.bc +; RUN: opt -module-summary %p/Inputs/select_right_alias_definition2.ll -o %t2.bc + +; Make sure that we always select the right definition for alia foo, whatever +; order the files are linked in. + +; Try with one order +; RUN: llvm-lto -thinlto-action=thinlink -o %t.index1.bc %t_main.bc %t1.bc %t2.bc +; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index1.bc %t_main.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT + +; Try with the other order (reversing %t1.bc and %t2.bc) +; RUN: llvm-lto -thinlto-action=thinlink -o %t.index2.bc %t_main.bc %t2.bc %t1.bc +; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index2.bc %t_main.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT + +; IMPORT: @foo = alias i32 (...), bitcast (i32 ()* @foo2 to i32 (...)*) +; IMPORT: define linkonce_odr i32 @foo2() { +; IMPORT-NEXT: %ret = add i32 42, 42 +; IMPORT-NEXT: ret i32 %ret +; IMPORT-NEXT: } + +declare i32 @foo() + +define i32 @main() { + %ret = call i32 @foo() + ret i32 %ret +} \ No newline at end of file -- 2.7.4