[llvm] [COFF] Preserve UniqueID used to create MCSectionCOFF (PR #123869)

Haohai Wen via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 17 19:51:44 PST 2025


https://github.com/HaohaiWen updated https://github.com/llvm/llvm-project/pull/123869

>From 7c531922f20bf284a5cd83b20e94cb624ef031d2 Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Thu, 9 Jan 2025 15:29:33 +0800
Subject: [PATCH 1/2] [COFF] Preserve UniqueID used to create MCSectionCOFF

This UniqueID can be used later to create associative section.
e.g. A .pseudo_probe associated to the section of the corresponding
function.
---
 llvm/include/llvm/MC/MCSectionCOFF.h | 9 +++++++--
 llvm/lib/MC/MCContext.cpp            | 2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h
index 97540d985dbd1..9c79c27f2a915 100644
--- a/llvm/include/llvm/MC/MCSectionCOFF.h
+++ b/llvm/include/llvm/MC/MCSectionCOFF.h
@@ -47,16 +47,19 @@ class MCSectionCOFF final : public MCSection {
   /// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
   mutable int Selection;
 
+  unsigned UniqueID;
+
 private:
   friend class MCContext;
   // The storage of Name is owned by MCContext's COFFUniquingMap.
   MCSectionCOFF(StringRef Name, unsigned Characteristics,
-                MCSymbol *COMDATSymbol, int Selection, MCSymbol *Begin)
+                MCSymbol *COMDATSymbol, int Selection, unsigned UniqueID,
+                MCSymbol *Begin)
       : MCSection(SV_COFF, Name, Characteristics & COFF::IMAGE_SCN_CNT_CODE,
                   Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA,
                   Begin),
         Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
-        Selection(Selection) {
+        Selection(Selection), UniqueID(UniqueID) {
     assert((Characteristics & 0x00F00000) == 0 &&
            "alignment must not be set upon section creation");
   }
@@ -72,6 +75,8 @@ class MCSectionCOFF final : public MCSection {
 
   void setSelection(int Selection) const;
 
+  unsigned getUniqueID() const { return UniqueID; }
+
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                             raw_ostream &OS,
                             uint32_t Subsection) const override;
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 46222fcaa5b15..56aba5de4445e 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -718,7 +718,7 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
   StringRef CachedName = Iter->first.SectionName;
   MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section);
   MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
-      CachedName, Characteristics, COMDATSymbol, Selection, Begin);
+      CachedName, Characteristics, COMDATSymbol, Selection, UniqueID, Begin);
   Iter->second = Result;
   auto *F = allocInitialFragment(*Result);
   Begin->setFragment(F);

>From a7fd88567919801620303a42a695e7d0d0ab4d44 Mon Sep 17 00:00:00 2001
From: Haohai Wen <haohai.wen at intel.com>
Date: Tue, 18 Feb 2025 11:51:20 +0800
Subject: [PATCH 2/2] Support unique for coff asm

---
 .../llvm/MC/MCParser/MCAsmParserExtension.h   |  2 +
 llvm/include/llvm/MC/MCSectionCOFF.h          |  1 +
 llvm/lib/MC/MCParser/COFFAsmParser.cpp        | 21 ++++--
 llvm/lib/MC/MCParser/ELFAsmParser.cpp         | 23 -------
 llvm/lib/MC/MCParser/MCAsmParserExtension.cpp | 22 ++++++
 llvm/lib/MC/MCSectionCOFF.cpp                 | 10 ++-
 llvm/test/CodeGen/X86/constructor.ll          |  4 +-
 llvm/test/CodeGen/X86/ctor-priority-coff.ll   |  4 +-
 llvm/test/CodeGen/X86/data-section-prefix.ll  |  8 +--
 llvm/test/CodeGen/X86/dtor-priority-coff.ll   |  2 +-
 llvm/test/CodeGen/X86/global-sections.ll      | 18 ++---
 llvm/test/CodeGen/X86/mingw-comdats.ll        | 18 ++---
 llvm/test/CodeGen/X86/text-section-prefix.ll  |  8 +--
 llvm/test/MC/COFF/global_ctors_dtors.ll       |  4 +-
 llvm/test/MC/COFF/section-unique.s            | 67 +++++++++++++++++++
 15 files changed, 148 insertions(+), 64 deletions(-)
 create mode 100644 llvm/test/MC/COFF/section-unique.s

