diff --git a/clang/test/Driver/linker-wrapper-libs.c b/clang/test/Driver/linker-wrapper-libs.c --- a/clang/test/Driver/linker-wrapper-libs.c +++ b/clang/test/Driver/linker-wrapper-libs.c @@ -64,6 +64,29 @@ // LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o // LIBRARY-GLOBAL: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.s {{.*}}.o +// +// Check that we do not extract a global symbol if the source file was not +// created by an offloading language that expects there to be a host version of +// the symbol. +// +// RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -DGLOBAL -o %t.nvptx.global.bc +// RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -DGLOBAL -o %t.amdgpu.global.bc +// RUN: clang-offload-packager -o %t-lib.out \ +// RUN: --image=file=%t.nvptx.global.bc,triple=nvptx64-nvidia-cuda,arch=sm_70 \ +// RUN: --image=file=%t.amdgpu.global.bc,triple=amdgcn-amd-amdhsa,arch=gfx1030 +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t-lib.out +// RUN: llvm-ar rcs %t.a %t.o +// RUN: clang-offload-packager -o %t.out \ +// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \ +// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx1030 +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out +// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \ +// RUN: --linker-path=/usr/bin/ld -- %t.o %t.a -o a.out 2>&1 \ +// RUN: | FileCheck %s --check-prefix=LIBRARY-GLOBAL-NONE + +// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img --target=amdgcn-amd-amdhsa -mcpu=gfx1030 {{.*}}.o {{.*}}.o +// LIBRARY-GLOBAL-NONE-NOT: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 {{.*}}.s {{.*}}.o + // // Check that we do not extract an external weak symbol. // diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1162,7 +1162,8 @@ /// Scan the symbols from a BitcodeFile \p Buffer and record if we need to /// extract any symbols from it. -Expected getSymbolsFromBitcode(MemoryBufferRef Buffer, StringSaver &Saver, +Expected getSymbolsFromBitcode(MemoryBufferRef Buffer, OffloadKind Kind, + StringSaver &Saver, DenseMap &Syms) { Expected IRSymtabOrErr = readIRSymtab(Buffer); if (!IRSymtabOrErr) @@ -1182,9 +1183,10 @@ ((OldSym & Sym_Undefined && !(OldSym & Sym_Weak)) && !Sym.isUndefined()); // We will extract if it defines a new global symbol visible to the host. + // This is only necessary for code targeting an offloading language. bool NewGlobalSymbol = ((NewSymbol || (OldSym & Sym_Undefined)) && !Sym.isUndefined() && - !Sym.canBeOmittedFromSymbolTable() && + !Sym.canBeOmittedFromSymbolTable() && Kind != object::OFK_None && (Sym.getVisibility() != GlobalValue::HiddenVisibility)); ShouldExtract |= ResolvesStrongReference | NewGlobalSymbol; @@ -1203,7 +1205,8 @@ /// Scan the symbols from an ObjectFile \p Obj and record if we need to extract /// any symbols from it. -Expected getSymbolsFromObject(const ObjectFile &Obj, StringSaver &Saver, +Expected getSymbolsFromObject(const ObjectFile &Obj, OffloadKind Kind, + StringSaver &Saver, DenseMap &Syms) { bool ShouldExtract = false; for (SymbolRef Sym : Obj.symbols()) { @@ -1228,9 +1231,11 @@ !(*FlagsOrErr & SymbolRef::SF_Undefined); // We will extract if it defines a new global symbol visible to the host. - bool NewGlobalSymbol = ((NewSymbol || (OldSym & Sym_Undefined)) && - !(*FlagsOrErr & SymbolRef::SF_Undefined) && - !(*FlagsOrErr & SymbolRef::SF_Hidden)); + // This is only necessary for code targeting an offloading language. + bool NewGlobalSymbol = + ((NewSymbol || (OldSym & Sym_Undefined)) && + !(*FlagsOrErr & SymbolRef::SF_Undefined) && Kind != object::OFK_None && + !(*FlagsOrErr & SymbolRef::SF_Hidden)); ShouldExtract |= ResolvesStrongReference | NewGlobalSymbol; // Update this symbol in the "table" with the new information. @@ -1250,18 +1255,18 @@ /// 1) It defines an undefined symbol in a regular object filie. /// 2) It defines a global symbol without hidden visibility that has not /// yet been defined. -Expected getSymbols(StringRef Image, StringSaver &Saver, +Expected getSymbols(StringRef Image, OffloadKind Kind, StringSaver &Saver, DenseMap &Syms) { MemoryBufferRef Buffer = MemoryBufferRef(Image, ""); switch (identify_magic(Image)) { case file_magic::bitcode: - return getSymbolsFromBitcode(Buffer, Saver, Syms); + return getSymbolsFromBitcode(Buffer, Kind, Saver, Syms); case file_magic::elf_relocatable: { Expected> ObjFile = ObjectFile::createObjectFile(Buffer); if (!ObjFile) return ObjFile.takeError(); - return getSymbolsFromObject(**ObjFile, Saver, Syms); + return getSymbolsFromObject(**ObjFile, Kind, Saver, Syms); } default: return false; @@ -1336,8 +1341,9 @@ if (IsArchive && !WholeArchive && !Syms.count(Binary)) continue; - Expected ExtractOrErr = - getSymbols(Binary.getBinary()->getImage(), Saver, Syms[Binary]); + Expected ExtractOrErr = getSymbols( + Binary.getBinary()->getImage(), + Binary.getBinary()->getOffloadKind(), Saver, Syms[Binary]); if (!ExtractOrErr) return ExtractOrErr.takeError();