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

>From ad2ca2b69e5ba4ba7b6808d9b716fdb269e6f2eb Mon Sep 17 00:00:00 2001
From: Haohai Wen <[email protected]>
Date: Tue, 7 Apr 2026 15:44:11 +0800
Subject: [PATCH 1/2] [X86][COFF] Enable basic-block-address-map emission

Enable -fbasic-block-address-map fo X86 COFF.
Add COFF section creation for .llvm_bb_addr_map.
---
 clang/lib/Driver/ToolChains/Clang.cpp         |  3 +-
 clang/test/Driver/basic-block-address-map.c   |  1 +
 llvm/include/llvm/Object/BBAddrMap.h          |  3 ++
 llvm/lib/MC/MCObjectFileInfo.cpp              | 45 +++++++++++++------
 ...sic-block-address-map-function-sections.ll | 32 +++++++++----
 .../CodeGen/X86/basic-block-address-map.ll    | 13 ++++--
 6 files changed, 70 insertions(+), 27 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 0d5722cd536f2..57f342273fef6 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6280,7 +6280,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
 
   if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_address_map,
                                options::OPT_fno_basic_block_address_map)) {
-    if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) {
+    if (((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) 
||
+        (Triple.isX86() && Triple.isOSBinFormatCOFF())) {
       if (A->getOption().matches(options::OPT_fbasic_block_address_map))
         A->render(Args, CmdArgs);
     } else {
diff --git a/clang/test/Driver/basic-block-address-map.c 
b/clang/test/Driver/basic-block-address-map.c
index 12393e8ebfd54..b11dbb3c65548 100644
--- a/clang/test/Driver/basic-block-address-map.c
+++ b/clang/test/Driver/basic-block-address-map.c
@@ -1,5 +1,6 @@
 // RUN: %clang -### --target=x86_64 -fbasic-block-address-map %s -S 2>&1 | 
FileCheck -check-prefix=CHECK-PRESENT %s
 // RUN: %clang -### --target=aarch64 -fbasic-block-address-map %s -S 2>&1 | 
FileCheck -check-prefix=CHECK-PRESENT %s
+// RUN: %clang -### --target=x86_64-pc-windows-msvc -fbasic-block-address-map 
%s -S 2>&1 | FileCheck -check-prefix=CHECK-PRESENT %s
 // CHECK-PRESENT: -fbasic-block-address-map
 
 // RUN: %clang -### --target=x86_64 -fno-basic-block-address-map %s -S 2>&1 | 
FileCheck %s --check-prefix=CHECK-ABSENT
diff --git a/llvm/include/llvm/Object/BBAddrMap.h 
b/llvm/include/llvm/Object/BBAddrMap.h
index 49c9b431822e0..4f710bc19951e 100644
--- a/llvm/include/llvm/Object/BBAddrMap.h
+++ b/llvm/include/llvm/Object/BBAddrMap.h
@@ -15,6 +15,7 @@
 #define LLVM_OBJECT_BBADDRMAP_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/BlockFrequency.h"
 #include "llvm/Support/BranchProbability.h"
 #include "llvm/Support/DataExtractor.h"
@@ -24,6 +25,8 @@
 namespace llvm {
 namespace object {
 
+inline constexpr StringLiteral BBAddrMapSectionName = ".llvm_bb_addr_map";
+
 // Struct representing the BBAddrMap for one function.
 struct BBAddrMap {
 
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 56a22241ae5d3..1e78e5fe2cc49 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -27,6 +27,7 @@
 #include "llvm/MC/MCSectionXCOFF.h"
 #include "llvm/MC/MCSymbolGOFF.h"
 #include "llvm/MC/SectionKind.h"
+#include "llvm/Object/BBAddrMap.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
@@ -1266,23 +1267,39 @@ MCObjectFileInfo::getStackSizesSection(const MCSection 
&TextSec) const {
 
 MCSection *
 MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
-  if (Ctx->getObjectFileType() != MCContext::IsELF)
-    return nullptr;
+  StringRef Name = object::BBAddrMapSectionName;
+  if (Ctx->getObjectFileType() == MCContext::IsELF) {
+    const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
+    unsigned Flags = ELF::SHF_LINK_ORDER;
+    StringRef GroupName;
+    if (const MCSymbol *Group = ElfSec.getGroup()) {
+      GroupName = Group->getName();
+      Flags |= ELF::SHF_GROUP;
+    }
 
-  const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
-  unsigned Flags = ELF::SHF_LINK_ORDER;
-  StringRef GroupName;
-  if (const MCSymbol *Group = ElfSec.getGroup()) {
-    GroupName = Group->getName();
-    Flags |= ELF::SHF_GROUP;
+    // Use the text section's begin symbol and unique ID to create a separate
+    // .llvm_bb_addr_map section associated with every unique text section.
+    return Ctx->getELFSection(
+        Name, ELF::SHT_LLVM_BB_ADDR_MAP, Flags, 0, GroupName, true,
+        ElfSec.getUniqueID(),
+        static_cast<const MCSymbolELF *>(TextSec.getBeginSymbol()));
+  } else if (Ctx->getObjectFileType() == MCContext::IsCOFF) {
+    StringRef COMDATSymName = "";
+    int Selection = 0;
+    unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                               COFF::IMAGE_SCN_MEM_DISCARDABLE |
+                               COFF::IMAGE_SCN_MEM_READ;
+    const auto &COFFSec = static_cast<const MCSectionCOFF &>(TextSec);
+    if (const MCSymbol *COMDATSym = COFFSec.getCOMDATSymbol()) {
+      COMDATSymName = COMDATSym->getName();
+      Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
+      Selection = COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
+    }
+    return Ctx->getCOFFSection(Name, Characteristics, COMDATSymName, Selection,
+                               COFFSec.getUniqueID());
   }
 
-  // Use the text section's begin symbol and unique ID to create a separate
-  // .llvm_bb_addr_map section associated with every unique text section.
-  return Ctx->getELFSection(
-      ".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP, Flags, 0, GroupName, 
true,
-      ElfSec.getUniqueID(),
-      static_cast<const MCSymbolELF *>(TextSec.getBeginSymbol()));
+  return nullptr;
 }
 
 MCSection *
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll 
b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
index 892fa009935d2..2f4be8ab9fd06 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map-function-sections.ll
@@ -1,15 +1,23 @@
-; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-address-map | 
FileCheck %s
+; RUN: llc < %s -mtriple=x86_64 -function-sections -basic-block-address-map | 
FileCheck %s --check-prefixes=CHECK,ELF,ELF-FS
+; RUN: llc < %s -mtriple=x86_64 -basic-block-address-map | FileCheck %s 
--check-prefixes=CHECK,ELF,ELF-NOFS
+; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -function-sections 
-basic-block-address-map | FileCheck %s --check-prefixes=CHECK,COFF-FS
+; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -basic-block-address-map | 
FileCheck %s --check-prefixes=CHECK,COFF-NOFS
 
 $_Z4fooTIiET_v = comdat any
 
 define dso_local i32 @_Z3barv() {
   ret i32 0
 }
-;; Check we add SHF_LINK_ORDER for .llvm_bb_addr_map and link it with the 
corresponding .text sections.
-; CHECK:               .section .text._Z3barv,"ax",@progbits
+;; For ELF, check we add SHF_LINK_ORDER for .llvm_bb_addr_map and link it with 
the corresponding .text sections.
+;; For COFF, it does not have SHF_LINK_ORDER like mechanism, we use function 
symbol to "link" them.
+; ELF-FS:              .section .text._Z3barv,"ax",@progbits
+; COFF-FS:             .section .text,"xr",one_only,_Z3barv
 ; CHECK-LABEL: _Z3barv:
 ; CHECK-NEXT:  [[BAR_BEGIN:.Lfunc_begin[0-9]+]]:
-; CHECK:               .section 
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3barv{{$}}
+; ELF-FS:              .section 
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3barv{{$}}
+; ELF-NOFS:            .section 
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text{{$}}
+; COFF-FS:             .section 
.llvm_bb_addr_map,"drD",associative,_Z3barv,unique,0{{$}}
+; COFF-NOFS:           .section .llvm_bb_addr_map,"drD"{{$}}
 ; CHECK-NEXT:          .byte  5                        # version
 ; CHECK-NEXT:          .short 0                        # feature
 ; CHECK-NEXT:          .quad [[BAR_BEGIN]]     # function address
@@ -19,10 +27,14 @@ define dso_local i32 @_Z3foov() {
   %1 = call i32 @_Z4fooTIiET_v()
   ret i32 %1
 }
-; CHECK:               .section .text._Z3foov,"ax",@progbits
+; ELF-FS:              .section .text._Z3foov,"ax",@progbits
+; COFF-FS:             .section .text,"xr",one_only,_Z3foov
 ; CHECK-LABEL: _Z3foov:
 ; CHECK-NEXT:  [[FOO_BEGIN:.Lfunc_begin[0-9]+]]:
-; CHECK:               .section  
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3foov{{$}}
+; ELF-FS:              .section 
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3foov{{$}}
+; ELF-NOFS:            .section 
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text{{$}}
+; COFF-FS:             .section 
.llvm_bb_addr_map,"drD",associative,_Z3foov,unique,1{{$}}
+; COFF-NOFS:           .section .llvm_bb_addr_map,"drD"{{$}}
 ; CHECK-NEXT:          .byte  5                        # version
 ; CHECK-NEXT:          .short 32                # feature
 ; CHECK-NEXT:          .quad [[FOO_BEGIN]]     # function address
@@ -32,10 +44,14 @@ define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat {
   ret i32 0
 }
 ;; Check we add .llvm_bb_addr_map section to a COMDAT group with the 
corresponding .text section if such a COMDAT exists.
-; CHECK:               .section 
.text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat
+; ELF:                 .section 
.text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat
+; COFF-FS:             .section .text,"xr",discard,_Z4fooTIiET_v,unique,2{{$}}
+; COFF-NOFS:           .section .text,"xr",discard,_Z4fooTIiET_v{{$}}
 ; CHECK-LABEL: _Z4fooTIiET_v:
 ; CHECK-NEXT:  [[FOOCOMDAT_BEGIN:.Lfunc_begin[0-9]+]]:
-; CHECK:               .section 
.llvm_bb_addr_map,"oG",@llvm_bb_addr_map,.text._Z4fooTIiET_v,_Z4fooTIiET_v,comdat{{$}}
+; ELF:                 .section 
.llvm_bb_addr_map,"oG",@llvm_bb_addr_map,.text._Z4fooTIiET_v,_Z4fooTIiET_v,comdat{{$}}
+; COFF-FS:             .section 
.llvm_bb_addr_map,"drD",associative,_Z4fooTIiET_v,unique,2{{$}}
+; COFF-NOFS:           .section 
.llvm_bb_addr_map,"drD",associative,_Z4fooTIiET_v{{$}}
 ; CHECK-NEXT:          .byte  5                                # version
 ; CHECK-NEXT:          .short 0                                # feature
 ; CHECK-NEXT:          .quad [[FOOCOMDAT_BEGIN]]       # function address
diff --git a/llvm/test/CodeGen/X86/basic-block-address-map.ll 
b/llvm/test/CodeGen/X86/basic-block-address-map.ll
index 5567ccd4f9e75..c716e12a57646 100644
--- a/llvm/test/CodeGen/X86/basic-block-address-map.ll
+++ b/llvm/test/CodeGen/X86/basic-block-address-map.ll
@@ -1,7 +1,8 @@
 ; Check the basic block sections labels option
-; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true 
-basic-block-address-map | FileCheck %s --check-prefixes=CHECK,UNIQ
-; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=false 
-basic-block-address-map | FileCheck %s --check-prefixes=CHECK,NOUNIQ
-; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true 
-basic-block-address-map -split-machine-functions | FileCheck %s 
--check-prefixes=CHECK,UNIQ
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true 
-basic-block-address-map | FileCheck %s --check-prefixes=CHECK,ELF,UNIQ
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=false 
-basic-block-address-map | FileCheck %s --check-prefixes=CHECK,ELF,NOUNIQ
+; RUN: llc < %s -mtriple=x86_64 -function-sections -unique-section-names=true 
-basic-block-address-map -split-machine-functions | FileCheck %s 
--check-prefixes=CHECK,ELF,UNIQ
+; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -function-sections 
-basic-block-address-map | FileCheck %s --check-prefixes=CHECK,COFF
 
 define void @_Z3bazb(i1 zeroext, i1 zeroext) personality ptr 
@__gxx_personality_v0 {
   br i1 %0, label %3, label %8
@@ -52,6 +53,7 @@ declare i32 @__gxx_personality_v0(...)
 ; UNIQ:                        .section        
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3bazb{{$}}
 ;; Verify that with -unique-section-names=false, the unique id of the text 
section gets assigned to the llvm_bb_addr_map section.
 ; NOUNIQ:              .section        
.llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text,unique,1
+; COFF:                        .section        
.llvm_bb_addr_map,"drD",associative,_Z3bazb,unique,0{{$}}
 ; CHECK-NEXT:   .byte   5              # version
 ; CHECK-NEXT:   .short  32             # feature
 ; CHECK-NEXT:  .quad   .Lfunc_begin0   # function address
@@ -87,4 +89,7 @@ declare i32 @__gxx_personality_v0(...)
 ; CHECK-NEXT:  .uleb128 .LBB0_5-.LBB_END0_4
 ; CHECK-NEXT:   .byte  0               # number of callsites
 ; CHECK-NEXT:  .uleb128 .LBB_END0_5-.LBB0_5
-; CHECK-NEXT:  .byte   5
+;; The landingpad block metadata differs: ELF uses eh_frame (HasReturn set),
+;; COFF uses SEH (HasReturn not set).
+; ELF-NEXT:    .byte   5
+; COFF-NEXT:   .byte   4

>From 82bcc4395826906e281eec9e930ebe25c745c327 Mon Sep 17 00:00:00 2001
From: Haohai Wen <[email protected]>
Date: Fri, 10 Apr 2026 15:40:21 +0800
Subject: [PATCH 2/2] [X86][COFF] Address review feedback for bb-addr-map
 emission

Remove BBAddrMapSectionName constant from BBAddrMap.h and hardcode
the section name in MCObjectFileInfo to avoid heavy Object header
dependency. Add fatal error for COMDAT functions on targets without
associative COMDAT support (e.g. MinGW). Allow MinGW in the driver
since non-COMDAT functions work without associative COMDATs.
---
 clang/test/Driver/basic-block-address-map.c | 1 +
 llvm/include/llvm/Object/BBAddrMap.h        | 3 ---
 llvm/lib/MC/MCObjectFileInfo.cpp            | 6 ++++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/test/Driver/basic-block-address-map.c 
b/clang/test/Driver/basic-block-address-map.c
index b11dbb3c65548..d060655aa8a2d 100644
--- a/clang/test/Driver/basic-block-address-map.c
+++ b/clang/test/Driver/basic-block-address-map.c
@@ -6,5 +6,6 @@
 // RUN: %clang -### --target=x86_64 -fno-basic-block-address-map %s -S 2>&1 | 
FileCheck %s --check-prefix=CHECK-ABSENT
 // CHECK-ABSENT-NOT: -fbasic-block-address-map
 
+// RUN: %clang -### --target=x86_64-w64-mingw32 -fbasic-block-address-map %s 
-S 2>&1 | FileCheck -check-prefix=CHECK-PRESENT %s
 // RUN: not %clang -c --target=x86_64-apple-darwin10 -fbasic-block-address-map 
%s -S 2>&1 | FileCheck -check-prefix=CHECK-TRIPLE %s
 // CHECK-TRIPLE: error: unsupported option '-fbasic-block-address-map' for 
target
diff --git a/llvm/include/llvm/Object/BBAddrMap.h 
b/llvm/include/llvm/Object/BBAddrMap.h
index 4f710bc19951e..49c9b431822e0 100644
--- a/llvm/include/llvm/Object/BBAddrMap.h
+++ b/llvm/include/llvm/Object/BBAddrMap.h
@@ -15,7 +15,6 @@
 #define LLVM_OBJECT_BBADDRMAP_H
 
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/BlockFrequency.h"
 #include "llvm/Support/BranchProbability.h"
 #include "llvm/Support/DataExtractor.h"
@@ -25,8 +24,6 @@
 namespace llvm {
 namespace object {
 
-inline constexpr StringLiteral BBAddrMapSectionName = ".llvm_bb_addr_map";
-
 // Struct representing the BBAddrMap for one function.
 struct BBAddrMap {
 
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 1e78e5fe2cc49..7227fe93b81a8 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -27,7 +27,6 @@
 #include "llvm/MC/MCSectionXCOFF.h"
 #include "llvm/MC/MCSymbolGOFF.h"
 #include "llvm/MC/SectionKind.h"
-#include "llvm/Object/BBAddrMap.h"
 #include "llvm/TargetParser/Triple.h"
 
 using namespace llvm;
@@ -1267,7 +1266,7 @@ MCObjectFileInfo::getStackSizesSection(const MCSection 
&TextSec) const {
 
 MCSection *
 MCObjectFileInfo::getBBAddrMapSection(const MCSection &TextSec) const {
-  StringRef Name = object::BBAddrMapSectionName;
+  constexpr StringLiteral Name = ".llvm_bb_addr_map";
   if (Ctx->getObjectFileType() == MCContext::IsELF) {
     const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
     unsigned Flags = ELF::SHF_LINK_ORDER;
@@ -1291,6 +1290,9 @@ MCObjectFileInfo::getBBAddrMapSection(const MCSection 
&TextSec) const {
                                COFF::IMAGE_SCN_MEM_READ;
     const auto &COFFSec = static_cast<const MCSectionCOFF &>(TextSec);
     if (const MCSymbol *COMDATSym = COFFSec.getCOMDATSymbol()) {
+      if (!Ctx->getAsmInfo()->hasCOFFAssociativeComdats())
+        report_fatal_error("BB address map requires associative COMDAT "
+                           "support for COMDAT functions");
       COMDATSymName = COMDATSym->getName();
       Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
       Selection = COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to