diff --git a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
index f1c1b2641ab15..b409a857e0091 100644
--- a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -100,6 +100,8 @@ class MCAsmParserExtension {
 
   bool parseDirectiveCGProfile(StringRef, SMLoc);
 
+  bool maybeParseUniqueID(int64_t &UniqueID);
+
   bool check(bool P, const Twine &Msg) {
     return getParser().check(P, Msg);
   }
diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h
index 9c79c27f2a915..4472a128caa6b 100644
--- a/llvm/include/llvm/MC/MCSectionCOFF.h
+++ b/llvm/include/llvm/MC/MCSectionCOFF.h
@@ -75,6 +75,7 @@ class MCSectionCOFF final : public MCSection {
 
   void setSelection(int Selection) const;
 
+  bool isUnique() const { return UniqueID != NonUniqueID; }
   unsigned getUniqueID() const { return UniqueID; }
 
   void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index 4618e5675e47b..eb15d063be74b 100644
--- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -38,12 +38,12 @@ class COFFAsmParser : public MCAsmParserExtension {
   bool parseSectionSwitch(StringRef Section, unsigned Characteristics);
 
   bool parseSectionSwitch(StringRef Section, unsigned Characteristics,
-                          StringRef COMDATSymName, COFF::COMDATType Type);
+                          StringRef COMDATSymName, COFF::COMDATType Type,
+                          unsigned UniqueID);
 
   bool parseSectionName(StringRef &SectionName);
   bool parseSectionFlags(StringRef SectionName, StringRef FlagsString,
                          unsigned *Flags);
-
   void Initialize(MCAsmParser &Parser) override {
     // Call the base implementation.
     MCAsmParserExtension::Initialize(Parser);
@@ -315,19 +315,21 @@ bool COFFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
 
 bool COFFAsmParser::parseSectionSwitch(StringRef Section,
                                        unsigned Characteristics) {
-  return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0);
+  return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0,
+                            MCSection::NonUniqueID);
 }
 
 bool COFFAsmParser::parseSectionSwitch(StringRef Section,
                                        unsigned Characteristics,
                                        StringRef COMDATSymName,
-                                       COFF::COMDATType Type) {
+                                       COFF::COMDATType Type,
+                                       unsigned UniqueID) {
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in section switching directive");
   Lex();
 
   getStreamer().switchSection(getContext().getCOFFSection(
-      Section, Characteristics, COMDATSymName, Type));
+      Section, Characteristics, COMDATSymName, Type, UniqueID));
 
   return false;
 }
@@ -386,7 +388,8 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
 
   COFF::COMDATType Type = (COFF::COMDATType)0;
   StringRef COMDATSymName;
-  if (getLexer().is(AsmToken::Comma)) {
+  if (getLexer().is(AsmToken::Comma) &&
+      getLexer().peekTok().getString() != "unique") {
     Type = COFF::IMAGE_COMDAT_SELECT_ANY;
     Lex();
 
@@ -407,6 +410,10 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
       return TokError("expected identifier in directive");
   }
 
+  int64_t UniqueID = MCSection::NonUniqueID;
+  if (maybeParseUniqueID(UniqueID))
+    return true;
+
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
@@ -415,7 +422,7 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
     if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
       Flags |= COFF::IMAGE_SCN_MEM_16BIT;
   }
-  parseSectionSwitch(SectionName, Flags, COMDATSymName, Type);
+  parseSectionSwitch(SectionName, Flags, COMDATSymName, Type, UniqueID);
   return false;
 }
 
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 99b13c68a9966..04496ed694f3a 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -158,7 +158,6 @@ class ELFAsmParser : public MCAsmParserExtension {
   bool parseMergeSize(int64_t &Size);
   bool parseGroup(StringRef &GroupName, bool &IsComdat);
   bool parseLinkedToSym(MCSymbolELF *&LinkedToSym);
-  bool maybeParseUniqueID(int64_t &UniqueID);
 };
 
 } // end anonymous namespace
@@ -495,28 +494,6 @@ bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
   return false;
 }
 
-bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
-  MCAsmLexer &L = getLexer();
-  if (L.isNot(AsmToken::Comma))
-    return false;
-  Lex();
-  StringRef UniqueStr;
-  if (getParser().parseIdentifier(UniqueStr))
-    return TokError("expected identifier");
-  if (UniqueStr != "unique")
-    return TokError("expected 'unique'");
-  if (L.isNot(AsmToken::Comma))
-    return TokError("expected commma");
-  Lex();
-  if (getParser().parseAbsoluteExpression(UniqueID))
-    return true;
-  if (UniqueID < 0)
-    return TokError("unique id must be positive");
-  if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
-    return TokError("unique id is too large");
-  return false;
-}
-
 static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
   return SectionName.consume_front(Prefix) &&
          (SectionName.empty() || SectionName[0] == '.');
diff --git a/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp b/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp
index 444ce395a4dea..1b83e0412cc2b 100644
--- a/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp
+++ b/llvm/lib/MC/MCParser/MCAsmParserExtension.cpp
@@ -62,3 +62,25 @@ bool MCAsmParserExtension::parseDirectiveCGProfile(StringRef, SMLoc) {
       Count);
   return false;
 }
+
+bool MCAsmParserExtension::maybeParseUniqueID(int64_t &UniqueID) {
+  MCAsmLexer &L = getLexer();
+  if (L.isNot(AsmToken::Comma))
+    return false;
+  Lex();
+  StringRef UniqueStr;
+  if (getParser().parseIdentifier(UniqueStr))
+    return TokError("expected identifier");
+  if (UniqueStr != "unique")
+    return TokError("expected 'unique'");
+  if (L.isNot(AsmToken::Comma))
+    return TokError("expected commma");
+  Lex();
+  if (getParser().parseAbsoluteExpression(UniqueID))
+    return true;
+  if (UniqueID < 0)
+    return TokError("unique id must be positive");
+  if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
+    return TokError("unique id is too large");
+  return false;
+}
diff --git a/llvm/lib/MC/MCSectionCOFF.cpp b/llvm/lib/MC/MCSectionCOFF.cpp
index 1389772502802..94e29ce27d881 100644
--- a/llvm/lib/MC/MCSectionCOFF.cpp
+++ b/llvm/lib/MC/MCSectionCOFF.cpp
@@ -18,7 +18,7 @@ using namespace llvm;
 // should be printed before the section name
 bool MCSectionCOFF::shouldOmitSectionDirective(StringRef Name,
                                                const MCAsmInfo &MAI) const {
-  if (COMDATSymbol)
+  if (COMDATSymbol || isUnique())
     return false;
 
   // FIXME: Does .section .bss/.data/.text work everywhere??
@@ -67,6 +67,10 @@ void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
     OS << 'i';
   OS << '"';
 
+  // unique should be tail of .section directive.
+  if (isUnique() && !COMDATSymbol)
+    OS << ",unique," << UniqueID;
+
   if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
     if (COMDATSymbol)
       OS << ",";
@@ -103,6 +107,10 @@ void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
       COMDATSymbol->print(OS, &MAI);
     }
   }
+
+  if (isUnique() && COMDATSymbol)
+    OS << ",unique," << UniqueID;
+
   OS << '\n';
 }
 
diff --git a/llvm/test/CodeGen/X86/constructor.ll b/llvm/test/CodeGen/X86/constructor.ll
index 3133979b32f83..f46325db8c19e 100644
--- a/llvm/test/CodeGen/X86/constructor.ll
+++ b/llvm/test/CodeGen/X86/constructor.ll
@@ -77,10 +77,10 @@ entry:
 ; MCU-CTORS:         .section        .ctors,"aw", at progbits
 ; MCU-INIT-ARRAY:    .section        .init_array,"aw", at init_array
 
-; COFF-CTOR:		.section	.ctors.65520,"dw",associative,v
+; COFF-CTOR:		.section	.ctors.65520,"dw",associative,v,unique,0
 ; COFF-CTOR-NEXT:	.p2align	3
 ; COFF-CTOR-NEXT:	.quad	g
-; COFF-CTOR-NEXT:	.section	.ctors.09980,"dw",associative,v
+; COFF-CTOR-NEXT:	.section	.ctors.09980,"dw",associative,v,unique,0
 ; COFF-CTOR-NEXT:	.p2align	3
 ; COFF-CTOR-NEXT:	.quad	h
 ; COFF-CTOR-NEXT:	.section	.ctors,"dw"
