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 @@ -2220,6 +2220,12 @@ if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) { MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol( &(MF->getFunction()), TM); + // If the FuncSectSym is the csect itself, the difference between FuncEnd + // and FuncSectSym is an absolute value. To avoid evaluating an MCExpr for + // (FuncEnd - FuncSectSym), set the fragment of FuncEnd to FuncSectSym. + if (TM.getFunctionSections() && FuncSectSym->isUndefined() && + FuncEnd->isDefined()) + FuncSectSym->setFragment(FuncEnd->getFragment()); OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4); } diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll @@ -5,6 +5,11 @@ ; RUN: -mattr=-altivec -function-sections < %s | \ ; RUN: FileCheck --check-prefix=ASM %s +; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \ +; RUN: -mattr=-altivec -function-sections -xcoff-traceback-table=true \ +; RUN: -filetype=obj -o %t.o < %s +; RUN: llvm-objdump --syms --reloc %t.o | FileCheck --check-prefix=XCOFF %s + @alias_foo = alias void (...), bitcast (void ()* @foo to void (...)*) define void @foo() { @@ -93,3 +98,38 @@ ; ASM-NEXT: .extern extern_foo[DS] ; ASM-NEXT: .globl alias_foo ; ASM-NEXT: .globl .alias_foo + +; XCOFF: SYMBOL TABLE: +; XCOFF-NEXT: 0000000000000000 df *DEBUG* 0000000000000000 +; XCOFF-NEXT: 0000000000000000 *UND* 0000000000000000 .extern_foo +; XCOFF-NEXT: 0000000000000000 *UND* 0000000000000000 extern_foo +; XCOFF-NEXT: 0000000000000000 l .text 0000000000000000 .text +; XCOFF-NEXT: 0000000000000000 g .text 0000000000000019 .foo +; XCOFF-NEXT: 0000000000000000 g F .text (csect: .foo) 0000000000000000 .alias_foo +; XCOFF-NEXT: 0000000000000020 g .text 0000000000000020 .hidden .hidden_foo +; XCOFF-NEXT: 0000000000000040 g .text 0000000000000059 .bar +; XCOFF-NEXT: 00000000000000c0 l .text 000000000000002a .static_overalign_foo +; XCOFF-NEXT: 00000000000000f0 g O .data 0000000000000018 foo +; XCOFF-NEXT: 00000000000000f0 g O .data (csect: foo) 0000000000000000 alias_foo +; XCOFF-NEXT: 0000000000000108 g O .data 0000000000000018 .hidden hidden_foo +; XCOFF-NEXT: 0000000000000120 g O .data 0000000000000018 bar +; XCOFF-NEXT: 0000000000000138 l O .data 0000000000000018 static_overalign_foo +; XCOFF-NEXT: 0000000000000150 l .data 0000000000000000 TOC + +; XCOFF: RELOCATION RECORDS FOR [.text]: +; XCOFF-NEXT: OFFSET TYPE VALUE +; XCOFF-NEXT: 000000000000004c R_RBR .foo +; XCOFF-NEXT: 0000000000000054 R_RBR .static_overalign_foo +; XCOFF-NEXT: 000000000000005c R_RBR .alias_foo +; XCOFF-NEXT: 0000000000000064 R_RBR .extern_foo +; XCOFF-NEXT: 000000000000006c R_RBR .hidden_foo +; XCOFF: RELOCATION RECORDS FOR [.data]: +; XCOFF-NEXT: OFFSET TYPE VALUE +; XCOFF-NEXT: 0000000000000000 R_POS .foo +; XCOFF-NEXT: 0000000000000008 R_POS TOC +; XCOFF-NEXT: 0000000000000018 R_POS .hidden_foo +; XCOFF-NEXT: 0000000000000020 R_POS TOC +; XCOFF-NEXT: 0000000000000030 R_POS .bar +; XCOFF-NEXT: 0000000000000038 R_POS TOC +; XCOFF-NEXT: 0000000000000048 R_POS .static_overalign_foo +; XCOFF-NEXT: 0000000000000050 R_POS TOC