forked from OSchip/llvm-project
Revert r226242 - Revert Revert Don't create new comdats in CodeGen
This breaks AddressSanitizer (ninja check-asan) on Windows llvm-svn: 226251
This commit is contained in:
parent
24b04aa393
commit
60b721363c
|
@ -156,27 +156,19 @@ 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:
|
||||
|
@ -187,6 +179,10 @@ 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:
|
||||
|
@ -195,18 +191,6 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1134,10 +1118,6 @@ 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;
|
||||
}
|
||||
|
@ -2160,8 +2140,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
|
|||
Ty = cast<PointerType>(Ty)->getElementType();
|
||||
|
||||
bool isConstant = Record[1];
|
||||
uint64_t RawLinkage = Record[3];
|
||||
GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage);
|
||||
GlobalValue::LinkageTypes Linkage = getDecodedLinkage(Record[3]);
|
||||
unsigned Alignment = (1 << Record[4]) >> 1;
|
||||
std::string Section;
|
||||
if (Record[5]) {
|
||||
|
@ -2199,7 +2178,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
|
|||
if (Record.size() > 10)
|
||||
NewGV->setDLLStorageClass(GetDecodedDLLStorageClass(Record[10]));
|
||||
else
|
||||
UpgradeDLLImportExportLinkage(NewGV, RawLinkage);
|
||||
UpgradeDLLImportExportLinkage(NewGV, Record[3]);
|
||||
|
||||
ValueList.push_back(NewGV);
|
||||
|
||||
|
@ -2207,14 +2186,11 @@ 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,
|
||||
|
@ -2238,8 +2214,7 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
|
|||
|
||||
Func->setCallingConv(static_cast<CallingConv::ID>(Record[1]));
|
||||
bool isProto = Record[2];
|
||||
uint64_t RawLinkage = Record[3];
|
||||
Func->setLinkage(getDecodedLinkage(RawLinkage));
|
||||
Func->setLinkage(getDecodedLinkage(Record[3]));
|
||||
Func->setAttributes(getAttributes(Record[4]));
|
||||
|
||||
Func->setAlignment((1 << Record[5]) >> 1);
|
||||
|
@ -2267,16 +2242,13 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
|
|||
if (Record.size() > 11)
|
||||
Func->setDLLStorageClass(GetDecodedDLLStorageClass(Record[11]));
|
||||
else
|
||||
UpgradeDLLImportExportLinkage(Func, RawLinkage);
|
||||
UpgradeDLLImportExportLinkage(Func, Record[3]);
|
||||
|
||||
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));
|
||||
|
|
|
@ -480,13 +480,13 @@ static unsigned getEncodedLinkage(const GlobalValue &GV) {
|
|||
case GlobalValue::ExternalLinkage:
|
||||
return 0;
|
||||
case GlobalValue::WeakAnyLinkage:
|
||||
return 16;
|
||||
return 1;
|
||||
case GlobalValue::AppendingLinkage:
|
||||
return 2;
|
||||
case GlobalValue::InternalLinkage:
|
||||
return 3;
|
||||
case GlobalValue::LinkOnceAnyLinkage:
|
||||
return 18;
|
||||
return 4;
|
||||
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 17;
|
||||
return 10;
|
||||
case GlobalValue::LinkOnceODRLinkage:
|
||||
return 19;
|
||||
return 11;
|
||||
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, 5)); // Linkage.
|
||||
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // Linkage.
|
||||
if (MaxAlignment == 0) // Alignment.
|
||||
Abbv->Add(BitCodeAbbrevOp(0));
|
||||
else {
|
||||
|
|
|
@ -257,7 +257,8 @@ 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 ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) {
|
||||
if ((GV->isWeakForLinker() || EmitUniquedSection || GV->hasComdat()) &&
|
||||
!Kind.isCommon()) {
|
||||
StringRef Prefix = getSectionPrefixForGlobal(Kind);
|
||||
|
||||
SmallString<128> Name(Prefix);
|
||||
|
@ -265,9 +266,12 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
|||
|
||||
StringRef Group = "";
|
||||
unsigned Flags = getELFSectionFlags(Kind);
|
||||
if (const Comdat *C = getELFComdat(GV)) {
|
||||
if (GV->isWeakForLinker() || GV->hasComdat()) {
|
||||
if (const Comdat *C = getELFComdat(GV))
|
||||
Group = C->getName();
|
||||
else
|
||||
Group = Name.substr(Prefix.size());
|
||||
Flags |= ELF::SHF_GROUP;
|
||||
Group = C->getName();
|
||||
}
|
||||
|
||||
return getContext().getELFSection(Name.str(),
|
||||
|
@ -797,7 +801,7 @@ const MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
|
|||
unsigned Characteristics = getCOFFSectionFlags(Kind);
|
||||
StringRef Name = GV->getSection();
|
||||
StringRef COMDATSymName = "";
|
||||
if (GV->hasComdat()) {
|
||||
if ((GV->isWeakForLinker() || GV->hasComdat()) && !Kind.isCommon()) {
|
||||
Selection = getSelectionForCOFF(GV);
|
||||
const GlobalValue *ComdatGV;
|
||||
if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
|
||||
|
@ -844,7 +848,12 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
|||
else
|
||||
EmitUniquedSection = TM.getDataSections();
|
||||
|
||||
if ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) {
|
||||
// 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()) {
|
||||
const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
|
||||
unsigned Characteristics = getCOFFSectionFlags(Kind);
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +140,7 @@ 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);
|
||||
|
|
|
@ -33,13 +33,13 @@
|
|||
; CHECK: @available_externally.var = available_externally constant i32 0{{$}}
|
||||
|
||||
@linkonce.var = linkonce constant i32 0
|
||||
; CHECK: @linkonce.var = linkonce constant i32 0, comdat{{$}}
|
||||
; CHECK: @linkonce.var = linkonce constant i32 0{{$}}
|
||||
|
||||
@weak.var = weak constant i32 0
|
||||
; CHECK: @weak.var = weak constant i32 0, comdat{{$}}
|
||||
; CHECK: @weak.var = weak constant i32 0{{$}}
|
||||
|
||||
@linkonce_odr.var = linkonce_odr constant i32 0
|
||||
; CHECK: @linkonce_odr.var = linkonce_odr constant i32 0, comdat{{$}}
|
||||
; CHECK: @linkonce_odr.var = linkonce_odr constant i32 0{{$}}
|
||||
|
||||
@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() comdat {
|
||||
; CHECK: define linkonce void @linkonce() {
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define weak void @weak()
|
||||
; CHECK: define weak void @weak() comdat {
|
||||
; CHECK: define weak void @weak() {
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
||||
define linkonce_odr void @linkonce_odr()
|
||||
; CHECK: define linkonce_odr void @linkonce_odr() comdat {
|
||||
; CHECK: define linkonce_odr void @linkonce_odr() {
|
||||
{
|
||||
ret void
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
; 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
|
|
@ -16,7 +16,7 @@ entry:
|
|||
ret void
|
||||
}
|
||||
|
||||
; CHECK: .text
|
||||
; CHECK: .section .text.test3,"axG",%progbits,test3,comdat
|
||||
; CHECK: .weak test3
|
||||
; CHECK: .type test3,%function
|
||||
define linkonce_odr void @test3() {
|
||||
|
|
|
@ -17,16 +17,19 @@ 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
|
||||
|
@ -44,9 +47,11 @@ 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
|
||||
|
||||
|
|
|
@ -36,16 +36,19 @@ 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
|
||||
|
@ -63,9 +66,11 @@ 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
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ 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":
|
||||
|
||||
|
@ -97,6 +98,7 @@ 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
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
; 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
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
declare void @_Z3bari(i32)
|
||||
|
||||
; CHECK-LINUX: _Z3fooILi1EEvi:
|
||||
; CHECK-LINUX: .text._Z3fooILi1EEvi,"axG",@progbits,_Z3fooILi1EEvi,comdat
|
||||
define linkonce void @_Z3fooILi1EEvi(i32 %Y) nounwind {
|
||||
entry:
|
||||
; CHECK: L0$pb
|
||||
|
|
|
@ -5,6 +5,5 @@
|
|||
@"\01?thingy@@3Ufoo@@B" = global %struct.foo zeroinitializer, align 4
|
||||
; CHECK: .bss
|
||||
|
||||
$thingy_linkonce = comdat any
|
||||
@thingy_linkonce = linkonce_odr global %struct.foo zeroinitializer, comdat, align 4
|
||||
@thingy_linkonce = linkonce_odr global %struct.foo zeroinitializer, align 4
|
||||
; CHECK: .section .bss,"wb",discard,_thingy_linkonce
|
||||
|
|
|
@ -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"
|
||||
; CHECK: .section .rdata,"rd",discard,weak_array
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
; Test that weak functions and globals are placed into selectany COMDAT
|
||||
; sections with the mangled name as suffix. Ensure that the weak linkage
|
||||
; type is not ignored by the backend if the section was specialized.
|
||||
;
|
||||
; RUN: llc -mtriple=i686-pc-win32 %s -o - | FileCheck %s --check-prefix=X86
|
||||
; RUN: llc -mtriple=i686-pc-mingw32 %s -o - | FileCheck %s --check-prefix=X86
|
||||
; RUN: llc -mtriple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=X64
|
||||
; RUN: llc -mtriple=x86_64-pc-mingw32 %s -o - | FileCheck %s --check-prefix=X64
|
||||
|
||||
; Mangled function
|
||||
; X86: .section .text,"xr",discard,__Z3foo
|
||||
; X86: .globl __Z3foo
|
||||
;
|
||||
; X64: .section .text,"xr",discard,_Z3foo
|
||||
; X64: .globl _Z3foo
|
||||
define weak void @_Z3foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
; Unmangled function
|
||||
; X86: .section .sect,"xr",discard,_f
|
||||
; X86: .globl _f
|
||||
;
|
||||
; X64: .section .sect,"xr",discard,f
|
||||
; X64: .globl f
|
||||
define weak void @f() section ".sect" {
|
||||
ret void
|
||||
}
|
||||
|
||||
; Weak global
|
||||
; X86: .section .data,"rd",discard,_a
|
||||
; X86: .globl _a
|
||||
; X86: .zero 12
|
||||
;
|
||||
; X64: .section .data,"rd",discard,a
|
||||
; X64: .globl a
|
||||
; X64: .zero 12
|
||||
@a = weak unnamed_addr constant { i32, i32, i32 } { i32 0, i32 0, i32 0}, section ".data"
|
||||
|
||||
; X86: .section .tls$,"wd",discard,_b
|
||||
; X86: .globl _b
|
||||
; X86: .long 0
|
||||
;
|
||||
; X64: .section .tls$,"wd",discard,b
|
||||
; X64: .globl b
|
||||
; X64: .long 0
|
||||
|
||||
@b = weak_odr thread_local global i32 0, align 4
|
Loading…
Reference in New Issue