diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index f7096b708b39d..8a14334551b00 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -43,9 +43,6 @@ bool TargetMachine::isLargeGlobalObject(const GlobalObject *GO) const { if (getTargetTriple().getArch() != Triple::x86_64) return false; - if (getCodeModel() != CodeModel::Medium && getCodeModel() != CodeModel::Large) - return false; - if (isa(GO)) return getCodeModel() == CodeModel::Large; @@ -54,22 +51,29 @@ bool TargetMachine::isLargeGlobalObject(const GlobalObject *GO) const { if (GV->isThreadLocal()) return false; - // Allowing large metadata sections in the presence of an explicit section is - // useful, even if GCC does not allow them. However, we should not mark - // certain well-known prefixes as large, because it would make the whole - // output section large and cause the linker to move it, which is almost - // always undesired. + // 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(); - 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 (!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; + } + + if (getCodeModel() == CodeModel::Medium || + getCodeModel() == CodeModel::Large) { + const DataLayout &DL = GV->getParent()->getDataLayout(); + uint64_t Size = DL.getTypeSizeInBits(GV->getValueType()) / 8; + return Size == 0 || Size > LargeDataThreshold; + } - const DataLayout &DL = GV->getParent()->getDataLayout(); - uint64_t Size = DL.getTypeSizeInBits(GV->getValueType()) / 8; - return Size == 0 || Size > LargeDataThreshold; + return false; } bool TargetMachine::isPositionIndependent() const { diff --git a/llvm/test/CodeGen/X86/code-model-elf-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-sections.ll index 0b99a70c4044a..f72880e172bdc 100644 --- a/llvm/test/CodeGen/X86/code-model-elf-sections.ll +++ b/llvm/test/CodeGen/X86/code-model-elf-sections.ll @@ -21,9 +21,14 @@ ; SMALL: .data {{.*}} WA {{.*}} ; SMALL: .data.x {{.*}} WA {{.*}} ; SMALL: .data0 {{.*}} WA {{.*}} +; SMALL: .ldata {{.*}} WAl {{.*}} +; SMALL: .ldata.x {{.*}} WAl {{.*}} +; SMALL: .ldata0 {{.*}} WA {{.*}} ; SMALL: foo {{.*}} WA {{.*}} ; SMALL: .bss {{.*}} WA {{.*}} +; SMALL: .lbss {{.*}} WAl {{.*}} ; SMALL: .rodata {{.*}} A {{.*}} +; SMALL: .lrodata {{.*}} Al {{.*}} ; SMALL: .data.rel.ro {{.*}} WA {{.*}} ; SMALL: .tbss {{.*}} WAT {{.*}} ; SMALL: .tdata {{.*}} WAT {{.*}} @@ -31,9 +36,14 @@ ; SMALL-DS: .data {{.*}} WA {{.*}} ; SMALL-DS: .data.x {{.*}} WA {{.*}} ; SMALL-DS: .data0 {{.*}} WA {{.*}} +; SMALL-DS: .ldata {{.*}} WAl {{.*}} +; SMALL-DS: .ldata.x {{.*}} WAl {{.*}} +; SMALL-DS: .ldata0 {{.*}} WA {{.*}} ; SMALL-DS: .data.data {{.*}} WA {{.*}} ; SMALL-DS: foo {{.*}} WA {{.*}} +; SMALL-DS: .lbss {{.*}} WAl {{.*}} ; SMALL-DS: .bss.bss {{.*}} WA {{.*}} +; SMALL-DS: .lrodata {{.*}} Al {{.*}} ; SMALL-DS: .rodata.rodata {{.*}} A {{.*}} ; SMALL-DS: .data.rel.ro.relro {{.*}} WA {{.*}} ; SMALL-DS: .tbss.tbss {{.*}} WAT {{.*}} @@ -43,6 +53,8 @@ ; LARGE: .data.x {{.*}} WA {{.*}} ; LARGE: .data0 {{.*}} WAl {{.*}} ; LARGE: .ldata {{.*}} WAl {{.*}} +; LARGE: .ldata.x {{.*}} WAl {{.*}} +; LARGE: .ldata0 {{.*}} WAl {{.*}} ; LARGE: foo {{.*}} WAl {{.*}} ; LARGE: .bss {{.*}} WA {{.*}} ; LARGE: .lbss {{.*}} WAl {{.*}} @@ -55,6 +67,9 @@ ; LARGE-DS: .data {{.*}} WA {{.*}} ; LARGE-DS: .data.x {{.*}} WA {{.*}} ; LARGE-DS: .data0 {{.*}} WAl {{.*}} +; LARGE-DS: .ldata {{.*}} WAl {{.*}} +; LARGE-DS: .ldata.x {{.*}} WAl {{.*}} +; LARGE-DS: .ldata0 {{.*}} WAl {{.*}} ; LARGE-DS: .ldata.data {{.*}} WAl {{.*}} ; LARGE-DS: foo {{.*}} WAl {{.*}} ; LARGE-DS: .bss {{.*}} WA {{.*}} @@ -71,11 +86,16 @@ target triple = "x86_64--linux" @data_with_explicit_section = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".data" @data_with_explicit_section2 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".data.x" @data_with_explicit_section0 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".data0" +@ldata_with_explicit_section = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".ldata" +@ldata_with_explicit_section2 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".ldata.x" +@ldata_with_explicit_section0 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".ldata0" @data = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0] @foo_with_explicit_section = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section "foo" @bss_with_explicit_section = internal global [10 x i64] zeroinitializer, section ".bss" +@lbss_with_explicit_section = internal global [10 x i64] zeroinitializer, section ".lbss" @bss = internal global [10 x i64] zeroinitializer @rodata_with_explicit_section = internal constant [10 x i64] zeroinitializer, section ".rodata" +@lrodata_with_explicit_section = internal constant [10 x i64] zeroinitializer, section ".lrodata" @rodata = internal constant [10 x i64] zeroinitializer @relro = internal constant [10 x ptr] [ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func] @tbss = internal thread_local global [10 x i64] zeroinitializer