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

Commit 3de08c6

Browse files
committed
Weak non-function symbols were being accessed directly, which is
incorrect, as the chosen representative of the weak symbol may not live with the code in question. Always indirect the access through the TOC instead. Patch by Kyle Butt! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253708 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 177d040 commit 3de08c6

File tree

6 files changed

+91
-47
lines changed

6 files changed

+91
-47
lines changed

lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -669,28 +669,22 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
669669
MO.isBlockAddress()) &&
670670
"Invalid operand for ADDIStocHA!");
671671
MCSymbol *MOSymbol = nullptr;
672-
bool IsExternal = false;
673-
bool IsNonLocalFunction = false;
674-
bool IsCommon = false;
675-
bool IsAvailExt = false;
672+
bool GlobalToc = false;
676673

677674
if (MO.isGlobal()) {
678675
const GlobalValue *GV = MO.getGlobal();
679676
MOSymbol = getSymbol(GV);
680-
IsExternal = GV->isDeclaration();
681-
IsCommon = GV->hasCommonLinkage();
682-
IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() &&
683-
!GV->isStrongDefinitionForLinker();
684-
IsAvailExt = GV->hasAvailableExternallyLinkage();
685-
} else if (MO.isCPI())
677+
unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
678+
GlobalToc = (GVFlags & PPCII::MO_NLP_FLAG);
679+
} else if (MO.isCPI()) {
686680
MOSymbol = GetCPISymbol(MO.getIndex());
687-
else if (MO.isJTI())
681+
} else if (MO.isJTI()) {
688682
MOSymbol = GetJTISymbol(MO.getIndex());
689-
else if (MO.isBlockAddress())
683+
} else if (MO.isBlockAddress()) {
690684
MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
685+
}
691686

692-
if (IsExternal || IsNonLocalFunction || IsCommon || IsAvailExt ||
693-
MO.isJTI() || MO.isBlockAddress() ||
687+
if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
694688
TM.getCodeModel() == CodeModel::Large)
695689
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
696690

@@ -727,13 +721,14 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
727721
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
728722
}
729723
else if (MO.isGlobal()) {
730-
const GlobalValue *GValue = MO.getGlobal();
731-
MOSymbol = getSymbol(GValue);
732-
if (GValue->getType()->getElementType()->isFunctionTy() ||
733-
GValue->isDeclaration() || GValue->hasCommonLinkage() ||
734-
GValue->hasAvailableExternallyLinkage() ||
735-
TM.getCodeModel() == CodeModel::Large)
736-
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
724+
const GlobalValue *GV = MO.getGlobal();
725+
MOSymbol = getSymbol(GV);
726+
DEBUG(
727+
unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
728+
assert((GVFlags & PPCII::MO_NLP_FLAG) &&
729+
"LDtocL used on symbol that could be accessed directly is "
730+
"invalid. Must match ADDIStocHA."));
731+
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
737732
}
738733

739734
const MCExpr *Exp =
@@ -754,21 +749,18 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
754749
const MachineOperand &MO = MI->getOperand(2);
755750
assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
756751
MCSymbol *MOSymbol = nullptr;
757-
bool IsExternal = false;
758-
bool IsNonLocalFunction = false;
759752

760753
if (MO.isGlobal()) {
761754
const GlobalValue *GV = MO.getGlobal();
755+
DEBUG(
756+
unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
757+
assert (
758+
!(GVFlags & PPCII::MO_NLP_FLAG) &&
759+
"Interposable definitions must use indirect access."));
762760
MOSymbol = getSymbol(GV);
763-
IsExternal = GV->isDeclaration();
764-
IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() &&
765-
!GV->isStrongDefinitionForLinker();
766-
} else if (MO.isCPI())
761+
} else if (MO.isCPI()) {
767762
MOSymbol = GetCPISymbol(MO.getIndex());
768-
769-
if (IsNonLocalFunction || IsExternal ||
770-
TM.getCodeModel() == CodeModel::Large)
771-
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
763+
}
772764

773765
const MCExpr *Exp =
774766
MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,

lib/Target/PowerPC/PPCFastISel.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,19 +1972,15 @@ unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
19721972
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::ADDIStocHA),
19731973
HighPartReg).addReg(PPC::X2).addGlobalAddress(GV);
19741974

1975-
// If/when switches are implemented, jump tables should be handled
1976-
// on the "if" path here.
1977-
if (CModel == CodeModel::Large ||
1978-
(GV->getType()->getElementType()->isFunctionTy() &&
1979-
!GV->isStrongDefinitionForLinker()) ||
1980-
GV->isDeclaration() || GV->hasCommonLinkage() ||
1981-
GV->hasAvailableExternallyLinkage())
1975+
unsigned char GVFlags = PPCSubTarget->classifyGlobalReference(GV);
1976+
if (GVFlags & PPCII::MO_NLP_FLAG) {
19821977
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::LDtocL),
19831978
DestReg).addGlobalAddress(GV).addReg(HighPartReg);
1984-
else
1979+
} else {
19851980
// Otherwise generate the ADDItocL.
19861981
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::ADDItocL),
19871982
DestReg).addReg(HighPartReg).addGlobalAddress(GV);
1983+
}
19881984
}
19891985

19901986
return DestReg;