diff --git a/llvm/test/CodeGen/X86/ctor-priority-coff.ll b/llvm/test/CodeGen/X86/ctor-priority-coff.ll
index 2e4e7ca0c5dcf..c99eb4e51d79d 100644
--- a/llvm/test/CodeGen/X86/ctor-priority-coff.ll
+++ b/llvm/test/CodeGen/X86/ctor-priority-coff.ll
@@ -12,13 +12,13 @@
 ; CHECK: .section        .CRT$XCC00250,"dr"
 ; CHECK: .p2align        3
 ; CHECK: .quad   k
-; CHECK: .section        .CRT$XCL,"dr"
+; CHECK: .section        .CRT$XCL,"dr",unique,0
 ; CHECK: .p2align        3
 ; CHECK: .quad   j
 ; CHECK: .section        .CRT$XCT12345,"dr"
 ; CHECK: .p2align        3
 ; CHECK: .quad   g
-; CHECK: .section        .CRT$XCT23456,"dr",associative,h
+; CHECK: .section        .CRT$XCT23456,"dr",associative,h,unique,0
 ; CHECK: .p2align        3
 ; CHECK: .quad   init_h
 
diff --git a/llvm/test/CodeGen/X86/data-section-prefix.ll b/llvm/test/CodeGen/X86/data-section-prefix.ll
index 4812fc70758fb..36e0527eb3c06 100644
--- a/llvm/test/CodeGen/X86/data-section-prefix.ll
+++ b/llvm/test/CodeGen/X86/data-section-prefix.ll
@@ -13,10 +13,10 @@
 ; ELF-NOUNIQ: .section    .bss.unlikely.,"aw", at nobits,unique,3
 ; ELF-NOUNIQ: .section    .bss,"aw", at nobits,unique,4
 
-; COFF-MSVC: .section .data,"dw",one_only,foo
-; COFF-MSVC: .section .data,"dw",one_only,bar
-; COFF-MSVC: .section .bss,"bw",one_only,baz
-; COFF-MSVC: .section .bss,"bw",one_only,quz
+; COFF-MSVC: .section .data,"dw",one_only,foo,unique,0
+; COFF-MSVC: .section .data,"dw",one_only,bar,unique,1
+; COFF-MSVC: .section .bss,"bw",one_only,baz,unique,2
+; COFF-MSVC: .section .bss,"bw",one_only,quz,unique,3
 
 @foo = global i32 1, !section_prefix !0
 @bar = global i32 2
diff --git a/llvm/test/CodeGen/X86/dtor-priority-coff.ll b/llvm/test/CodeGen/X86/dtor-priority-coff.ll
index a170690b69441..8a7b0379d2373 100644
--- a/llvm/test/CodeGen/X86/dtor-priority-coff.ll
+++ b/llvm/test/CodeGen/X86/dtor-priority-coff.ll
@@ -9,7 +9,7 @@
 ; CHECK: .section        .CRT$XTT12345,"dr"
 ; CHECK: .p2align        3
 ; CHECK: .quad   g
-; CHECK: .section        .CRT$XTT23456,"dr",associative,h
+; CHECK: .section        .CRT$XTT23456,"dr",associative,h,unique,0
 ; CHECK: .p2align        3
 ; CHECK: .quad   init_h
 ; CHECK: .section        .CRT$XTX,"dr"
diff --git a/llvm/test/CodeGen/X86/global-sections.ll b/llvm/test/CodeGen/X86/global-sections.ll
index b300fc87e38ab..4199481a1f299 100644
--- a/llvm/test/CodeGen/X86/global-sections.ll
+++ b/llvm/test/CodeGen/X86/global-sections.ll
@@ -12,7 +12,7 @@ define void @F1() {
   ret void
 }
 
