Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 212ec3a

Browse files
committed
[PPC64] Fix PR19893 - improve code generation for local function addresses
Rafael opened http://llvm.org/bugs/show_bug.cgi?id=19893 to track non-optimal code generation for forming a function address that is local to the compile unit. The existing code was treating both local and non-local functions identically. This patch fixes the problem by properly identifying local functions and generating the proper addis/addi code. I also noticed that Rafael's earlier changes to correct the surrounding code in PPCISelLowering.cpp were also needed for fast instruction selection in PPCFastISel.cpp, so this patch fixes that code as well. The existing test/CodeGen/PowerPC/func-addr.ll is modified to test the new code generation. I've added a -O0 run line to test the fast-isel code as well. Tested on powerpc64[le]-unknown-linux-gnu with no regressions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211056 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent e4f1220 commit 212ec3a

File tree

4 files changed

+28
-28
lines changed

4 files changed

+28
-28
lines changed

lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
365365
// Transform %Xd = ADDIStocHA %X2, <ga:@sym>
366366
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
367367

368-
// Change the opcode to ADDIS8. If the global address is external,
369-
// has common linkage, is a function address, or is a jump table
368+
// Change the opcode to ADDIS8. If the global address is external, has
369+
// common linkage, is a non-local function address, or is a jump table
370370
// address, then generate a TOC entry and reference that. Otherwise
371371
// reference the symbol directly.
372372
TmpInst.setOpcode(PPC::ADDIS8);
@@ -375,7 +375,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
375375
"Invalid operand for ADDIStocHA!");
376376
MCSymbol *MOSymbol = nullptr;
377377
bool IsExternal = false;
378-
bool IsFunction = false;
378+
bool IsNonLocalFunction = false;
379379
bool IsCommon = false;
380380
bool IsAvailExt = false;
381381

@@ -384,15 +384,16 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
384384
MOSymbol = getSymbol(GV);
385385
IsExternal = GV->isDeclaration();
386386
IsCommon = GV->hasCommonLinkage();
387-
IsFunction = GV->getType()->getElementType()->isFunctionTy();
387+
IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() &&
388+
(GV->isDeclaration() || GV->isWeakForLinker());
388389
IsAvailExt = GV->hasAvailableExternallyLinkage();
389390
} else if (MO.isCPI())
390391
MOSymbol = GetCPISymbol(MO.getIndex());
391392
else if (MO.isJTI())
392393
MOSymbol = GetJTISymbol(MO.getIndex());
393394

394-
if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI() ||
395-
TM.getCodeModel() == CodeModel::Large)
395+
if (IsExternal || IsNonLocalFunction || IsCommon || IsAvailExt ||
396+
MO.isJTI() || TM.getCodeModel() == CodeModel::Large)
396397
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
397398

398399
const MCExpr *Exp =
@@ -451,17 +452,19 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
451452
assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
452453
MCSymbol *MOSymbol = nullptr;
453454
bool IsExternal = false;
454-
bool IsFunction = false;
455+
bool IsNonLocalFunction = false;
455456

456457
if (MO.isGlobal()) {
457458
const GlobalValue *GV = MO.getGlobal();
458459
MOSymbol = getSymbol(GV);
459460
IsExternal = GV->isDeclaration();
460-
IsFunction = GV->getType()->getElementType()->isFunctionTy();
461+
IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() &&
462+
(GV->isDeclaration() || GV->isWeakForLinker());
461463
} else if (MO.isCPI())
462464
MOSymbol = GetCPISymbol(MO.getIndex());
463465

464-
if (IsFunction || IsExternal || TM.getCodeModel() == CodeModel::Large)
466+
if (IsNonLocalFunction || IsExternal ||
467+
TM.getCodeModel() == CodeModel::Large)
465468
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
466469

467470
const MCExpr *Exp =

lib/Target/PowerPC/PPCFastISel.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,7 +1858,6 @@ unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
18581858
// FIXME: Jump tables are not yet required because fast-isel doesn't
18591859
// handle switches; if that changes, we need them as well. For now,
18601860
// what follows assumes everything's a generic (or TLS) global address.
1861-
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
18621861

