[llvm] 6ab9daf - [clang] Implement #pragma clang section on COFF targets (#112714)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 21 16:13:02 PST 2025
Author: Vinicius Tadeu Zein
Date: 2025-01-21T16:12:58-08:00
New Revision: 6ab9dafec807a64a4e940bfaecc815e23454dfe8
URL: https://github.com/llvm/llvm-project/commit/6ab9dafec807a64a4e940bfaecc815e23454dfe8
DIFF: https://github.com/llvm/llvm-project/commit/6ab9dafec807a64a4e940bfaecc815e23454dfe8.diff
LOG: [clang] Implement #pragma clang section on COFF targets (#112714)
This patch implements the directive #pragma clang section on COFF targets
with the exact same features available on ELF and Mach-O.
Added:
llvm/test/CodeGen/X86/clang-section-coff.ll
Modified:
clang/docs/LanguageExtensions.rst
clang/docs/ReleaseNotes.rst
clang/test/Sema/pragma-clang-section.c
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Removed:
################################################################################
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index bbeeefe82282b9..c42b88015e2695 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -5656,7 +5656,7 @@ The ``#pragma clang section`` directive obeys the following rules:
* The pragma clang section is enabled automatically, without need of any flags.
-* This feature is only defined to work sensibly for ELF and Mach-O targets.
+* This feature is only defined to work sensibly for ELF, Mach-O and COFF targets.
* If section name is specified through _attribute_((section("myname"))), then
the attribute name gains precedence.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index da9569759a4081..f19be0446d3fec 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1124,6 +1124,8 @@ Windows Support
When `-fms-compatibility-version=18.00` or prior is set on the command line this Microsoft extension is still
allowed as VS2013 and prior allow it.
+- Clang now supports the ``#pragma clang section`` directive for COFF targets.
+
LoongArch Support
^^^^^^^^^^^^^^^^^
diff --git a/clang/test/Sema/pragma-clang-section.c b/clang/test/Sema/pragma-clang-section.c
index 458c91c2cf31cd..e33e1dfe8cbef7 100644
--- a/clang/test/Sema/pragma-clang-section.c
+++ b/clang/test/Sema/pragma-clang-section.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple arm-none-eabi
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple arm64-windows-msvc
#pragma clang section bss = "mybss.1" data = "mydata.1" rodata = "myrodata.1" text = "mytext.1" // expected-note 2 {{#pragma entered here}}
#pragma clang section bss="" data="" rodata="" text=""
#pragma clang section
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index be243c0e74e9db..7db949ffde7883 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -788,29 +788,35 @@ getGlobalObjectInfo(const GlobalObject *GO, const TargetMachine &TM) {
return {Group, IsComdat, Flags};
}
-static MCSection *selectExplicitSectionGlobal(
- const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM,
- MCContext &Ctx, Mangler &Mang, unsigned &NextUniqueID,
- bool Retain, bool ForceUnique) {
- StringRef SectionName = GO->getSection();
-
+static StringRef handlePragmaClangSection(const GlobalObject *GO,
+ SectionKind Kind) {
// Check if '#pragma clang section' name is applicable.
// Note that pragma directive overrides -ffunction-section, -fdata-section
// and so section name is exactly as user specified and not uniqued.
const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
if (GV && GV->hasImplicitSection()) {
auto Attrs = GV->getAttributes();
- if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
- SectionName = Attrs.getAttribute("bss-section").getValueAsString();
- } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
- SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
- } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
- SectionName = Attrs.getAttribute("relro-section").getValueAsString();
- } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
- SectionName = Attrs.getAttribute("data-section").getValueAsString();
- }
+ if (Attrs.hasAttribute("bss-section") && Kind.isBSS())
+ return Attrs.getAttribute("bss-section").getValueAsString();
+ else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly())
+ return Attrs.getAttribute("rodata-section").getValueAsString();
+ else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel())
+ return Attrs.getAttribute("relro-section").getValueAsString();
+ else if (Attrs.hasAttribute("data-section") && Kind.isData())
+ return Attrs.getAttribute("data-section").getValueAsString();
}
+ return GO->getSection();
+}
+
+static MCSection *selectExplicitSectionGlobal(const GlobalObject *GO,
+ SectionKind Kind,
+ const TargetMachine &TM,
+ MCContext &Ctx, Mangler &Mang,
+ unsigned &NextUniqueID,
+ bool Retain, bool ForceUnique) {
+ StringRef SectionName = handlePragmaClangSection(GO, Kind);
+
// Infer section flags from the section name if we can.
Kind = getELFKindForNamedSection(SectionName, Kind);
@@ -1291,21 +1297,7 @@ static void checkMachOComdat(const GlobalValue *GV) {
MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
- StringRef SectionName = GO->getSection();
-
- const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
- if (GV && GV->hasImplicitSection()) {
- auto Attrs = GV->getAttributes();
- if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
- SectionName = Attrs.getAttribute("bss-section").getValueAsString();
- } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
- SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
- } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
- SectionName = Attrs.getAttribute("relro-section").getValueAsString();
- } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
- SectionName = Attrs.getAttribute("data-section").getValueAsString();
- }
- }
+ StringRef SectionName = handlePragmaClangSection(GO, Kind);
// Parse the section specifier and create it if valid.
StringRef Segment, Section;
@@ -1674,7 +1666,7 @@ static int getSelectionForCOFF(const GlobalValue *GV) {
MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
- StringRef Name = GO->getSection();
+ StringRef Name = handlePragmaClangSection(GO, Kind);
if (Name == getInstrProfSectionName(IPSK_covmap, Triple::COFF,
/*AddSegmentInfo=*/false) ||
Name == getInstrProfSectionName(IPSK_covfun, Triple::COFF,
diff --git a/llvm/test/CodeGen/X86/clang-section-coff.ll b/llvm/test/CodeGen/X86/clang-section-coff.ll
new file mode 100644
index 00000000000000..02381fd256aaa1
--- /dev/null
+++ b/llvm/test/CodeGen/X86/clang-section-coff.ll
@@ -0,0 +1,146 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+;RUN: llc -mtriple=x86_64-windows-msvc %s -o - | FileCheck %s
+;Test that global variables and functions are assigned to correct sections.
+
+ at a = global i32 0, align 4 #0
+ at b = global i32 1, align 4 #0
+ at c = global [4 x i32] zeroinitializer, align 4 #0
+ at d = global [5 x i16] zeroinitializer, align 2 #0
+ at e = global [6 x i16] [i16 0, i16 0, i16 1, i16 0, i16 0, i16 0], align 2 #0
+ at f = constant i32 2, align 4 #0
+ at h = global i32 0, align 4 #1
+ at i = global i32 0, align 4 #2
+ at j = constant i32 4, align 4 #2
+ at k = global i32 0, align 4 #2
+ at _ZZ3gooE7lstat_h = internal global i32 0, align 4 #2
+ at _ZL1g = internal global [2 x i32] zeroinitializer, align 4 #0
+ at l = global i32 5, align 4 #3
+ at m = constant i32 6, align 4 #3
+ at n = global i32 0, align 4
+ at o = global i32 6, align 4
+ at p = constant i32 7, align 4
+
+declare i32 @zoo(ptr, ptr) #6
+
+; Function Attrs: noinline nounwind
+define i32 @hoo() #7 {
+; CHECK-LABEL: hoo:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: movl b(%rip), %eax
+; CHECK-NEXT: retq
+entry:
+ %0 = load i32, ptr @b, align 4
+ ret i32 %0
+}
+
+attributes #0 = { "bss-section"="my_bss.1" "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+attributes #1 = { "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+attributes #2 = { "bss-section"="my_bss.2" "rodata-section"="my_rodata.1" }
+attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "rodata-section"="my_rodata.2" }
+attributes #6 = { "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign,preserve-sign" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #7 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign,preserve-sign" "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"static_rwdata", i32 1}
+!2 = !{i32 1, !"enumsize_buildattr", i32 2}
+!3 = !{i32 1, !"armlib_unavailable", i32 0}
+
+;CHECK: .section my_bss.1,"bw"
+;CHECK: .globl a # @a
+;CHECK: .p2align 2, 0x0
+;CHECK: a:
+;CHECK: .long 0 # 0x0
+
+;CHECK: .section my_data.1,"dw"
+;CHECK: .globl b # @b
+;CHECK: .p2align 2, 0x0
+;CHECK: b:
+;CHECK: .long 1 # 0x1
+
+;CHECK: .section my_bss.1,"bw"
+;CHECK: .globl c # @c
+;CHECK: .p2align 2, 0x0
+;CHECK: c:
+;CHECK: .zero 16
+;CHECK: .globl d # @d
+;CHECK: .p2align 1, 0x0
+;CHECK: d:
+;CHECK: .zero 10
+
+;CHECK: .section my_data.1,"dw"
+;CHECK: .globl e # @e
+;CHECK: .p2align 1, 0x0
+;CHECK: e:
+;CHECK: .short 0 # 0x0
+;CHECK: .short 0 # 0x0
+;CHECK: .short 1 # 0x1
+;CHECK: .short 0 # 0x0
+;CHECK: .short 0 # 0x0
+;CHECK: .short 0 # 0x0
+
+;CHECK: .section my_rodata.1,"dr"
+;CHECK: .globl f # @f
+;CHECK: .p2align 2, 0x0
+;CHECK: f:
+;CHECK: .long 2 # 0x2
+;CHECK: .bss
+;CHECK: .globl h # @h
+;CHECK: .p2align 2, 0x0
+;CHECK: h:
+;CHECK: .long 0 # 0x0
+
+;CHECK: .section my_bss.2,"bw"
+;CHECK: .globl i # @i
+;CHECK: .p2align 2, 0x0
+;CHECK: i:
+;CHECK: .long 0 # 0x0
+
+;CHECK: .section my_rodata.1,"dr"
+;CHECK: .globl j # @j
+;CHECK: .p2align 2, 0x0
+;CHECK: j:
+;CHECK: .long 4 # 0x4
+
+;CHECK: .section my_bss.2,"bw"
+;CHECK: .globl k # @k
+;CHECK: .p2align 2, 0x0
+;CHECK: k:
+;CHECK: .long 0 # 0x0
+;CHECK: .p2align 2, 0x0 # @_ZZ3gooE7lstat_h
+;CHECK: _ZZ3gooE7lstat_h:
+;CHECK: .long 0 # 0x0
+
+;CHECK: .section my_bss.1,"bw"
+;CHECK: .p2align 2, 0x0 # @_ZL1g
+;CHECK: _ZL1g:
+;CHECK: .zero 8
+
+;CHECK: .section my_data.2,"dw"
+;CHECK: .globl l # @l
+;CHECK: .p2align 2, 0x0
+;CHECK: l:
+;CHECK: .long 5 # 0x5
+
+;CHECK: .section my_rodata.2,"dr"
+;CHECK: .globl m # @m
+;CHECK: .p2align 2, 0x0
+;CHECK: m:
+;CHECK: .long 6 # 0x6
+;CHECK: .bss
+;CHECK: .globl n # @n
+;CHECK: .p2align 2, 0x0
+;CHECK: n:
+;CHECK: .long 0 # 0x0
+;CHECK: .data
+;CHECK: .globl o # @o
+;CHECK: .p2align 2, 0x0
+;CHECK: o:
+;CHECK: .long 6 # 0x6
+
+;CHECK: .section .rdata,"dr"
+;CHECK: .globl p # @p
+;CHECK: .p2align 2, 0x0
+;CHECK: p:
+;CHECK: .long 7 # 0x7
More information about the llvm-commits
mailing list