-; WIN32-SECTIONS: .section        .text,"xr",one_only,_F1
+; WIN32-SECTIONS: .section        .text,"xr",one_only,_F1,unique,0
 ; WIN32-SECTIONS: .globl _F1
 
 define void @F2(i32 %y) {
@@ -49,9 +49,9 @@ bb5:
 ; LINUX-FUNC-SECTIONS-NEXT: .cfi_endproc
 ; LINUX-FUNC-SECTIONS-NEXT: .section        .rodata.F2,"a", at progbits
 
-; WIN32-FUNC-SECTIONS: .section        .text,"xr",one_only,_F2
+; WIN32-FUNC-SECTIONS: .section        .text,"xr",one_only,_F2,unique,1
 ; WIN32-FUNC-SECTIONS-NOT: .section
-; WIN32-FUNC-SECTIONS: .section        .rdata,"dr",associative,_F2
+; WIN32-FUNC-SECTIONS: .section        .rdata,"dr",associative,_F2,unique,2
 
 
 ; LINUX-SECTIONS-PIC: .section        .text.F2,"ax", at progbits
@@ -138,7 +138,7 @@ bb7:
 ; LINUX-SECTIONS: .section        .rodata.G3,"a", at progbits
 ; LINUX-SECTIONS: .globl  G3
 
-; WIN32-SECTIONS: .section        .rdata,"dr",one_only,_G3
+; WIN32-SECTIONS: .section        .rdata,"dr",one_only,_G3,unique,6
 ; WIN32-SECTIONS: .globl  _G3
 
 
@@ -213,7 +213,7 @@ bb7:
 ; LINUX-SECTIONS: .section        .rodata.str1.1,"aMS", at progbits,1
 ; LINUX-SECTIONS:       .globl G7
 
-; WIN32-SECTIONS: .section        .rdata,"dr",one_only,_G7
+; WIN32-SECTIONS: .section        .rdata,"dr",one_only,_G7,unique,11
 ; WIN32-SECTIONS:       .globl _G7
 
 
@@ -276,7 +276,7 @@ bb7:
 ; LINUX-SECTIONS:        .asciz  "foo"
 ; LINUX-SECTIONS:        .size   .LG14, 4
 
-; WIN32-SECTIONS:        .section        .rdata,"dr",one_only,_G14
+; WIN32-SECTIONS:        .section        .rdata,"dr",one_only,_G14,unique,18
 ; WIN32-SECTIONS: _G14:
 ; WIN32-SECTIONS:        .asciz  "foo"
 
@@ -298,7 +298,7 @@ bb7:
 ; LINUX-SECTIONS: .section      .rodata.cst8,"aM", at progbits,8
 ; LINUX-SECTIONS: G15:
 
-; WIN32-SECTIONS: .section      .rdata,"dr",one_only,_G15
+; WIN32-SECTIONS: .section      .rdata,"dr",one_only,_G15,unique,19
 ; WIN32-SECTIONS: _G15:
 
 @G16 = unnamed_addr constant i256 0
@@ -309,7 +309,7 @@ bb7:
 ; LINUX-SECTIONS: .section      .rodata.cst32,"aM", at progbits,32
 ; LINUX-SECTIONS: G16:
 
-; WIN32-SECTIONS: .section      .rdata,"dr",one_only,_G16
+; WIN32-SECTIONS: .section      .rdata,"dr",one_only,_G16,unique,20
 ; WIN32-SECTIONS: _G16:
 
 ; PR26570
@@ -326,7 +326,7 @@ bb7:
 ; LINUX-SECTIONS: .byte	0
 ; LINUX-SECTIONS: .size	G17, 1
 
-; WIN32-SECTIONS: .section	.bss,"bw",one_only,_G17
+; WIN32-SECTIONS: .section	.bss,"bw",one_only,_G17,unique,21
 ; WIN32-SECTIONS: _G17:
 ; WIN32-SECTIONS:.byte	0
 
diff --git a/llvm/test/CodeGen/X86/mingw-comdats.ll b/llvm/test/CodeGen/X86/mingw-comdats.ll
index 01c8c03161292..bca8e12ea3c73 100644
--- a/llvm/test/CodeGen/X86/mingw-comdats.ll
+++ b/llvm/test/CodeGen/X86/mingw-comdats.ll
@@ -27,11 +27,11 @@ entry:
   ret i32 %call
 }
 
-; CHECK: .section        .text,"xr",one_only,main
+; CHECK: .section        .text,"xr",one_only,main,unique,0
 ; CHECK: main:
-; GNU: .section        .text$main,"xr",one_only,main
+; GNU: .section        .text$main,"xr",one_only,main,unique,0
 ; GNU: main:
