/// 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.
return HasWeakDefCanBeHiddenDirective;
}
- bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
+ bool avoidWeakIfComdat() const { return AvoidWeakIfComdat; }
bool hasDotLGloblDirective() const { return HasDotLGloblDirective; }
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.
HasDotTypeDotSizeDirective = false;
HasSingleParameterDotFile = true;
WeakRefDirective = "\t.weak\t";
- HasLinkOnceDirective = true;
+ AvoidWeakIfComdat = true;
// Doesn't support visibility:
HiddenVisibilityAttr = HiddenDeclarationVisibilityAttr = MCSA_Invalid;
--- /dev/null
+; 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
+}
-; 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"
+; 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
-; CHECK: .section{{.*}}one_only
-define linkonce_odr void @foo() {
+define linkonce_odr void @quux_comdat() comdat {
ret void
}
}
; 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
}
; 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
}
; 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
}
; 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