From cb8f2ef644df255196a78c8ea6981f38e9aa6f0c Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 12 Oct 2016 09:00:06 +0000 Subject: [PATCH] LTO: Don't follow lazy references when seeing new definitions in the combined LTO object Following the lazy reference might bring in an object file that depends on bitcode files that weren't part of the LTO step. Differential Revision: https://reviews.llvm.org/D25461 llvm-svn: 283989 --- lld/COFF/SymbolTable.cpp | 12 ++++++----- .../COFF/Inputs/lto-lazy-reference-dummy.ll | 6 ++++++ .../Inputs/lto-lazy-reference-quadruple.ll | 16 ++++++++++++++ lld/test/COFF/lto-lazy-reference.ll | 21 +++++++++++++++++++ 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 lld/test/COFF/Inputs/lto-lazy-reference-dummy.ll create mode 100644 lld/test/COFF/Inputs/lto-lazy-reference-quadruple.ll create mode 100644 lld/test/COFF/lto-lazy-reference.ll diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index df9da4c36650..58c3618a0024 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -347,11 +347,13 @@ void SymbolTable::addCombinedLTOObject(ObjectFile *Obj) { Sym->Body = Body; continue; } - if (auto *L = dyn_cast(Existing)) { - // We may see new references to runtime library symbols such as __chkstk - // here. These symbols must be wholly defined in non-bitcode files. - addMemberFile(L); - continue; + if (isa(Body)) { + if (auto *L = dyn_cast(Existing)) { + // We may see new references to runtime library symbols such as __chkstk + // here. These symbols must be wholly defined in non-bitcode files. + addMemberFile(L); + continue; + } } int Comp = Existing->compare(Body); diff --git a/lld/test/COFF/Inputs/lto-lazy-reference-dummy.ll b/lld/test/COFF/Inputs/lto-lazy-reference-dummy.ll new file mode 100644 index 000000000000..0309f89c38f4 --- /dev/null +++ b/lld/test/COFF/Inputs/lto-lazy-reference-dummy.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-pc-windows-msvc18.0.0" + +define void @dummy() { + ret void +} diff --git a/lld/test/COFF/Inputs/lto-lazy-reference-quadruple.ll b/lld/test/COFF/Inputs/lto-lazy-reference-quadruple.ll new file mode 100644 index 000000000000..99c1d2bdbc5e --- /dev/null +++ b/lld/test/COFF/Inputs/lto-lazy-reference-quadruple.ll @@ -0,0 +1,16 @@ +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-pc-windows-msvc18.0.0" + +define double @quadruple(double %x) { +entry: + ; The symbol __real@40800000 is used to materialize the 4.0 constant. + %mul = fmul double %x, 4.0 + ret double %mul +} + + +declare void @dummy() +define void @f() { + call void @dummy() + ret void +} diff --git a/lld/test/COFF/lto-lazy-reference.ll b/lld/test/COFF/lto-lazy-reference.ll new file mode 100644 index 000000000000..22f953975682 --- /dev/null +++ b/lld/test/COFF/lto-lazy-reference.ll @@ -0,0 +1,21 @@ +; RUN: llc -mtriple=i686-pc-windows-msvc -filetype=obj -o %T/lto-lazy-reference-quadruple.obj %S/Inputs/lto-lazy-reference-quadruple.ll +; RUN: llvm-as -o %T/lto-lazy-reference-dummy.bc %S/Inputs/lto-lazy-reference-dummy.ll +; RUN: rm -f %t.lib +; RUN: llvm-ar cru %t.lib %T/lto-lazy-reference-quadruple.obj %T/lto-lazy-reference-dummy.bc +; RUN: llvm-as -o %t.obj %s +; RUN: lld-link /out:%t.exe /entry:main /subsystem:console %t.obj %t.lib + +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-pc-windows-msvc18.0.0" + +define double @main(double %x) { +entry: + ; When compiled, this defines the __real@40800000 symbol, which already has a + ; lazy definition in the lib file from lto-lazy-reference-quadruple.obj. This + ; test makes sure we *don't* try to take the definition from the lazy + ; reference, because that can bring in new references to bitcode files after + ; LTO, such as lto-lazy-reference-dummy.bc in this case. + %mul = fmul double %x, 4.0 + + ret double %mul +}