Bring r226038 back.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 19 Jan 2015 15:16:06 +0000 (15:16 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 19 Jan 2015 15:16:06 +0000 (15:16 +0000)
No change in this commit, but clang was changed to also produce trivial comdats when
needed.

Original message:

Don't create new comdats in CodeGen.

This patch stops the implicit creation of comdats during codegen.

Clang now sets the comdat explicitly when it is required. With this patch clang and gcc
now produce the same result in pr19848.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226467 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
lib/Target/XCore/XCoreAsmPrinter.cpp
test/Bitcode/linkage-types-3.2.ll
test/CodeGen/ARM/odr_comdat.ll [deleted file]
test/CodeGen/ARM/section-name.ll
test/CodeGen/X86/dllexport-x86_64.ll
test/CodeGen/X86/dllexport.ll
test/CodeGen/X86/global-sections.ll
test/CodeGen/X86/odr_comdat.ll [deleted file]
test/CodeGen/X86/pic_jumptable.ll
test/MC/COFF/bss_section.ll
test/MC/COFF/const-gv-with-rel-init.ll
test/MC/COFF/weak-symbol.ll [deleted file]

index 409adafc78631b664636955c5b8d170842ded135..fe48c254d247f6e97819c56964bcc961246ac34d 100644 (file)
@@ -156,19 +156,27 @@ static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,
   return false;
 }
 
+static bool hasImplicitComdat(size_t Val) {
+  switch (Val) {
+  default:
+    return false;
+  case 1:  // Old WeakAnyLinkage
+  case 4:  // Old LinkOnceAnyLinkage
+  case 10: // Old WeakODRLinkage
+  case 11: // Old LinkOnceODRLinkage
+    return true;
+  }
+}
+
 static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
   switch (Val) {
   default: // Map unknown/new linkages to external
   case 0:
     return GlobalValue::ExternalLinkage;
-  case 1:
-    return GlobalValue::WeakAnyLinkage;
   case 2:
     return GlobalValue::AppendingLinkage;
   case 3:
     return GlobalValue::InternalLinkage;
-  case 4:
-    return GlobalValue::LinkOnceAnyLinkage;
   case 5:
     return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage
   case 6:
@@ -179,10 +187,6 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
     return GlobalValue::CommonLinkage;
   case 9:
     return GlobalValue::PrivateLinkage;
-  case 10:
-    return GlobalValue::WeakODRLinkage;
-  case 11:
-    return GlobalValue::LinkOnceODRLinkage;
   case 12:
     return GlobalValue::AvailableExternallyLinkage;
   case 13:
@@ -191,6 +195,18 @@ static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) {
     return GlobalValue::PrivateLinkage; // Obsolete LinkerPrivateWeakLinkage
   case 15:
     return GlobalValue::ExternalLinkage; // Obsolete LinkOnceODRAutoHideLinkage
+  case 1: // Old value with implicit comdat.
+  case 16:
+    return GlobalValue::WeakAnyLinkage;
+  case 10: // Old value with implicit comdat.
+  case 17:
+    return GlobalValue::WeakODRLinkage;
+  case 4: // Old value with implicit comdat.
+  case 18:
+    return GlobalValue::LinkOnceAnyLinkage;
+  case 11: // Old value with implicit comdat.
+  case 19:
+    return GlobalValue::LinkOnceODRLinkage;
   }
 }
 
@@ -1118,6 +1134,10 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
       Value *V = ValueList[ValueID];
 
       V->setName(StringRef(ValueName.data(), ValueName.size()));
+      if (auto *GO = dyn_cast<GlobalObject>(V)) {
+        if (GO->getComdat() == reinterpret_cast<Comdat *>(1))
+          GO->setComdat(TheModule->getOrInsertComdat(V->getName()));
+      }
       ValueName.clear();
       break;
     }
@@ -2140,7 +2160,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
       Ty = cast<PointerType>(Ty)->getElementType();
 
       bool isConstant = Record[1];
-      GlobalValue::LinkageTypes Linkage = getDecodedLinkage(Record[3]);
+      uint64_t RawLinkage = Record[3];
+      GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
       unsigned Alignment = (1 << Record[4]) >> 1;
       std::string Section;
       if (Record[5]) {
@@ -2178,7 +2199,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
       if (Record.size() > 10)
         NewGV->setDLLStorageClass(GetDecodedDLLStorageClass(Record[10]));
       else
-        UpgradeDLLImportExportLinkage(NewGV, Record[3]);
+        UpgradeDLLImportExportLinkage(NewGV, RawLinkage);
 
       ValueList.push_back(NewGV);
 
@@ -2186,11 +2207,14 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
       if (unsigned InitID = Record[2])
         GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
 
-      if (Record.size() > 11)
+      if (Record.size() > 11) {
         if (unsigned ComdatID = Record[11]) {
           assert(ComdatID <= ComdatList.size());
           NewGV->setComdat(ComdatList[ComdatID - 1]);
         }
+      } else if (hasImplicitComdat(RawLinkage)) {
+        NewGV->setComdat(reinterpret_cast<Comdat *>(1));
+      }
       break;
     }
     // FUNCTION:  [type, callingconv, isproto, linkage, paramattr,
