diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h index b4f7c350739a..18f1637deb50 100644 --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -322,9 +322,10 @@ protected: /// symbol that can be hidden (unexported). Defaults to false. bool HasWeakDefCanBeHiddenDirective = false; - /// True if we have a .linkonce directive. This is used on cygwin/mingw. + /// True if we should mark symbols as global instead of weak, for + /// weak*/linkonce*, if the symbol has a comdat. /// Defaults to false. - bool HasLinkOnceDirective = false; + bool AvoidWeakIfComdat = false; /// True if we have a .lglobl directive, which is used to emit the information /// of a static symbol into the symbol table. Defaults to false. @@ -590,7 +591,7 @@ public: return HasWeakDefCanBeHiddenDirective; } - bool hasLinkOnceDirective() const { return HasLinkOnceDirective; } + bool avoidWeakIfComdat() const { return AvoidWeakIfComdat; } bool hasDotLGloblDirective() const { return HasDotLGloblDirective; } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index a75f16b796d0..6d96205c615f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -414,7 +414,7 @@ void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefinition); else OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate); - } else if (MAI->hasLinkOnceDirective()) { + } else if (MAI->avoidWeakIfComdat() && GV->hasComdat()) { // .globl _foo OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global); //NOTE: linkonce is handled by the section the symbol was assigned to. diff --git a/llvm/lib/MC/MCAsmInfoCOFF.cpp b/llvm/lib/MC/MCAsmInfoCOFF.cpp index 9f19d163f57b..d9971028649c 100644 --- a/llvm/lib/MC/MCAsmInfoCOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoCOFF.cpp @@ -26,7 +26,7 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() { HasDotTypeDotSizeDirective = false; HasSingleParameterDotFile = true; WeakRefDirective = "\t.weak\t"; - HasLinkOnceDirective = true; + AvoidWeakIfComdat = true; // Doesn't support visibility: HiddenVisibilityAttr = HiddenDeclarationVisibilityAttr = MCSA_Invalid; diff --git a/llvm/test/CodeGen/X86/coff-linkonce.ll b/llvm/test/CodeGen/X86/coff-linkonce.ll new file mode 100644 index 000000000000..369750147f29 --- /dev/null +++ b/llvm/test/CodeGen/X86/coff-linkonce.ll @@ -0,0 +1,9 @@ +; RUN: llc -function-sections -o - %s | FileCheck %s + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +; CHECK: .section{{.*}}one_only +define linkonce_odr void @foo() { + ret void +} diff --git a/llvm/test/CodeGen/X86/coff-weak.ll b/llvm/test/CodeGen/X86/coff-weak.ll index 369750147f29..485e8f6a3847 100644 --- a/llvm/test/CodeGen/X86/coff-weak.ll +++ b/llvm/test/CodeGen/X86/coff-weak.ll @@ -1,9 +1,50 @@ -; RUN: llc -function-sections -o - %s | FileCheck %s +; RUN: llc -mtriple=i686-windows-msvc -o - %s | FileCheck -check-prefix=X86 %s +; RUN: llc -mtriple=x86_64-windows-msvc -o - %s | FileCheck -check-prefix=X64 %s -target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-pc-windows-msvc" - -; CHECK: .section{{.*}}one_only -define linkonce_odr void @foo() { +; X86: .weak _foo +; X64: .weak foo +define weak void @foo() { + ret void +} + +; X86: .weak _bar +; X64: .weak bar +define weak_odr void @bar() { + ret void +} + +; X86-NOT: .weak _bar_comdat +; X64-NOT: .weak bar_comdat +$bar_comdat = comdat any + +define weak_odr void @bar_comdat() comdat { + ret void +} + +; X86: .weak _baz +; X64: .weak baz +define linkonce void @baz() { + ret void +} + +; X86-NOT: .weak _baz_comdat +; X64-NOT: .weak baz_comdat +$baz_comdat = comdat any + +define linkonce void @baz_comdat() comdat { + ret void +} + +; X86: .weak _quux +; X64: .weak quux +define linkonce_odr void @quux() { + ret void +} + +; X86-NOT: .weak _quux_comdat +; X64-NOT: .weak quux_comdat +$quux_comdat = comdat any + +define linkonce_odr void @quux_comdat() comdat { ret void } diff --git a/llvm/test/CodeGen/X86/dllexport-x86_64.ll b/llvm/test/CodeGen/X86/dllexport-x86_64.ll index a2825bc0458a..9f427f60e623 100644 --- a/llvm/test/CodeGen/X86/dllexport-x86_64.ll +++ b/llvm/test/CodeGen/X86/dllexport-x86_64.ll @@ -20,16 +20,20 @@ define dllexport void @f2() unnamed_addr { } ; CHECK: .globl lnk1 -define linkonce_odr dllexport void @lnk1() { +$lnk1 = comdat any + +define linkonce_odr dllexport void @lnk1() comdat { ret void } ; CHECK: .globl lnk2 -define linkonce_odr dllexport void @lnk2() alwaysinline { +$lnk2 = comdat any + +define linkonce_odr dllexport void @lnk2() alwaysinline comdat { ret void } -; CHECK: .globl weak1 +; CHECK: .weak weak1 define weak_odr dllexport void @weak1() { ret void } @@ -46,14 +50,14 @@ define weak_odr dllexport void @weak1() { ; CHECK: .comm Var3 @Var3 = common dllexport global i32 0, align 4 -; CHECK: .globl WeakVar1 +; CHECK: .weak WeakVar1 @WeakVar1 = weak_odr dllexport global i32 1, align 4 -; CHECK: .globl WeakVar2 +; CHECK: .weak WeakVar2 @WeakVar2 = weak_odr dllexport unnamed_addr constant i32 1 ; CHECK: .bss -; CHECK: .globl WeakVar3 +; CHECK: .weak WeakVar3 @WeakVar3 = weak_odr dllexport global i32 0, align 4 diff --git a/llvm/test/CodeGen/X86/dllexport.ll b/llvm/test/CodeGen/X86/dllexport.ll index 999733949ab2..f08395a8d3be 100644 --- a/llvm/test/CodeGen/X86/dllexport.ll +++ b/llvm/test/CodeGen/X86/dllexport.ll @@ -45,16 +45,20 @@ define dllexport x86_thiscallcc void @thisfun() nounwind { } ; CHECK: .globl _lnk1 -define linkonce_odr dllexport void @lnk1() { +$lnk1 = comdat any + +define linkonce_odr dllexport void @lnk1() comdat { ret void } ; CHECK: .globl _lnk2 -define linkonce_odr dllexport void @lnk2() alwaysinline { +$lnk2 = comdat any + +define linkonce_odr dllexport void @lnk2() alwaysinline comdat { ret void } -; CHECK: .globl _weak1 +; CHECK: .weak _weak1 define weak_odr dllexport void @weak1() { ret void } @@ -71,10 +75,10 @@ define weak_odr dllexport void @weak1() { ; CHECK: .comm _Var3 @Var3 = common dllexport global i32 0, align 4 -; CHECK: .globl _WeakVar1 +; CHECK: .weak _WeakVar1 @WeakVar1 = weak_odr dllexport global i32 1, align 4 -; CHECK: .globl _WeakVar2 +; CHECK: .weak _WeakVar2 @WeakVar2 = weak_odr dllexport unnamed_addr constant i32 1