diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index 2a4383314e465..abd0fdf2390c0 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -58,24 +58,8 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const { if (GV->isThreadLocal()) return false; - // We should properly mark well-known section name prefixes as small/large, - // because otherwise the output section may have the wrong section flags and - // the linker will lay it out in an unexpected way. - StringRef Name = GV->getSection(); - if (!Name.empty()) { - auto IsPrefix = [&](StringRef Prefix) { - StringRef S = Name; - return S.consume_front(Prefix) && (S.empty() || S[0] == '.'); - }; - if (IsPrefix(".bss") || IsPrefix(".data") || IsPrefix(".rodata")) - return false; - if (IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata")) - return true; - } - // For x86-64, we treat an explicit GlobalVariable small code model to mean // that the global should be placed in a small section, and ditto for large. - // Well-known section names above take precedence for correctness. if (auto CM = GV->getCodeModel()) { if (*CM == CodeModel::Small) return false; @@ -83,6 +67,20 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const { return true; } + // Treat all globals in explicit sections as small, except for the standard + // large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking + // together small and large sections, resulting in small references to large + // data sections. The code model attribute overrides this above. + if (GV->hasSection()) { + StringRef Name = GV->getSection(); + auto IsPrefix = [&](StringRef Prefix) { + StringRef S = Name; + return S.consume_front(Prefix) && (S.empty() || S[0] == '.'); + }; + return IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata"); + } + + // Respect large data threshold for medium and large code models. if (getCodeModel() == CodeModel::Medium || getCodeModel() == CodeModel::Large) { if (!GV->getValueType()->isSized()) diff --git a/llvm/test/CodeGen/X86/code-model-elf-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-sections.ll index 749d5b6bf904e..fc5dac89a6b3d 100644 --- a/llvm/test/CodeGen/X86/code-model-elf-sections.ll +++ b/llvm/test/CodeGen/X86/code-model-elf-sections.ll @@ -55,13 +55,13 @@ ; LARGE: .data {{.*}} WA {{.*}} ; LARGE: .data.x {{.*}} WA {{.*}} -; LARGE: .data0 {{.*}} WAl {{.*}} +; LARGE: .data0 {{.*}} WA {{.*}} ; LARGE: .ldata {{.*}} WAl {{.*}} ; LARGE: .ldata.x {{.*}} WAl {{.*}} -; LARGE: .ldata0 {{.*}} WAl {{.*}} +; LARGE: .ldata0 {{.*}} WA {{.*}} ; LARGE: force_small {{.*}} WA {{.*}} ; LARGE: force_large {{.*}} WAl {{.*}} -; LARGE: foo {{.*}} WAl {{.*}} +; LARGE: foo {{.*}} WA {{.*}} ; LARGE: .bss {{.*}} WA {{.*}} ; LARGE: .lbss {{.*}} WAl {{.*}} ; LARGE: .rodata {{.*}} A {{.*}} @@ -72,14 +72,14 @@ ; LARGE-DS: .data {{.*}} WA {{.*}} ; LARGE-DS: .data.x {{.*}} WA {{.*}} -; LARGE-DS: .data0 {{.*}} WAl {{.*}} +; LARGE-DS: .data0 {{.*}} WA {{.*}} ; LARGE-DS: .ldata {{.*}} WAl {{.*}} ; LARGE-DS: .ldata.x {{.*}} WAl {{.*}} -; LARGE-DS: .ldata0 {{.*}} WAl {{.*}} +; LARGE-DS: .ldata0 {{.*}} WA {{.*}} ; LARGE-DS: .ldata.data {{.*}} WAl {{.*}} ; LARGE-DS: force_small {{.*}} WA {{.*}} ; LARGE-DS: force_large {{.*}} WAl {{.*}} -; LARGE-DS: foo {{.*}} WAl {{.*}} +; LARGE-DS: foo {{.*}} WA {{.*}} ; LARGE-DS: .bss {{.*}} WA {{.*}} ; LARGE-DS: .lbss.bss {{.*}} WAl {{.*}} ; LARGE-DS: .rodata {{.*}} A {{.*}}