@@ -2214,7 +2238,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
 
       Func->setCallingConv(static_cast<CallingConv::ID>(Record[1]));
       bool isProto = Record[2];
-      Func->setLinkage(getDecodedLinkage(Record[3]));
+      uint64_t RawLinkage = Record[3];
+      Func->setLinkage(getDecodedLinkage(RawLinkage));
       Func->setAttributes(getAttributes(Record[4]));
 
       Func->setAlignment((1 << Record[5]) >> 1);
@@ -2242,13 +2267,16 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
       if (Record.size() > 11)
         Func->setDLLStorageClass(GetDecodedDLLStorageClass(Record[11]));
       else
-        UpgradeDLLImportExportLinkage(Func, Record[3]);
+        UpgradeDLLImportExportLinkage(Func, RawLinkage);
 
-      if (Record.size() > 12)
+      if (Record.size() > 12) {
         if (unsigned ComdatID = Record[12]) {
           assert(ComdatID <= ComdatList.size());
           Func->setComdat(ComdatList[ComdatID - 1]);
         }
+      } else if (hasImplicitComdat(RawLinkage)) {
+        Func->setComdat(reinterpret_cast<Comdat *>(1));
+      }
 
       if (Record.size() > 13 && Record[13] != 0)
         FunctionPrefixes.push_back(std::make_pair(Func, Record[13]-1));
index 5e8c64ee9cd5121e7b22d4c31a260742f8c86c5a..960a7922cd804f58f0ed1d9c75966a7e68401947 100644 (file)
@@ -480,13 +480,13 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
   case GlobalValue::ExternalLinkage:
     return 0;
   case GlobalValue::WeakAnyLinkage:
-    return 1;
+    return 16;
   case GlobalValue::AppendingLinkage:
     return 2;
   case GlobalValue::InternalLinkage:
     return 3;
   case GlobalValue::LinkOnceAnyLinkage:
-    return 4;
+    return 18;
   case GlobalValue::ExternalWeakLinkage:
     return 7;
   case GlobalValue::CommonLinkage:
@@ -494,9 +494,9 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
   case GlobalValue::PrivateLinkage:
     return 9;
   case GlobalValue::WeakODRLinkage:
-    return 10;
+    return 17;
   case GlobalValue::LinkOnceODRLinkage:
-    return 11;
+    return 19;
   case GlobalValue::AvailableExternallyLinkage:
     return 12;
   }
@@ -629,7 +629,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
                               Log2_32_Ceil(MaxGlobalType+1)));
     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));      // Constant.
     Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));        // Initializer.
