diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1406,15 +1406,23 @@ if (!TOC.empty()) { const char *Name = isPPC64 ? ".toc" : ".got2"; - MCSectionELF *Section = OutContext.getELFSection( - Name, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); - OutStreamer->SwitchSection(Section); - if (!isPPC64) - OutStreamer->emitValueToAlignment(4); - + MCSectionELF *CurSection = nullptr, *Section; for (const auto &TOCMapPair : TOC) { const MCSymbol *const TOCEntryTarget = TOCMapPair.first; MCSymbol *const TOCEntryLabel = TOCMapPair.second; + const MCSymbolELF *Group = nullptr; + if (isPPC64 && TOCEntryTarget->isInSection()) + Group = cast(TOCEntryTarget->getSection()).getGroup(); + Section = OutStreamer->getContext().getELFSection( + Name, ELF::SHT_PROGBITS, + ELF::SHF_WRITE | ELF::SHF_ALLOC | (Group ? ELF::SHF_GROUP : 0), 0, + Group, MCSection::NonUniqueID, nullptr); + if (Section != CurSection) { + OutStreamer->SwitchSection(Section); + CurSection = Section; + if (!isPPC64) + OutStreamer->emitValueToAlignment(4); + } OutStreamer->emitLabel(TOCEntryLabel); if (isPPC64) diff --git a/llvm/test/CodeGen/PowerPC/mcm-1.ll b/llvm/test/CodeGen/PowerPC/mcm-1.ll --- a/llvm/test/CodeGen/PowerPC/mcm-1.ll +++ b/llvm/test/CodeGen/PowerPC/mcm-1.ll @@ -7,7 +7,12 @@ target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" target triple = "powerpc64-unknown-linux-gnu" +$fi = comdat any +$gi = comdat any + @ei = external global i32 +@fi = global i32 0, align 4, comdat +@gi = global i32 0, align 4, comdat define signext i32 @test_external() nounwind { entry: @@ -17,11 +22,27 @@ ret i32 %0 } +define i32 @load() { +entry: + %0 = load i32, i32* @gi, align 4 + %1 = load i32, i32* @fi, align 4 + %2 = add i32 %0, %1 + ret i32 %2 +} + ; CHECK-LABEL: test_external: ; CHECK: addis [[REG1:[0-9]+]], 2, .LC[[TOCNUM:[0-9]+]]@toc@ha ; CHECK: ld [[REG2:[0-9]+]], .LC[[TOCNUM]]@toc@l([[REG1]]) ; CHECK: lwz {{[0-9]+}}, 0([[REG2]]) ; CHECK: stw {{[0-9]+}}, 0([[REG2]]) -; CHECK: .section .toc -; CHECK: .LC[[TOCNUM]]: -; CHECK: .tc {{[a-z0-9A-Z_.]+}}[TC],{{[a-z0-9A-Z_.]+}} + + +; CHECK: .section .toc,"aw",@progbits +; CHECK-NEXT: .LC0: +; CHECK-NEXT: .tc ei[TC],ei +; CHECK-NEXT: .section .toc,"aGw",@progbits,fi,comdat +; CHECK-NEXT: .LC1: +; CHECK-NEXT: .tc fi[TC],fi +; CHECK-NEXT: .section .toc,"aGw",@progbits,gi,comdat +; CHECK-NEXT: .LC2: +; CHECK-NEXT: .tc gi[TC],gi diff --git a/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll b/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll --- a/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll +++ b/llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll @@ -1,12 +1,17 @@ -; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=LARGE-BSS %s -; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck --check-prefixes=LARGE,LARGE-BSS %s +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -mattr=+secure-plt -relocation-model=pic | FileCheck --check-prefixes=LARGE,LARGE-SECUREPLT %s ; RUN: llc < %s -mtriple=powerpc-unknown-netbsd -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s ; RUN: llc < %s -mtriple=powerpc-unknown-netbsd -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s ; RUN: llc < %s -mtriple=powerpc-unknown-openbsd -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s ; RUN: llc < %s -mtriple=powerpc-unknown-openbsd -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s ; RUN: llc < %s -mtriple=powerpc-linux-musl -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s ; RUN: llc < %s -mtriple=powerpc-linux-musl -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s +$bar1 = comdat any +$bar2 = comdat any + @bar = common global i32 0, align 4 +@bar1 = global i32 0, align 4, comdat +@bar2 = global i32 0, align 4, comdat declare i32 @call_foo(i32, ...) @@ -17,6 +22,14 @@ ret i32 %0 } +define i32 @load() { +entry: + %0 = load i32, i32* @bar1 + %1 = load i32, i32* @bar2 + %2 = add i32 %0, %1 + ret i32 %2 +} + !llvm.module.flags = !{!0} !0 = !{i32 1, !"PIC Level", i32 2} ; LARGE-BSS: [[POFF:\.L[0-9]+\$poff]]: @@ -33,10 +46,17 @@ ; LARGE-BSS-DAG: lwz {{[0-9]+}}, 0([[VREG]]) ; LARGE-BSS-DAG: stw {{[0-9]+}}, 8(1) ; LARGE-BSS: lwz 30, 24(1) -; LARGE-BSS: .section .got2,"aw",@progbits -; LARGE-BSS-NEXT: .p2align 2 -; LARGE-BSS-NEXT: [[VREF]]: -; LARGE-BSS-NEXT: .long bar ; LARGE-SECUREPLT: addis 30, 30, .LTOC-.L0$pb@ha ; LARGE-SECUREPLT: addi 30, 30, .LTOC-.L0$pb@l ; LARGE-SECUREPLT: bl call_foo@PLT+32768 + +; LARGE: .section .bss.bar1,"aGw",@nobits,bar1,comdat +; LARGE: .section .bss.bar2,"aGw",@nobits,bar2,comdat +; LARGE: .section .got2,"aw",@progbits +; LARGE-NEXT: .p2align 2 +; LARGE-NEXT: .LC0: +; LARGE-NEXT: .long bar +; LARGE-NEXT: .LC1: +; LARGE-NEXT: .long bar1 +; LARGE-NEXT: .LC2: +; LARGE-NEXT: .long bar2