-; GNU32: .section        .text$main,"xr",one_only,_main
+; GNU32: .section        .text$main,"xr",one_only,_main,unique,0
 ; GNU32: _main:
 
 define dso_local x86_fastcallcc i32 @fastcall(i32 %x, i32 %y) {
@@ -39,11 +39,11 @@ define dso_local x86_fastcallcc i32 @fastcall(i32 %x, i32 %y) {
   ret i32 %rv
 }
 
-; CHECK: .section        .text,"xr",one_only,fastcall
+; CHECK: .section        .text,"xr",one_only,fastcall,unique,1
 ; CHECK: fastcall:
-; GNU: .section        .text$fastcall,"xr",one_only,fastcall
+; GNU: .section        .text$fastcall,"xr",one_only,fastcall,unique,1
 ; GNU: fastcall:
-; GNU32: .section        .text$fastcall,"xr",one_only, at fastcall@8
+; GNU32: .section        .text$fastcall,"xr",one_only, at fastcall@8,unique,1
 ; GNU32: @fastcall at 8:
 
 ; Function Attrs: inlinehint uwtable
@@ -55,19 +55,19 @@ entry:
   ret i32 %add
 }
 
-; CHECK: .section        .text,"xr",discard,_Z3fooi
+; CHECK: .section        .text,"xr",discard,_Z3fooi,unique,2
 ; CHECK: _Z3fooi:
 ; CHECK: .section        .data,"dw",discard,gv
 ; CHECK: gv:
 ; CHECK: .long 42
 
-; GNU: .section        .text$_Z3fooi,"xr",discard,_Z3fooi
+; GNU: .section        .text$_Z3fooi,"xr",discard,_Z3fooi,unique,2
 ; GNU: _Z3fooi:
 ; GNU: .section        .data$gv,"dw",discard,gv
 ; GNU: gv:
 ; GNU: .long 42
 
-; GNU32: .section        .text$_Z3fooi,"xr",discard,__Z3fooi
+; GNU32: .section        .text$_Z3fooi,"xr",discard,__Z3fooi,unique,2
 ; GNU32: __Z3fooi:
 ; GNU32: .section        .data$gv,"dw",discard,_gv
 ; GNU32: _gv:
diff --git a/llvm/test/CodeGen/X86/text-section-prefix.ll b/llvm/test/CodeGen/X86/text-section-prefix.ll
index 652f29cd331d0..43206c8e3b2a0 100644
--- a/llvm/test/CodeGen/X86/text-section-prefix.ll
+++ b/llvm/test/CodeGen/X86/text-section-prefix.ll
@@ -7,8 +7,8 @@ define void @foo1(i1 zeroext %0) nounwind !section_prefix !0 {
 ;; Check hot section name
 ; ELF:        .section  .text.hot.foo1,"ax", at progbits
 ; ELF-NOUNIQ: .section  .text.hot.,"ax", at progbits,unique,1
-; COFF-MSVC:  .section  .text$hot,"xr",one_only,foo1
-; COFF-GNU:   .section  .text$hot$foo1,"xr",one_only,foo1
+; COFF-MSVC:  .section  .text$hot,"xr",one_only,foo1,unique,0
+; COFF-GNU:   .section  .text$hot$foo1,"xr",one_only,foo1,unique,0
   ret void
 }
 
@@ -16,8 +16,8 @@ define void @foo2(i1 zeroext %0) nounwind !section_prefix !1 {
 ;; Check unlikely section name
 ; ELF:        .section  .text.unlikely.foo2,"ax", at progbits
 ; ELF-NOUNIQ: .section  .text.unlikely.,"ax", at progbits,unique,2
-; COFF-MSVC:  .section  .text$unlikely,"xr",one_only,foo2
-; COFF-GNU:   .section  .text$unlikely$foo2,"xr",one_only,foo2
+; COFF-MSVC:  .section  .text$unlikely,"xr",one_only,foo2,unique,1
+; COFF-GNU:   .section  .text$unlikely$foo2,"xr",one_only,foo2,unique,1
   ret void
 }
 
