From a0222ac1f9c20d513caed09557d5ef83574f453c Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Fri, 3 Apr 2020 13:29:14 -0700 Subject: [PATCH] [AsmPrinter] Do not define local aliases for global objects in a comdat A global symbol that is defined in a comdat should not generate an alias since call sites that would've referred to that symbol will refer to their own independent local aliases rather than the surviving global comdat one. This could result in something that looks like: ``` ld.lld: error: relocation refers to a discarded section: .text._ZN3fbl8internal18NullFunctionTargetIvJjjPjEED1Ev.stub >>> defined in user-x64-clang/obj/system/ulib/minfs/libminfs.a(minfs._sources.file.cc.o) >>> section group signature: _ZN3fbl8internal18NullFunctionTargetIvJjjPjEED1Ev.stub >>> prevailing definition is in user-x64-clang/obj/system/ulib/minfs/libminfs.a(minfs._sources.vnode.cc.o) >>> referenced by function.h:169 (../../zircon/system/ulib/fbl/include/fbl/function.h:169) >>> minfs._sources.file.cc.o:(minfs::File::AllocateAndCommitData(std::__2::unique_ptr >)) in archive user-x64-clang/obj/system/ulib/minfs/libminfs.a ``` We ran into this when experimenting with a new C++ ABI for fuchsia (refer to D72959) which takes relative offsets between comdat'd functions which is why the normal C++ user wouldn't run into this. Differential Revision: https://reviews.llvm.org/D77429 --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +- .../CodeGen/X86/semantic-interposition-comdat.ll | 23 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/X86/semantic-interposition-comdat.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 8c51203..395746d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -460,7 +460,7 @@ MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const { // assumed it. if (TM.getTargetTriple().isOSBinFormatELF() && GlobalObject::isExternalLinkage(GV.getLinkage()) && GV.isDSOLocal() && - !GV.isDeclaration() && !isa(GV)) + !GV.isDeclaration() && !isa(GV) && !GV.hasComdat()) return getSymbolWithGlobalValueBase(&GV, "$local"); return TM.getSymbol(&GV); } diff --git a/llvm/test/CodeGen/X86/semantic-interposition-comdat.ll b/llvm/test/CodeGen/X86/semantic-interposition-comdat.ll new file mode 100644 index 0000000..0657405 --- /dev/null +++ b/llvm/test/CodeGen/X86/semantic-interposition-comdat.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple x86_64-unknown-linux-gnu %s -o - | FileCheck %s + +$comdat_func = comdat any + +; CHECK-LABEL: func2: +; CHECK-NEXT: .Lfunc2$local + +declare void @func() + +define hidden void @func2() { +entry: + call void @func() + ret void +} + +; CHECK: comdat_func: +; CHECK-NOT: .Lcomdat_func$local + +define hidden void @comdat_func() comdat { +entry: + call void @func() + ret void +} -- 2.7.4