diff --git a/lld/test/wasm/lto/Inputs/foo.ll b/lld/test/wasm/lto/Inputs/foo.ll index f3b54cc7d0094..695b552fc6249 100644 --- a/lld/test/wasm/lto/Inputs/foo.ll +++ b/lld/test/wasm/lto/Inputs/foo.ll @@ -1,7 +1,17 @@ target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-unknown" -define void @foo() local_unnamed_addr { +define void @foo() { +entry: + ret void +} + +define void @baz() { +entry: + ret void +} + +define void @quux() { entry: ret void } diff --git a/lld/test/wasm/lto/Inputs/stub.so b/lld/test/wasm/lto/Inputs/stub.so index e76c890dbb435..c471b81da5064 100644 --- a/lld/test/wasm/lto/Inputs/stub.so +++ b/lld/test/wasm/lto/Inputs/stub.so @@ -1,3 +1,4 @@ #STUB bar: foo memcpy: foo +baz: quux diff --git a/lld/test/wasm/lto/stub-library.s b/lld/test/wasm/lto/stub-library.s index 36d6b7b3f38aa..3ad3ebb597c63 100644 --- a/lld/test/wasm/lto/stub-library.s +++ b/lld/test/wasm/lto/stub-library.s @@ -1,6 +1,10 @@ ## The function `bar` is declared in stub.so and depends on `foo` which is ## defined in an LTO object. We also test the case where the LTO object is ## with an archive file. +## The function `baz` is declared in stub.so and depends on `quux`, and both +## `baz` and `quux` are defined in an LTO object. When `baz` is DCE'd and +## becomes undefined in the LTO process, `quux` should still be preserved and +## exported. ## This verifies that stub library dependencies (which are required exports) can ## be defined in LTO objects, even when they are within archive files. @@ -40,3 +44,6 @@ _start: # CHECK-NEXT: - Name: foo # CHECK-NEXT: Kind: FUNCTION # CHECK-NEXT: Index: 2 +# CHECK-NEXT: - Name: quux +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Index: 3 diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index 97e50783985a8..6d5447be812aa 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -1028,7 +1028,11 @@ static void processStubLibrariesPreLTO() { // If the symbol is not present at all (yet), or if it is present but // undefined, then mark the dependent symbols as used by a regular // object so they will be preserved and exported by the LTO process. - if (!sym || sym->isUndefined()) { + // If the symbol is defined and in bitcode, it can be DCE'd during LTO and + // become undefined, so mark the dependent symbols as used by a regular + // object as well. + if (!sym || sym->isUndefined() || + (sym->isDefined() && isa(sym->getFile()))) { for (const auto dep : deps) { auto* needed = symtab->find(dep); if (needed ) {