18631862
// FIXME: We don't yet handle the complexity of TLS.
18641863
if (GV->isThreadLocal())
@@ -1871,8 +1870,8 @@ unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
18711870
.addGlobalAddress(GV)
18721871
.addReg(PPC::X2);
18731872
else {
1874-
// If the address is an externally defined symbol, a symbol with
1875-
// common or externally available linkage, a function address, or a
1873+
// If the address is an externally defined symbol, a symbol with common
1874+
// or externally available linkage, a non-local function address, or a
18761875
// jump table address (not yet needed), or if we are generating code
18771876
// for large code model, we generate:
18781877
// LDtocL(GV, ADDIStocHA(%X2, GV))
@@ -1883,12 +1882,13 @@ unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
18831882
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::ADDIStocHA),
18841883
HighPartReg).addReg(PPC::X2).addGlobalAddress(GV);
18851884

1886-
// !GVar implies a function address. An external variable is one
1887-
// without an initializer.
18881885
// If/when switches are implemented, jump tables should be handled
18891886
// on the "if" path here.
1890-
if (CModel == CodeModel::Large || !GVar || !GVar->hasInitializer() ||
1891-
GVar->hasCommonLinkage() || GVar->hasAvailableExternallyLinkage())
1887+
if (CModel == CodeModel::Large ||
1888+
(GV->getType()->getElementType()->isFunctionTy() &&
1889+
(GV->isDeclaration() || GV->isWeakForLinker())) ||
1890+
GV->isDeclaration() || GV->hasCommonLinkage() ||
1891+
GV->hasAvailableExternallyLinkage())
18921892
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::LDtocL),
18931893
DestReg).addGlobalAddress(GV).addReg(HighPartReg);
18941894
else

lib/Target/PowerPC/PPCISelDAGToDAG.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,10 +1454,10 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
14541454
if (CModel != CodeModel::Medium && CModel != CodeModel::Large)
14551455
break;
14561456

1457-
// The first source operand is a TargetGlobalAddress or a
1458-
// TargetJumpTable. If it is an externally defined symbol, a symbol
1459-
// with common linkage, a function address, or a jump table address,
1460-
// or if we are generating code for large code model, we generate:
1457+
// The first source operand is a TargetGlobalAddress or a TargetJumpTable.
1458+
// If it is an externally defined symbol, a symbol with common linkage,
1459+
// a non-local function address, or a jump table address, or if we are
1460+
// generating code for large code model, we generate:
14611461
// LDtocL(<ga:@sym>, ADDIStocHA(%X2, <ga:@sym>))
14621462
// Otherwise we generate:
14631463
// ADDItocL(ADDIStocHA(%X2, <ga:@sym>), <ga:@sym>)
@@ -1472,7 +1472,8 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
14721472

14731473
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(GA)) {
14741474
const GlobalValue *GValue = G->getGlobal();
1475-
if (GValue->getType()->getElementType()->isFunctionTy() ||
1475+
if ((GValue->getType()->getElementType()->isFunctionTy() &&
1476+
(GValue->isDeclaration() || GValue->isWeakForLinker())) ||
14761477
GValue->isDeclaration() || GValue->hasCommonLinkage() ||
14771478
GValue->hasAvailableExternallyLinkage())
14781479
return CurDAG->getMachineNode(PPC::LDtocL, dl, MVT::i64, GA,

test/CodeGen/PowerPC/func-addr.ll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
; RUN: llc -mtriple powerpc64-linux < %s | FileCheck %s
2+
; RUN: llc -O0 -mtriple powerpc64-linux < %s | FileCheck %s
23

34
define void @foo() {
45
ret void
56
}
67
declare i32 @bar(i8*)
78

89
; CHECK-LABEL: {{^}}zed:
9-
; CHECK: addis 3, 2, .LC1@toc@ha
10-
; CHECK-NEXT: ld 3, .LC1@toc@l(3)
10+
; CHECK: addis 3, 2, foo@toc@ha
11+
; CHECK-NEXT: addi 3, 3, foo@toc@l
1112
; CHECK-NEXT: bl bar
1213

13-
14-
; CHECK-LABEL: .section .toc,"aw",@progbits
15-
; CHECK: .LC1:
16-
; CHECK-NEXT: .tc foo[TC],foo
17-
1814
define void @zed() {
1915
call i32 @bar(i8* bitcast (void ()* @foo to i8*))
2016
ret void

0 commit comments

Comments
 (0)