diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -75,6 +75,12 @@ const MachineBasicBlock &MBB, const TargetMachine &TM) const override; + /// Mutates NextUniqueID + unsigned calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, + StringRef SectionName, + SectionKind Kind, unsigned &Flags, + unsigned &EntrySize) const; + MCSection * getUniqueSectionForFunction(const Function &F, const TargetMachine &TM) const override; diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -351,29 +351,30 @@ /// Map of currently defined macros. StringMap MacroMap; - struct ELFEntrySizeKey { + struct ELFSectionUniqueKey { std::string SectionName; unsigned Flags; unsigned EntrySize; - ELFEntrySizeKey(StringRef SectionName, unsigned Flags, unsigned EntrySize) + ELFSectionUniqueKey(StringRef SectionName, unsigned Flags, + unsigned EntrySize) : SectionName(SectionName), Flags(Flags), EntrySize(EntrySize) {} - bool operator<(const ELFEntrySizeKey &Other) const { + bool operator<(const ELFSectionUniqueKey &Other) const { if (SectionName != Other.SectionName) return SectionName < Other.SectionName; - if ((Flags & ELF::SHF_STRINGS) != (Other.Flags & ELF::SHF_STRINGS)) - return Other.Flags & ELF::SHF_STRINGS; + if (Flags != Other.Flags) + return Flags < Other.Flags; return EntrySize < Other.EntrySize; } }; - // Symbols must be assigned to a section with a compatible entry - // size. This map is used to assign unique IDs to sections to - // distinguish between sections with identical names but incompatible entry - // sizes. This can occur when a symbol is explicitly assigned to a - // section, e.g. via __attribute__((section("myname"))). - std::map ELFEntrySizeMap; + // Symbols must be assigned to a section with a compatible entry size and + // flags. This map is used to assign unique IDs to sections to distinguish + // between sections with identical names but incompatible entry sizes and/or + // flags. This can occur when a symbol is explicitly assigned to a section, + // e.g. via __attribute__((section("myname"))). + std::map ELFSectionUniqueMap; // This set is used to record the generic mergeable section names seen. // These are sections that are created as mergeable e.g. .debug_str. We need @@ -573,7 +574,9 @@ bool isELFGenericMergeableSection(StringRef Name); - Optional getELFUniqueIDForEntsize(StringRef SectionName, + /// Return the unique ID of the section with the given name, flags and entry + /// size, if it exists. + Optional getELFUniqueIDForSection(StringRef SectionName, unsigned Flags, unsigned EntrySize); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -652,6 +652,74 @@ }; } +/// Calculate an appropriate unique ID for a section, and update Flags and +/// EntrySize where appropriate. Mutates NextUniqueID. +unsigned TargetLoweringObjectFileELF::calcUniqueIDUpdateFlagsAndSize( + const GlobalObject *GO, StringRef SectionName, SectionKind Kind, + unsigned &Flags, unsigned &EntrySize) const { + // A section can have at most one associated section. Put each global with + // MD_associated in a unique section. + const bool Associated = GO->getMetadata(LLVMContext::MD_associated); + if (Associated) { + Flags |= ELF::SHF_LINK_ORDER; + return NextUniqueID++; + } + + const bool Retain = Used.count(GO); + if (Retain) { + if (getContext().getAsmInfo()->useIntegratedAssembler() || + getContext().getAsmInfo()->binutilsIsAtLeast(2, 36)) + Flags |= ELF::SHF_GNU_RETAIN; + return NextUniqueID++; + } + + // If two symbols with differing sizes end up in the same mergeable section + // that section can be assigned an incorrect entry size. To avoid this we + // usually put symbols of the same size into distinct mergeable sections with + // the same name. Doing so relies on the ",unique ," assembly feature. This + // feature is not avalible until bintuils version 2.35 + // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). + const bool SupportsUnique = + getContext().getAsmInfo()->useIntegratedAssembler() || + getContext().getAsmInfo()->binutilsIsAtLeast(2, 35); + if (!SupportsUnique) { + Flags &= ~ELF::SHF_MERGE; + EntrySize = 0; + return MCContext::GenericSectionID; + } + + const bool SeenSectionNameBefore = + getContext().isELFGenericMergeableSection(SectionName); + // If this is the first ocurrence of this section name, treat it as the + // generic section + if (!SeenSectionNameBefore) + return MCContext::GenericSectionID; + + // Symbols must be placed into sections with compatible entry sizes. Generate + // unique sections for symbols that have not been assigned to compatible + // sections. + const auto PreviousID = + getContext().getELFUniqueIDForSection(SectionName, Flags, EntrySize); + if (PreviousID) + return *PreviousID; + + // If the user has specified the same section name as would be created + // implicitly for this symbol e.g. .rodata.str1.1, then we don't need + // to unique the section as the entry size for this symbol will be + // compatible with implicitly created sections. + const bool SymbolMergeable = Flags & ELF::SHF_MERGE; + SmallString<128> ImplicitSectionNameStem = getELFSectionNameForGlobal( + GO, Kind, getMangler(), *TM, EntrySize, false); // Note: using this->TM + if (SymbolMergeable && + getContext().isELFImplicitMergeableSectionNamePrefix(SectionName) && + SectionName.startswith(ImplicitSectionNameStem)) + return MCContext::GenericSectionID; + + // We have seen this section name before, but with different flags or entity + // size. Create a new unique ID. + return NextUniqueID++; +} + MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { StringRef SectionName = GO->getSection(); @@ -690,65 +758,10 @@ } unsigned EntrySize = getEntrySizeForKind(Kind); + const unsigned UniqueID = + calcUniqueIDUpdateFlagsAndSize(GO, SectionName, Kind, Flags, EntrySize); - // A section can have at most one associated section. Put each global with - // MD_associated in a unique section. - unsigned UniqueID = MCContext::GenericSectionID; const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); - const bool Associated = GO->getMetadata(LLVMContext::MD_associated); - const bool Retain = Used.count(GO); - if (Associated || Retain) { - UniqueID = NextUniqueID++; - if (Associated) - Flags |= ELF::SHF_LINK_ORDER; - if (Retain && (getContext().getAsmInfo()->useIntegratedAssembler() || - getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) - Flags |= ELF::SHF_GNU_RETAIN; - } else { - if (getContext().getAsmInfo()->useIntegratedAssembler() || - getContext().getAsmInfo()->binutilsIsAtLeast(2, 35)) { - // Symbols must be placed into sections with compatible entry - // sizes. Generate unique sections for symbols that have not - // been assigned to compatible sections. - if (Flags & ELF::SHF_MERGE) { - auto maybeID = getContext().getELFUniqueIDForEntsize(SectionName, Flags, - EntrySize); - if (maybeID) - UniqueID = *maybeID; - else { - // If the user has specified the same section name as would be created - // implicitly for this symbol e.g. .rodata.str1.1, then we don't need - // to unique the section as the entry size for this symbol will be - // compatible with implicitly created sections. - SmallString<128> ImplicitSectionNameStem = getELFSectionNameForGlobal( - GO, Kind, getMangler(), TM, EntrySize, false); - if (!(getContext().isELFImplicitMergeableSectionNamePrefix( - SectionName) && - SectionName.startswith(ImplicitSectionNameStem))) - UniqueID = NextUniqueID++; - } - } else { - // We need to unique the section if the user has explicity - // assigned a non-mergeable symbol to a section name for - // a generic mergeable section. - if (getContext().isELFGenericMergeableSection(SectionName)) { - auto maybeID = getContext().getELFUniqueIDForEntsize( - SectionName, Flags, EntrySize); - UniqueID = maybeID ? *maybeID : NextUniqueID++; - } - } - } else { - // If two symbols with differing sizes end up in the same mergeable - // section that section can be assigned an incorrect entry size. To avoid - // this we usually put symbols of the same size into distinct mergeable - // sections with the same name. Doing so relies on the ",unique ," - // assembly feature. This feature is not avalible until bintuils - // version 2.35 (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). - Flags &= ~ELF::SHF_MERGE; - EntrySize = 0; - } - } - MCSectionELF *Section = getContext().getELFSection( SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize, Group, IsComdat, UniqueID, LinkedToSym); diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -130,7 +130,7 @@ WasmUniquingMap.clear(); XCOFFUniquingMap.clear(); - ELFEntrySizeMap.clear(); + ELFSectionUniqueMap.clear(); ELFSeenGenericMergeableSections.clear(); NextID.clear(); @@ -550,17 +550,17 @@ void MCContext::recordELFMergeableSectionInfo(StringRef SectionName, unsigned Flags, unsigned UniqueID, unsigned EntrySize) { - bool IsMergeable = Flags & ELF::SHF_MERGE; - if (IsMergeable && (UniqueID == GenericSectionID)) + if (UniqueID == GenericSectionID) ELFSeenGenericMergeableSections.insert(SectionName); - // For mergeable sections or non-mergeable sections with a generic mergeable - // section name we enter their Unique ID into the ELFEntrySizeMap so that - // compatible globals can be assigned to the same section. - if (IsMergeable || isELFGenericMergeableSection(SectionName)) { - ELFEntrySizeMap.insert(std::make_pair( - ELFEntrySizeKey{SectionName, Flags, EntrySize}, UniqueID)); - } + // Store all Unique ID into the ELFSectionUniqueMap so that compatible globals + // (i.e. same name, flags, and entsize) can be assigned to the same section. + ELFSectionUniqueKey K{SectionName, Flags, EntrySize}; + if (ELFSectionUniqueMap.count(K) == 0) + ELFSectionUniqueMap.insert({K, UniqueID}); + else + assert(ELFSectionUniqueMap.at(K) == UniqueID && + "ELFSectionUniqueMap unexpected UniqueID"); } bool MCContext::isELFImplicitMergeableSectionNamePrefix(StringRef SectionName) { @@ -573,12 +573,13 @@ ELFSeenGenericMergeableSections.count(SectionName); } -Optional MCContext::getELFUniqueIDForEntsize(StringRef SectionName, +Optional MCContext::getELFUniqueIDForSection(StringRef SectionName, unsigned Flags, unsigned EntrySize) { - auto I = ELFEntrySizeMap.find( - MCContext::ELFEntrySizeKey{SectionName, Flags, EntrySize}); - return (I != ELFEntrySizeMap.end()) ? Optional(I->second) : None; + auto I = ELFSectionUniqueMap.find( + MCContext::ELFSectionUniqueKey{SectionName, Flags, EntrySize}); + return (I != ELFSectionUniqueMap.end()) ? Optional(I->second) + : None; } MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, diff --git a/llvm/test/CodeGen/Generic/elf-unique-sections-by-flags.ll b/llvm/test/CodeGen/Generic/elf-unique-sections-by-flags.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/Generic/elf-unique-sections-by-flags.ll @@ -0,0 +1,85 @@ +; Test that global values with the same specified section produces multiple +; sections with different sets of flags, depending on the properties (mutable, +; executable) of the global value. + +; RUN: llc < %s | FileCheck %s +target triple="aarch64-none-eabi" + +; Normal function goes in text +define i32 @fn_text() { + entry: + ret i32 0 +} +; CHECK: .text{{$}} +; CHECK-NEXT: .file +; CHECK-NEXT: .globl fn_text + +; Functions in user defined executable sections +define i32 @fn_s1() section "s1" { + entry: + ret i32 0 +} +; CHECK: .section s1,"ax",@progbits{{$}} +; CHECK-NEXT: .globl fn_s1 +define i32 @fn_s2() section "s2" { + entry: + ret i32 0 +} +; CHECK: .section s2,"ax",@progbits{{$}} +; CHECK-NEXT: .globl fn_s2 + +; Values that share a section name with a function +@rw_s1 = global i32 10, section "s1", align 4 +@ro_s2 = constant i32 10, section "s2", align 4 +; CHECK: .section s1,"aw",@progbits,unique,[[#UNIQUE_S1_aw:]] +; CHECK-NEXT: .globl rw_s1 +; CHECK: .section s2,"a",@progbits,unique,[[#UNIQUE_S2_a:]] +; CHECK-NEXT: .globl ro_s2 + +; Values declared without explicit sections +@rw_nosec = global i32 10, align 4 +@ro_nosec = constant i32 10, align 4 +; CHECK: .data{{$}} +; CHECK-NEXT: .globl rw_nosec +; CHECK: .section .rodata,"a",@progbits{{$}} +; CHECK-NEXT: .globl ro_nosec + +; Explicit sections that shouldn't have section flags updated +@a = global [2 x i32] zeroinitializer, section ".rodata", align 4 +@b = global [4 x i32] zeroinitializer, section ".sdata", align 4 +@c = global [4 x i32] zeroinitializer, section ".sbss", align 4 +; CHECK: .section .rodata +; CHECK-NEXT: .globl a{{$}} +; CHECK: .section .sdata +; CHECK-NEXT: .globl b{{$}} +; CHECK: .section .sbss +; CHECK-NEXT: .globl c{{$}} + +; Normal user defined section +@ro_s3 = constant i32 10, section "s3", align 4 +@rw_s3 = global i32 10, section "s3", align 4 +; CHECK: .section s3,"a",@progbits{{$}} +; CHECK-NEXT: .globl ro_s3 +; CHECK: .section s3,"aw",@progbits,unique,[[#UNIQUE_S3_aw:]] +; CHECK-NEXT: .globl rw_s3 + +; Multiple .text sections are emitted +@rw_text = global i32 10, section ".text", align 4 +@ro_text = constant i32 10, section ".text", align 4 +; CHECK: .section .text,"aw",@progbits,unique,[[#UNIQUE_TEXT_aw:]] +; CHECK-NEXT: .globl rw_text +; CHECK: .section .text,"a",@progbits,unique,[[#UNIQUE_TEXT_a:]] +; CHECK-NEXT: .globl ro_text + +; A read-only .data section is emitted +@ro_data = constant i32 10, section ".data", align 4 +; CHECK: .section .data,"a",@progbits +; CHECK-NEXT: .globl ro_data + +; TLS and non-TLS symbols cannot live in the same section +@tls_var = thread_local global i32 10, section "s4", align 4 +@non_tls_var = global i32 10, section "s4", align 4 +; CHECK: .section s4,"awT",@progbits{{$}} +; CHECK-NEXT: .globl tls_var +; CHECK: .section s4,"aw",@progbits,unique,[[#UNIQUE_S4_aw:]] +; CHECK-NEXT: .globl non_tls_var diff --git a/llvm/test/CodeGen/Mips/gpopt-explict-section.ll b/llvm/test/CodeGen/Mips/gpopt-explict-section.ll --- a/llvm/test/CodeGen/Mips/gpopt-explict-section.ll +++ b/llvm/test/CodeGen/Mips/gpopt-explict-section.ll @@ -41,7 +41,7 @@ ; CHECK: .type a,@object -; CHECK: .section .rodata,"a",@progbits +; CHECK: .section .rodata,"aw",@progbits,unique,[[#ID:]] ; CHECK: .globl a ; CHECK: .type b,@object diff --git a/llvm/test/CodeGen/X86/explicit-section-mergeable.ll b/llvm/test/CodeGen/X86/explicit-section-mergeable.ll --- a/llvm/test/CodeGen/X86/explicit-section-mergeable.ll +++ b/llvm/test/CodeGen/X86/explicit-section-mergeable.ll @@ -36,7 +36,7 @@ ;; Basic checks that mergeable globals are placed into multiple distinct ;; sections with the same name and a compatible entry size. -; CHECK: .section .explicit_basic,"aM",@progbits,4,unique,3 +; CHECK: .section .explicit_basic,"aM",@progbits,4 ; CHECK: explicit_basic_1: ; CHECK: explicit_basic_2: @@ -45,7 +45,7 @@ ;; Assign a compatible mergeable global to the previous section. @explicit_basic_2 = unnamed_addr constant [2 x i16] [i16 1, i16 1], section ".explicit_basic" -; CHECK: .section .explicit_basic,"aM",@progbits,8,unique,4 +; CHECK: .section .explicit_basic,"aM",@progbits,8,unique,3 ; CHECK: explicit_basic_3: ; CHECK: explicit_basic_4: @@ -54,7 +54,7 @@ ;; Assign a compatible mergeable global to the previous section. @explicit_basic_4 = unnamed_addr constant [2 x i32] [i32 1, i32 1], section ".explicit_basic" -; CHECK: .section .explicit_basic,"aMS",@progbits,4,unique,5 +; CHECK: .section .explicit_basic,"aMS",@progbits,4,unique,4 ; CHECK: explicit_basic_5: ; CHECK: explicit_basic_6: @@ -63,13 +63,13 @@ ;; Assign a compatible mergeable global to the previous section. @explicit_basic_6 = unnamed_addr constant [2 x i32] [i32 1, i32 0], section ".explicit_basic" -; CHECK: .section .explicit_basic,"a",@progbits +; CHECK: .section .explicit_basic,"a",@progbits,unique,5 ; CHECK: explicit_basic_7: ;; Assign a symbol with an incompatible entsize (non-mergeable) to a mergeable section created explicitly. @explicit_basic_7 = constant [2 x i16] [i16 1, i16 1], section ".explicit_basic" -; CHECK: .section .explicit_initially_nonmergeable,"a",@progbits +; CHECK: .section .explicit_initially_nonmergeable,"a",@progbits{{$}} ; CHECK: explicit_basic_8: ; CHECK: .section .explicit_initially_nonmergeable,"aM",@progbits,4,unique,6 ; CHECK: explicit_basic_9: @@ -78,7 +78,7 @@ @explicit_basic_8 = constant [2 x i16] [i16 1, i16 1], section ".explicit_initially_nonmergeable" @explicit_basic_9 = unnamed_addr constant [2 x i16] [i16 1, i16 1], section ".explicit_initially_nonmergeable" -; CHECK: .section .explicit_initially_nonmergeable,"a",@progbits +; CHECK: .section .explicit_initially_nonmergeable,"a",@progbits{{$}} ; CHECK: explicit_basic_10: ; CHECK: .section .explicit_initially_nonmergeable,"aM",@progbits,4,unique,6 ; CHECK: explicit_basic_11: @@ -101,22 +101,22 @@ ;; Assign a compatible global to a "default" mergeable section. @explicit_default_2 = unnamed_addr constant [2 x i64] [i64 1, i64 1], section ".rodata.cst16" -; CHECK: .section .debug_str,"MS",@progbits,1 +; CHECK: .section .debug_str,"aMS",@progbits,1,unique,8 ; CHECK: explicit_default_3: ;; Non-allocatable "default" sections can have allocatable mergeable symbols with compatible entry sizes assigned to them. @explicit_default_3 = unnamed_addr constant [2 x i8] [i8 1, i8 0], section ".debug_str" -; CHECK: .section .debug_str,"a",@progbits,unique,8 +; CHECK: .section .debug_str,"a",@progbits,unique,9 ; CHECK: explicit_default_4: ;; Non-allocatable "default" sections cannot have allocatable mergeable symbols with incompatible (non-mergeable) entry sizes assigned to them. @explicit_default_4 = constant [2 x i16] [i16 1, i16 1], section ".debug_str" ;; Test implicit section assignment for globals with associated globals. -; CHECK: .section .rodata.cst4,"aMo",@progbits,4,implicit_rodata_cst4,unique,9 +; CHECK: .section .rodata.cst4,"aMo",@progbits,4,implicit_rodata_cst4,unique,10 ; CHECK: implicit_rodata_cst4_assoc: -; CHECK: .section .rodata.cst8,"aMo",@progbits,8,implicit_rodata_cst4,unique,10 +; CHECK: .section .rodata.cst8,"aMo",@progbits,8,implicit_rodata_cst4,unique,11 ; CHECK: implicit_rodata_cst8_assoc: @implicit_rodata_cst4_assoc = unnamed_addr constant [2 x i16] [i16 1, i16 1], !associated !4 @@ -125,11 +125,11 @@ ;; Check that globals with associated globals that are explicitly assigned ;; to a section have been placed into distinct sections with the same name, but ;; different entry sizes. -; CHECK: .section .explicit,"aMo",@progbits,4,implicit_rodata_cst4,unique,11 -; CHECK: explicit_assoc_1: ; CHECK: .section .explicit,"aMo",@progbits,4,implicit_rodata_cst4,unique,12 +; CHECK: explicit_assoc_1: +; CHECK: .section .explicit,"aMo",@progbits,4,implicit_rodata_cst4,unique,13 ; CHECK: explicit_assoc_2: -; CHECK: .section .explicit,"aMo",@progbits,8,implicit_rodata_cst4,unique,13 +; CHECK: .section .explicit,"aMo",@progbits,8,implicit_rodata_cst4,unique,14 ; CHECK: explicit_assoc_3: @explicit_assoc_1 = unnamed_addr constant [2 x i16] [i16 1, i16 1], section ".explicit", !associated !4 @@ -139,9 +139,9 @@ !4 = !{[2 x i16]* @implicit_rodata_cst4} ;; Test implicit section assignment for globals in distinct comdat groups. -; CHECK: .section .rodata.cst4,"aGM",@progbits,4,f,comdat,unique,14 +; CHECK: .section .rodata.cst4,"aGM",@progbits,4,f,comdat,unique,15 ; CHECK: implicit_rodata_cst4_comdat: -; CHECK: .section .rodata.cst8,"aGM",@progbits,8,g,comdat,unique,15 +; CHECK: .section .rodata.cst8,"aGM",@progbits,8,g,comdat,unique,16 ; CHECK: implicit_rodata_cst8_comdat: ;; Check that globals in distinct comdat groups that are explicitly assigned @@ -151,13 +151,13 @@ ;; appear incorrect as comdats are not taken into account when looking up the unique ID ;; for a mergeable section. However, as they have no effect it doesn't matter that they ;; are incorrect. -; CHECK: .section .explicit_comdat_distinct,"aM",@progbits,4,unique,16 +; CHECK: .section .explicit_comdat_distinct,"aM",@progbits,4{{$}} ; CHECK: explicit_comdat_distinct_supply_uid: -; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,f,comdat,unique,16 +; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,f,comdat,unique,17 ; CHECK: explicit_comdat_distinct1: -; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,g,comdat,unique,16 +; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,g,comdat,unique,17 ; CHECK: explicit_comdat_distinct2: -; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,8,h,comdat,unique,17 +; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,8,h,comdat,unique,18 ; CHECK: explicit_comdat_distinct3: $f = comdat any @@ -173,9 +173,9 @@ @explicit_comdat_distinct3 = unnamed_addr constant [2 x i32] [i32 1, i32 1], section ".explicit_comdat_distinct", comdat($h) ;; Test implicit section assignment for globals in the same comdat group. -; CHECK: .section .rodata.cst4,"aGM",@progbits,4,i,comdat,unique,18 +; CHECK: .section .rodata.cst4,"aGM",@progbits,4,i,comdat,unique,19 ; CHECK: implicit_rodata_cst4_same_comdat: -; CHECK: .section .rodata.cst8,"aGM",@progbits,8,i,comdat,unique,19 +; CHECK: .section .rodata.cst8,"aGM",@progbits,8,i,comdat,unique,20 ; CHECK: implicit_rodata_cst8_same_comdat: ;; Check that globals in the same comdat group that are explicitly assigned @@ -185,12 +185,12 @@ ;; appear incorrect as comdats are not taken into account when looking up the unique ID ;; for a mergeable section. However, as they have no effect it doesn't matter that they ;; are incorrect. -; CHECK: .section .explicit_comdat_same,"aM",@progbits,4,unique,20 +; CHECK: .section .explicit_comdat_same,"aM",@progbits,4{{$}} ; CHECK: explicit_comdat_same_supply_uid: -; CHECK: .section .explicit_comdat_same,"aGM",@progbits,4,i,comdat,unique,20 +; CHECK: .section .explicit_comdat_same,"aGM",@progbits,4,i,comdat,unique,21 ; CHECK: explicit_comdat_same1: ; CHECK: explicit_comdat_same2: -; CHECK: .section .explicit_comdat_same,"aGM",@progbits,8,i,comdat,unique,21 +; CHECK: .section .explicit_comdat_same,"aGM",@progbits,8,i,comdat,unique,22 ; CHECK: explicit_comdat_same3: $i = comdat any @@ -206,7 +206,7 @@ ;; Check interaction between symbols that are explicitly assigned ;; to a section and implicitly assigned symbols. -; CHECK: .section .rodata.str1.1,"aMS",@progbits,1 +; CHECK: .section .rodata.str1.1,"aMS",@progbits,1{{$}} ; CHECK: implicit_rodata_str1_1: ; CHECK: explicit_implicit_1: @@ -214,7 +214,7 @@ @implicit_rodata_str1_1 = unnamed_addr constant [2 x i8] [i8 1, i8 0] @explicit_implicit_1 = unnamed_addr constant [2 x i8] [i8 1, i8 0], section ".rodata.str1.1" -; CHECK: .section .rodata.str1.1,"a",@progbits,unique,22 +; CHECK: .section .rodata.str1.1,"a",@progbits,unique,23 ; CHECK: explicit_implicit_2: ;; Assign an incompatible symbol (non-mergeable) to an existing mergeable section created implicitly. @@ -222,14 +222,14 @@ ; CHECK: .section .rodata.str1.1,"aMS",@progbits,1 ; CHECK: explicit_implicit_3: -; CHECK: .section .rodata.str1.1,"a",@progbits,unique,22 +; CHECK: .section .rodata.str1.1,"a",@progbits,unique,23 ; CHECK: explicit_implicit_4: ;; Assign compatible globals to the previously created sections. @explicit_implicit_3 = unnamed_addr constant [2 x i8] [i8 1, i8 0], section ".rodata.str1.1" @explicit_implicit_4 = constant [2 x i16] [i16 1, i16 1], section ".rodata.str1.1" -; CHECK: .section .rodata.str2.2,"aMS",@progbits,2 +; CHECK: .section .rodata.str2.2,"aMS",@progbits,2{{$}} ; CHECK: explicit_implicit_5: ; CHECK: implicit_rodata_str2_2: @@ -239,21 +239,21 @@ ;; Check the interaction with inline asm. -; CHECK: .section .asm_mergeable1,"aMS",@progbits,2 +; CHECK: .section .asm_mergeable1,"aMS",@progbits,2{{$}} ; CHECK: explicit_asm_1: -; CHECK: .section .asm_nonmergeable1,"a",@progbits +; CHECK: .section .asm_nonmergeable1,"a",@progbits{{$}} ; CHECK: explicit_asm_2: -; CHECK: .section .asm_mergeable1,"aM",@progbits,4,unique,23 +; CHECK: .section .asm_mergeable1,"aM",@progbits,4,unique,24 ; CHECK: explicit_asm_3: -; CHECK: .section .asm_nonmergeable1,"aMS",@progbits,2,unique,24 +; CHECK: .section .asm_nonmergeable1,"aMS",@progbits,2,unique,25 ; CHECK: explicit_asm_4: -; CHECK: .section .asm_mergeable2,"aM",@progbits,4,unique,25 +; CHECK: .section .asm_mergeable2,"aM",@progbits,4,unique,26 ; CHECK: explicit_asm_5: -; CHECK: .section .asm_nonmergeable2,"aMS",@progbits,2,unique,26 +; CHECK: .section .asm_nonmergeable2,"aMS",@progbits,2,unique,27 ; CHECK: explicit_asm_6: -; CHECK: .section .asm_mergeable2,"aMS",@progbits,2 +; CHECK: .section .asm_mergeable2,"aMS",@progbits,2{{$}} ; CHECK: explicit_asm_7: -; CHECK: .section .asm_nonmergeable2,"a",@progbits +; CHECK: .section .asm_nonmergeable2,"a",@progbits{{$}} ; CHECK: explicit_asm_8: module asm ".section .asm_mergeable1,\22aMS\22,@progbits,2" @@ -299,4 +299,4 @@ ; RUN: | FileCheck %s --check-prefix=NO-I-AS-NEW ; RUN: llc < %t.no_i_as.ll -mtriple=x86_64 --no-integrated-as -binutils-version=none 2>&1 \ ; RUN: | FileCheck %s --check-prefix=NO-I-AS-NEW -; NO-I-AS-NEW: .section .explicit,"aM",@progbits,4,unique,1 +; NO-I-AS-NEW: .section .explicit,"aM",@progbits,4{{$}}