-    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));      // Linkage.
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));      // Linkage.
     if (MaxAlignment == 0)                                      // Alignment.
       Abbv->Add(BitCodeAbbrevOp(0));
     else {
index 9f1e06b4725d2e894e4d3a16b448fe35dcf384fa..b9a3ad23d1f812c710196e1abde1f08d58550ec2 100644 (file)
@@ -257,8 +257,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
 
   // If this global is linkonce/weak and the target handles this by emitting it
   // into a 'uniqued' section name, create and return the section now.
-  if ((GV->isWeakForLinker() || EmitUniquedSection || GV->hasComdat()) &&
-      !Kind.isCommon()) {
+  if ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) {
     StringRef Prefix = getSectionPrefixForGlobal(Kind);
 
     SmallString<128> Name(Prefix);
@@ -266,12 +265,9 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
 
     StringRef Group = "";
     unsigned Flags = getELFSectionFlags(Kind);
-    if (GV->isWeakForLinker() || GV->hasComdat()) {
-      if (const Comdat *C = getELFComdat(GV))
-        Group = C->getName();
-      else
-        Group = Name.substr(Prefix.size());
+    if (const Comdat *C = getELFComdat(GV)) {
       Flags |= ELF::SHF_GROUP;
+      Group = C->getName();
     }
 
     return getContext().getELFSection(Name.str(),
@@ -801,7 +797,7 @@ const MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
   unsigned Characteristics = getCOFFSectionFlags(Kind);
   StringRef Name = GV->getSection();
   StringRef COMDATSymName = "";
-  if ((GV->isWeakForLinker() || GV->hasComdat()) && !Kind.isCommon()) {
+  if (GV->hasComdat()) {
     Selection = getSelectionForCOFF(GV);
     const GlobalValue *ComdatGV;
     if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
@@ -848,12 +844,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
   else
     EmitUniquedSection = TM.getDataSections();
 
-  // If this global is linkonce/weak and the target handles this by emitting it
-  // into a 'uniqued' section name, create and return the section now.
-  // Section names depend on the name of the symbol which is not feasible if the
-  // symbol has private linkage.
-  if ((GV->isWeakForLinker() || EmitUniquedSection || GV->hasComdat()) &&
-      !Kind.isCommon()) {
+  if ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) {
     const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
     unsigned Characteristics = getCOFFSectionFlags(Kind);
 
index cbcf05ade82a1be0a17b3f6ddd771ceaa28e263b..18e718493c9fb014ebd04c9a26a5efb9f334555e 100644 (file)
@@ -106,7 +106,6 @@ void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
                                                       OutContext));
     if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
         GV->hasCommonLinkage()) {
-      // TODO Use COMDAT groups for LinkOnceLinkage
       OutStreamer.EmitSymbolAttribute(SymGlob, MCSA_Weak);
     }
   }
@@ -141,7 +140,6 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
     emitArrayBound(GVSym, GV);
     OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
 
-    // TODO Use COMDAT groups for LinkOnceLinkage
     if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
         GV->hasCommonLinkage())
       OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
index e255b619f41b04e15f96dd694854baf48af4a4bd..fb6cc5745fad3b006dc89a80e5cab17a18222e0c 100644 (file)
 ; CHECK: @available_externally.var = available_externally constant i32 0{{$}}
 
 @linkonce.var = linkonce constant i32 0
-; CHECK: @linkonce.var = linkonce constant i32 0{{$}}
+; CHECK: @linkonce.var = linkonce constant i32 0, comdat{{$}}
 
 @weak.var = weak constant i32 0
-; CHECK: @weak.var = weak constant i32 0{{$}}
+; CHECK: @weak.var = weak constant i32 0, comdat{{$}}
 
 @linkonce_odr.var = linkonce_odr constant i32 0
-; CHECK: @linkonce_odr.var = linkonce_odr constant i32 0{{$}}
+; CHECK: @linkonce_odr.var = linkonce_odr constant i32 0, comdat{{$}}
 
 @linkonce_odr_auto_hide.var = linkonce_odr_auto_hide constant i32 0
 ; CHECK: @linkonce_odr_auto_hide.var = constant i32 0{{$}}
@@ -90,19 +90,19 @@ define available_externally void @available_externally()
 }
 
 define linkonce void @linkonce()
-; CHECK: define linkonce void @linkonce() {
+; CHECK: define linkonce void @linkonce() comdat {
 {
   ret void
 }
 
 define weak void @weak()
-; CHECK: define weak void @weak() {
+; CHECK: define weak void @weak() comdat {
 {
   ret void
 }
 
 define linkonce_odr void @linkonce_odr()
-; CHECK: define linkonce_odr void @linkonce_odr() {
+; CHECK: define linkonce_odr void @linkonce_odr() comdat {
 {
   ret void
 }
diff --git a/test/CodeGen/ARM/odr_comdat.ll b/test/CodeGen/ARM/odr_comdat.ll
deleted file mode 100644 (file)
index e28b578..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: llc < %s -mtriple=arm-linux-gnueabi | FileCheck %s -check-prefix=ARMGNUEABI
-
-; Checking that a comdat group gets generated correctly for a static member 
-; of instantiated C++ templates.
-; see http://sourcery.mentor.com/public/cxx-abi/abi.html#vague-itemplate
-; section 5.2.6 Instantiated templates
-; "Any static member data object is emitted in a COMDAT identified by its mangled 
-;  name, in any object file with a reference to its name symbol."
-
-; Case 1: variable is not explicitly initialized, and ends up in a .bss section
-; ARMGNUEABI: .section        .bss._ZN1CIiE1iE,"aGw",%nobits,_ZN1CIiE1iE,comdat
-@_ZN1CIiE1iE = weak_odr global i32 0, align 4
-
-; Case 2: variable is explicitly initialized, and ends up in a .data section
-; ARMGNUEABI: .section        .data._ZN1CIiE1jE,"aGw",%progbits,_ZN1CIiE1jE,comdat
-@_ZN1CIiE1jE = weak_odr global i32 12, align 4
index a0aad4733bc8398a05518d4ad054559a6d71b542..a4c6054197f3e6ed6513af71da7abf6c70f42328 100644 (file)
@@ -16,7 +16,7 @@ entry:
   ret void
 }
 
-; CHECK: .section .text.test3,"axG",%progbits,test3,comdat
+; CHECK: .text
 ; CHECK: .weak test3
 ; CHECK: .type test3,%function
 define linkonce_odr void @test3() {
index c673f5d485f9eecfe9958bd3b720a24dfdb13f6e..25b88e56e459fa40835875de6244ddf439674331 100644 (file)
@@ -17,19 +17,16 @@ define dllexport void @f2() unnamed_addr {
        ret void
 }
 
-; CHECK: .section .text,"xr",discard,lnk1
 ; CHECK: .globl lnk1
 define linkonce_odr dllexport void @lnk1() {
        ret void
 }
 
-; CHECK: .section .text,"xr",discard,lnk2
 ; CHECK: .globl lnk2
 define linkonce_odr dllexport void @lnk2() alwaysinline {
        ret void
 }
 
-; CHECK: .section .text,"xr",discard,weak1
 ; CHECK: .globl weak1
 define weak_odr dllexport void @weak1() {
        ret void
@@ -47,11 +44,9 @@ define weak_odr dllexport void @weak1() {
 ; CHECK: .comm Var3
 @Var3 = common dllexport global i32 0, align 4
 
-; CHECK: .section .data,"wd",discard,WeakVar1
 ; CHECK: .globl WeakVar1
 @WeakVar1 = weak_odr dllexport global i32 1, align 4
 
-; CHECK: .section .rdata,"rd",discard,WeakVar2
 ; CHECK: .globl WeakVar2
 @WeakVar2 = weak_odr dllexport unnamed_addr constant i32 1
 
index 5035aa153301383a70b6a337ffe319934d8f2b13..e76591d7f5eab377cd551d5aab63a05156ebe85a 100644 (file)
@@ -36,19 +36,16 @@ define dllexport x86_thiscallcc void @thisfun() nounwind {
        ret void
 }
 
-; CHECK: .section .text,"xr",discard,_lnk1
 ; CHECK: .globl _lnk1
 define linkonce_odr dllexport void @lnk1() {
        ret void
 }
 
-; CHECK: .section .text,"xr",discard,_lnk2
 ; CHECK: .globl _lnk2
 define linkonce_odr dllexport void @lnk2() alwaysinline {
        ret void
 }
 
-; CHECK: .section .text,"xr",discard,_weak1
 ; CHECK: .globl _weak1
 define weak_odr dllexport void @weak1() {
        ret void
@@ -66,11 +63,9 @@ define weak_odr dllexport void @weak1() {
 ; CHECK: .comm _Var3
 @Var3 = common dllexport global i32 0, align 4
 
-; CHECK: .section .data,"wd",discard,_WeakVar1
 ; CHECK: .globl _WeakVar1
 @WeakVar1 = weak_odr dllexport global i32 1, align 4
 
-; CHECK: .section .rdata,"rd",discard,_WeakVar2
 ; CHECK: .globl _WeakVar2
 @WeakVar2 = weak_odr dllexport unnamed_addr constant i32 1
 
index fa1169d8a8e315dfad243b5e98971ff9e48c388f..24be27161f4a9524244898f89a75bd1debae2448 100644 (file)
@@ -85,7 +85,6 @@ define void @F1() {
 @"foo bar" = linkonce global i32 42
 
 ; LINUX: .type  "foo bar",@object
-; LINUX: .section ".data.foo bar","aGw",@progbits,"foo bar",comdat
 ; LINUX: .weak  "foo bar"
 ; LINUX: "foo bar":
 
@@ -98,7 +97,6 @@ define void @F1() {
 @G6 = weak_odr unnamed_addr constant [1 x i8] c"\01"
 
 ; LINUX:   .type        G6,@object
-; LINUX:   .section     .rodata.G6,"aG",@progbits,G6,comdat
 ; LINUX:   .weak        G6
 ; LINUX: G6:
 ; LINUX:   .byte        1
diff --git a/test/CodeGen/X86/odr_comdat.ll b/test/CodeGen/X86/odr_comdat.ll
deleted file mode 100644 (file)
index 547334c..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s -check-prefix=X86LINUX
-
-; Checking that a comdat group gets generated correctly for a static member 
-; of instantiated C++ templates.
-; see http://sourcery.mentor.com/public/cxx-abi/abi.html#vague-itemplate
-; section 5.2.6 Instantiated templates
-; "Any static member data object is emitted in a COMDAT identified by its mangled 
-;  name, in any object file with a reference to its name symbol."
-
-; Case 1: variable is not explicitly initialized, and ends up in a .bss section
-; X86LINUX:   .section        .bss._ZN1CIiE1iE,"aGw",@nobits,_ZN1CIiE1iE,comdat
-@_ZN1CIiE1iE = weak_odr global i32 0, align 4
-
-; Case 2: variable is explicitly initialized, and ends up in a .data section
-; X86LINUX:   .section        .data._ZN1CIiE1jE,"aGw",@progbits,_ZN1CIiE1jE,comdat
-@_ZN1CIiE1jE = weak_odr global i32 12, align 4
index bdd8859358426eeb34c5d0a883c1e88331f9aef6..d66ff0c59db511ea63bfc663b52b7522863a1069 100644 (file)
@@ -10,7 +10,7 @@
 
 declare void @_Z3bari(i32)
 
-; CHECK-LINUX: .text._Z3fooILi1EEvi,"axG",@progbits,_Z3fooILi1EEvi,comdat
+; CHECK-LINUX: _Z3fooILi1EEvi:
 define linkonce void @_Z3fooILi1EEvi(i32 %Y) nounwind {
 entry:
 ; CHECK:       L0$pb
index 1921eeb61a654c21b21cd372e3de44bf0735987e..f80a0712b7eb99409f97db57dbdf2c77ff00ad5f 100644 (file)
@@ -5,5 +5,6 @@
 @"\01?thingy@@3Ufoo@@B" = global %struct.foo zeroinitializer, align 4
 ; CHECK: .bss
 
-@thingy_linkonce = linkonce_odr global %struct.foo zeroinitializer, align 4
+$thingy_linkonce = comdat any
+@thingy_linkonce = linkonce_odr global %struct.foo zeroinitializer, comdat, align 4
 ; CHECK: .section .bss,"wb",discard,_thingy_linkonce
index 7d3c5f631881927af577c58aeb5d21836aaa091e..6a89e2faa689477d88b196be41d3e13192909701 100644 (file)
@@ -8,4 +8,4 @@ define void @f() {
 ; CHECK:  .section  .CRT$XLB,"rd"
 
 @weak_array = weak_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void ()* @f to i8*)]
-; CHECK:  .section  .rdata,"rd",discard,weak_array
+; CHECK:  .section  .rdata,"rd"
diff --git a/test/MC/COFF/weak-symbol.ll b/test/MC/COFF/weak-symbol.ll
deleted file mode 100644 (file)
index fd78307..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-; Test that weak functions and globals are placed into selectany COMDAT\r
-; sections with the mangled name as suffix. Ensure that the weak linkage\r
-; type is not ignored by the backend if the section was specialized.\r
-;\r
-; RUN: llc -mtriple=i686-pc-win32 %s     -o - | FileCheck %s --check-prefix=X86\r
-; RUN: llc -mtriple=i686-pc-mingw32 %s   -o - | FileCheck %s --check-prefix=X86\r
-; RUN: llc -mtriple=x86_64-pc-win32 %s   -o - | FileCheck %s --check-prefix=X64\r
-; RUN: llc -mtriple=x86_64-pc-mingw32 %s -o - | FileCheck %s --check-prefix=X64\r
-\r
-; Mangled function\r
-; X86: .section .text,"xr",discard,__Z3foo\r
-; X86: .globl __Z3foo\r
-;\r
-; X64: .section .text,"xr",discard,_Z3foo\r
-; X64: .globl _Z3foo\r
-define weak void @_Z3foo() {\r
-  ret void\r
-}\r
-\r
-; Unmangled function\r
-; X86: .section .sect,"xr",discard,_f\r
-; X86: .globl _f\r
-;\r
-; X64: .section .sect,"xr",discard,f\r
-; X64: .globl f\r
-define weak void @f() section ".sect" {\r
-  ret void\r
-}\r
-\r
-; Weak global\r
-; X86: .section .data,"rd",discard,_a\r
-; X86: .globl _a\r
-; X86: .zero 12\r
-;\r
-; X64: .section .data,"rd",discard,a\r
-; X64: .globl a\r
-; X64: .zero 12\r
-@a = weak unnamed_addr constant { i32, i32, i32 } { i32 0, i32 0, i32 0}, section ".data"\r
-\r
-; X86:  .section        .tls$,"wd",discard,_b\r
-; X86:  .globl  _b\r
-; X86:  .long   0\r
-;\r
-; X64:  .section        .tls$,"wd",discard,b\r
-; X64:  .globl  b\r
-; X64:  .long   0\r
-\r
-@b = weak_odr thread_local global i32 0, align 4\r