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