diff --git a/llvm/test/MC/COFF/global_ctors_dtors.ll b/llvm/test/MC/COFF/global_ctors_dtors.ll
index 7df4d3e500b54..6668ea196829e 100644
--- a/llvm/test/MC/COFF/global_ctors_dtors.ll
+++ b/llvm/test/MC/COFF/global_ctors_dtors.ll
@@ -51,14 +51,14 @@ define i32 @main() nounwind {
 
 ; WIN32: .section .CRT$XCU,"dr"
 ; WIN32: a_global_ctor
-; WIN32: .section .CRT$XCU,"dr",associative,{{_?}}b
+; WIN32: .section .CRT$XCU,"dr",associative,{{_?}}b,unique,0
 ; WIN32: b_global_ctor
 ; WIN32-NOT: c_global_ctor
 ; WIN32: .section .CRT$XTX,"dr"
 ; WIN32: a_global_dtor
 ; MINGW32: .section .ctors,"dw"
 ; MINGW32: a_global_ctor
-; MINGW32: .section .ctors,"dw",associative,{{_?}}b
+; MINGW32: .section .ctors,"dw",associative,{{_?}}b,unique,0
 ; MINGW32: b_global_ctor
 ; MINGW32-NOT: c_global_ctor
 ; MINGW32: .section .dtors,"dw"
diff --git a/llvm/test/MC/COFF/section-unique.s b/llvm/test/MC/COFF/section-unique.s
new file mode 100644
index 0000000000000..e14748d5e6662
--- /dev/null
+++ b/llvm/test/MC/COFF/section-unique.s
@@ -0,0 +1,67 @@
+// RUN: llvm-mc -triple x86_64-pc-windows-msvc %s -o - | FileCheck %s
+// RUN: llvm-mc -triple x86_64-pc-windows-msvc %s -filetype=obj -o - | llvm-readobj --symbols - | FileCheck %s --check-prefix=OBJ
+  .section        .text,"xr",unique,0
+      nop
+  .section        .text,"xr",one_only,main,unique,4294967293
+      nop
+  .section        .text,"xr",discard,"",unique,4294967294
+      nop
+
+// CHECK: .section        .text,"xr",unique,0
+
+// CHECK: .section        .text,"xr",one_only,main,unique,4294967293
+
+// CHECK:       .section        .text,"xr",unique,4294967294
+// CHECK-NEXT:  .linkonce       discard
+
+// OBJ-COUNT-4: Symbol {
+// OBJ-NEXT:      Name: .text
+// OBJ-NEXT:      Value: 0
+// OBJ-NEXT:      Section: .text (4)
+// OBJ-NEXT:      BaseType: Null (0x0)
+// OBJ-NEXT:      ComplexType: Null (0x0)
+// OBJ-NEXT:      StorageClass: Static (0x3)
+// OBJ-NEXT:      AuxSymbolCount: 1
+// OBJ-NEXT:      AuxSectionDef {
+// OBJ-NEXT:        Length: 1
+// OBJ-NEXT:        RelocationCount: 0
+// OBJ-NEXT:        LineNumberCount: 0
+// OBJ-NEXT:        Checksum: 0xF00F9344
+// OBJ-NEXT:        Number: 4
+// OBJ-NEXT:        Selection: 0x0
+// OBJ-NEXT:      }
+// OBJ-NEXT:    }
+// OBJ-NEXT:    Symbol {
+// OBJ-NEXT:      Name: .text
+// OBJ-NEXT:      Value: 0
+// OBJ-NEXT:      Section: .text (5)
+// OBJ-NEXT:      BaseType: Null (0x0)
+// OBJ-NEXT:      ComplexType: Null (0x0)
+// OBJ-NEXT:      StorageClass: Static (0x3)
+// OBJ-NEXT:      AuxSymbolCount: 1
+// OBJ-NEXT:      AuxSectionDef {
+// OBJ-NEXT:        Length: 1
+// OBJ-NEXT:        RelocationCount: 0
+// OBJ-NEXT:        LineNumberCount: 0
+// OBJ-NEXT:        Checksum: 0xF00F9344
+// OBJ-NEXT:        Number: 5
+// OBJ-NEXT:        Selection: NoDuplicates (0x1)
+// OBJ-NEXT:      }
+// OBJ-NEXT:    }
+// OBJ-COUNT-2: Symbol {
+// OBJ-NEXT:      Name: .text
+// OBJ-NEXT:      Value: 0
+// OBJ-NEXT:      Section: .text (6)
+// OBJ-NEXT:      BaseType: Null (0x0)
+// OBJ-NEXT:      ComplexType: Null (0x0)
+// OBJ-NEXT:      StorageClass: Static (0x3)
+// OBJ-NEXT:      AuxSymbolCount: 1
+// OBJ-NEXT:      AuxSectionDef {
+// OBJ-NEXT:        Length: 1
+// OBJ-NEXT:        RelocationCount: 0
+// OBJ-NEXT:        LineNumberCount: 0
+// OBJ-NEXT:        Checksum: 0xF00F9344
+// OBJ-NEXT:        Number: 6
+// OBJ-NEXT:        Selection: Any (0x2)
+// OBJ-NEXT:      }
+// OBJ-NEXT:    }



More information about the llvm-commits mailing list