lib/Target/PowerPC/PPCISelDAGToDAG.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2902,9 +2902,7 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
29022902
break;
29032903

29042904
// The first source operand is a TargetGlobalAddress or a TargetJumpTable.
2905-
// If it is an externally defined symbol, a symbol with common linkage,
2906-
// a non-local function address, or a jump table address, or if we are
2907-
// generating code for large code model, we generate:
2905+
// If it must be toc-referenced according to PPCSubTarget, we generate:
29082906
// LDtocL(<ga:@sym>, ADDIStocHA(%X2, <ga:@sym>))
29092907
// Otherwise we generate:
29102908
// ADDItocL(ADDIStocHA(%X2, <ga:@sym>), <ga:@sym>)
@@ -2919,13 +2917,12 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
29192917
MVT::i64, GA, SDValue(Tmp, 0)));
29202918

29212919
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(GA)) {
2922-
const GlobalValue *GValue = G->getGlobal();
2923-
if ((GValue->getType()->getElementType()->isFunctionTy() &&
2924-
!GValue->isStrongDefinitionForLinker()) ||
2925-
GValue->isDeclaration() || GValue->hasCommonLinkage() ||
2926-
GValue->hasAvailableExternallyLinkage())
2920+
const GlobalValue *GV = G->getGlobal();
2921+
unsigned char GVFlags = PPCSubTarget->classifyGlobalReference(GV);
2922+
if (GVFlags & PPCII::MO_NLP_FLAG) {
29272923
return transferMemOperands(N, CurDAG->getMachineNode(PPC::LDtocL, dl,
29282924
MVT::i64, GA, SDValue(Tmp, 0)));
2925+
}
29292926
}
29302927

29312928
return CurDAG->getMachineNode(PPC::ADDItocL, dl, MVT::i64,

lib/Target/PowerPC/PPCSubtarget.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,33 @@ bool PPCSubtarget::enableSubRegLiveness() const {
210210
return UseSubRegLiveness;
211211
}
212212

213+
unsigned char PPCSubtarget::classifyGlobalReference(
214+
const GlobalValue *GV) const {
215+
// Note that currently we don't generate non-pic references.
216+
// If a caller wants that, this will have to be updated.
217+
218+
// Large code model always uses the TOC even for local symbols.
219+
if (TM.getCodeModel() == CodeModel::Large)
220+
return PPCII::MO_PIC_FLAG | PPCII::MO_NLP_FLAG;
221+
222+
unsigned char flags = PPCII::MO_PIC_FLAG;
223+
224+
// Only if the relocation mode is PIC do we have to worry about
225+
// interposition. In all other cases we can use a slightly looser standard to
226+
// decide how to access the symbol.
227+
if (TM.getRelocationModel() == Reloc::PIC_) {
228+
// If it's local, or it's non-default, it can't be interposed.
229+
if (!GV->hasLocalLinkage() &&
230+
GV->hasDefaultVisibility()) {
231+
flags |= PPCII::MO_NLP_FLAG;
232+
}
233+
return flags;
234+
}
235+
236+
if (GV->isStrongDefinitionForLinker())
237+
return flags;
238+
return flags | PPCII::MO_NLP_FLAG;
239+
}
240+
213241
bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); }
214242
bool PPCSubtarget::isPPC64() const { return TM.isPPC64(); }

lib/Target/PowerPC/PPCSubtarget.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ class PPCSubtarget : public PPCGenSubtargetInfo {
285285
bool useAA() const override;
286286

287287
bool enableSubRegLiveness() const override;
288+
289+
/// classifyGlobalReference - Classify a global variable reference for the
290+
/// current subtarget accourding to how we should reference it.
291+
unsigned char classifyGlobalReference(const GlobalValue *GV) const;
288292
};
289293
} // End llvm namespace
290294

test/CodeGen/PowerPC/mcm-13.ll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; RUN: llc -mcpu=pwr7 -O0 -code-model=medium <%s | FileCheck %s
2+
; RUN: llc -mcpu=pwr7 -O0 -code-model=large <%s | FileCheck %s
3+
4+
; Test correct code generation for medium and large code model
5+
; for loading and storing a weak variable
6+
7+
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"
8+
target triple = "powerpc64-unknown-linux-gnu"
9+
10+
@wi = weak global i32 0, align 4
11+
12+
define signext i32 @test_weak() nounwind {
13+
entry:
14+
%0 = load i32, i32* @wi, align 4
15+
%inc = add nsw i32 %0, 1
16+
store i32 %inc, i32* @wi, align 4
17+
ret i32 %0
18+
}
19+
20+
; CHECK-LABEL: test_weak:
21+
; CHECK: addis [[REG1:[0-9]+]], 2, .LC[[TOCNUM:[0-9]+]]@toc@ha
22+
; CHECK: ld [[REG2:[0-9]+]], .LC[[TOCNUM]]@toc@l([[REG1]])
23+
; CHECK: lwz {{[0-9]+}}, 0([[REG2]])
24+
; CHECK: stw {{[0-9]+}}, 0([[REG2]])
25+
; CHECK: .section .toc
26+
; CHECK: .LC[[TOCNUM]]:
27+
; CHECK: .tc {{[a-z0-9A-Z_.]+}}[TC],{{[a-z0-9A-Z_.]+}}

0 commit comments

Comments
 (0)