Skip to content

Commit 13daabc

Browse files
author
Zaara Syeda
committed
Rebase and address review comments
1 parent 6800f42 commit 13daabc

File tree

5 files changed

+143
-19
lines changed

5 files changed

+143
-19
lines changed

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,15 +1147,28 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
11471147

11481148
MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
11491149

1150-
// Always use TOC on AIX. Map the global address operand to be a reference
1151-
// to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
1152-
// reference the storage allocated in the TOC which contains the address of
1153-
// 'MOSymbol'.
1154-
MCSymbol *TOCEntry =
1155-
lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1156-
const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
1157-
MCSymbolRefExpr::VK_PPC_U,
1158-
OutContext);
1150+
// If the symbol isn't toc-data then use the TOC on AIX.
1151+
// Map the global address operand to be a reference to the TOC entry we
1152+
// will synthesize later. 'TOCEntry' is a label used to reference the
1153+
// storage allocated in the TOC which contains the address of 'MOSymbol'.
1154+
// If the toc-data attribute is used, the TOC entry contains the data
1155+
// rather than the address of the MOSymbol.
1156+
auto isSymbolTD = [](const MachineOperand &MO) {
1157+
if (!MO.isGlobal())
1158+
return false;
1159+
1160+
const GlobalVariable *GV = dyn_cast<GlobalVariable>(MO.getGlobal());
1161+
if (!GV)
1162+
return false;
1163+
1164+
return GV->hasAttribute("toc-data");
1165+
};
1166+
1167+
if (!isSymbolTD(MO))
1168+
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1169+
1170+
const MCExpr *Exp = MCSymbolRefExpr::create(
1171+
MOSymbol, MCSymbolRefExpr::VK_PPC_U, OutContext);
11591172
TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
11601173
EmitToStreamer(*OutStreamer, TmpInst);
11611174
return;
@@ -1272,6 +1285,30 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
12721285
EmitToStreamer(*OutStreamer, TmpInst);
12731286
return;
12741287
}
1288+
case PPC::ADDItocL: {
1289+
// Transform %xd = ADDItocL %xs, @sym
1290+
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1291+
1292+
// Change the opcode to load address.
1293+
TmpInst.setOpcode(PPC::LA);
1294+
1295+
const MachineOperand &MO = MI->getOperand(2);
1296+
assert(MO.isGlobal() && "Invalid operand for ADDItocL.");
1297+
1298+
LLVM_DEBUG(assert(
1299+
!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
1300+
"Interposable definitions must use indirect accesses."));
1301+
1302+
// Map the operand to its corresponding MCSymbol.
1303+
const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1304+
1305+
const MCExpr *Exp = MCSymbolRefExpr::create(
1306+
MOSymbol, MCSymbolRefExpr::VK_PPC_L, OutContext);
1307+
1308+
TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
1309+
EmitToStreamer(*OutStreamer, TmpInst);
1310+
return;
1311+
}
12751312
case PPC::ADDItocL8: {
12761313
// Transform %xd = ADDItocL8 %xs, @sym
12771314
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
@@ -1286,7 +1323,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
12861323

12871324
LLVM_DEBUG(assert(
12881325
!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
1289-
"Interposable definitions must use indirect access."));
1326+
"Interposable definitions must use indirect accesses."));
12901327

12911328
const MCExpr *Exp =
12921329
MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO, *this),

llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
510510
}
511511

512512
// Check if a SDValue has the toc-data attribute.
513-
static bool hasTocDataAttr(SDValue Val, unsigned PointerSize) {
513+
static bool hasTocDataAttr(SDValue Val) {
514514
GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Val);
515515
if (!GA)
516516
return false;
@@ -6115,8 +6115,7 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
61156115

61166116
assert(isAIXABI && "ELF ABI already handled");
61176117

6118-
if (hasTocDataAttr(N->getOperand(0),
6119-
CurDAG->getDataLayout().getPointerSize())) {
6118+
if (hasTocDataAttr(N->getOperand(0))) {
61206119
replaceWith(PPC::ADDItoc, N, MVT::i32);
61216120
return;
61226121
}
@@ -6128,8 +6127,7 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
61286127
if (isPPC64 && CModel == CodeModel::Small) {
61296128
assert(isAIXABI && "ELF ABI handled in common SelectCode");
61306129

6131-
if (hasTocDataAttr(N->getOperand(0),
6132-
CurDAG->getDataLayout().getPointerSize())) {
6130+
if (hasTocDataAttr(N->getOperand(0))) {
61336131
replaceWith(PPC::ADDItoc8, N, MVT::i64);
61346132
return;
61356133
}
@@ -6144,23 +6142,44 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
61446142
" ELF/AIX or 32-bit AIX in the following.");
61456143

61466144
// Transforms the ISD::TOC_ENTRY node for 32-bit AIX large code model mode
6147-
// or 64-bit medium (ELF-only) or large (ELF and AIX) code model code. We
6148-
// generate two instructions as described below. The first source operand
6149-
// is a symbol reference. If it must be toc-referenced according to
6145+
// or 64-bit medium (ELF-only) or large (ELF and AIX) code model code non
6146+
// toc-data symbols.
6147+
// We generate two instructions as described below. The first source
6148+
// operand is a symbol reference. If it must be toc-referenced according to
61506149
// Subtarget, we generate:
61516150
// [32-bit AIX]
61526151
// LWZtocL(@sym, ADDIStocHA(%r2, @sym))
61536152
// [64-bit ELF/AIX]
61546153
// LDtocL(@sym, ADDIStocHA8(%x2, @sym))
61556154
// Otherwise we generate:
61566155
// ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
6156+
6157+
// For large code model toc-data symbols we generate:
6158+
// [32-bit AIX]
6159+
// ADDItocL(ADDIStocHA(%x2, @sym), @sym)
6160+
// [64-bit AIX]
6161+
// ADDItocL8(ADDIStocHA8(%x2, @sym), @sym)
6162+
61576163
SDValue GA = N->getOperand(0);
61586164
SDValue TOCbase = N->getOperand(1);
61596165

61606166
EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
61616167
SDNode *Tmp = CurDAG->getMachineNode(
61626168
isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
61636169

6170+
// On AIX if the symbol has the toc-data attribute it will be defined
6171+
// in the TOC entry, so we use an ADDItocL similar to the medium code
6172+
// model ELF abi.
6173+
if (isAIXABI && hasTocDataAttr(GA)) {
6174+
if (isPPC64)
6175+
report_fatal_error(
6176+
"64-bit large code model toc-data not yet supported");
6177+
6178+
ReplaceNode(N, CurDAG->getMachineNode(PPC::ADDItocL, dl, VT,
6179+
SDValue(Tmp, 0), GA));
6180+
return;
6181+
}
6182+
61646183
if (PPCLowering->isAccessedAsGotIndirect(GA)) {
61656184
// If it is accessed as got-indirect, we need an extra LWZ/LD to load
61666185
// the address.

llvm/lib/Target/PowerPC/PPCInstrInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,7 @@ bool PPCInstrInfo::isReallyTriviallyReMaterializable(
10771077
case PPC::LIS8:
10781078
case PPC::ADDIStocHA:
10791079
case PPC::ADDIStocHA8:
1080+
case PPC::ADDItocL:
10801081
case PPC::ADDItocL8:
10811082
case PPC::LOAD_STACK_GUARD:
10821083
case PPC::PPCLdFixedAddr:

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3346,11 +3346,13 @@ def ADDIStocHA : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, tocentr
33463346
"#ADDIStocHA",
33473347
[(set i32:$rD,
33483348
(PPCtoc_entry i32:$reg, tglobaladdr:$disp))]>;
3349-
// Local Data Transform
3349+
// TOC Data Transform AIX
33503350
def ADDItoc : PPCEmitTimePseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg),
33513351
"#ADDItoc",
33523352
[(set i32:$rD,
33533353
(PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
3354+
def ADDItocL : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, tocentry32:$disp),
3355+
"#ADDItocL", []>;
33543356

33553357
// Get Global (GOT) Base Register offset, from the word immediately preceding
33563358
// the function label.

llvm/test/CodeGen/PowerPC/toc-data.ll

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
; RUN: llc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST32
1313
; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST64
1414

15+
; RUN: llc -mtriple powerpc-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s \
16+
; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK32LARGE
17+
; RUN: llc -mtriple powerpc-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST32LARGE
18+
19+
; Global variables i and f have the toc-data attribute.
20+
; In the following functions, those writing to or reading from
21+
; variables i and f should use the toc-data access pattern.
22+
; All remaining variables should use the regular toc access sequence.
1523
@i = dso_local global i32 0, align 4 #0
1624
@d = dso_local local_unnamed_addr global double 3.141590e+00, align 8
1725
@f = dso_local local_unnamed_addr global float 0x4005BE76C0000000, align 4 #0
@@ -44,6 +52,15 @@ define dso_local void @write_int(i32 signext %in) {
4452
; TEST64: la 4, i[TD](2)
4553
; TEST64-NEXT: stw 3, 0(4)
4654

55+
; CHECK32LARGE: name: write_int
56+
; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @i
57+
; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc_and_gprc_nor0 = ADDItocL killed %[[SCRATCH1]], @i
58+
; CHECK32LARGE-NEXT: STW %{{[0-9]+}}, 0, killed %[[SCRATCH2]] :: (store (s32) into @i)
59+
60+
; TEST32LARGE: .write_int:
61+
; TEST32LARGE: addis 4, i[TD]@u(2)
62+
; TEST32LARGE-NEXT: la 4, i[TD]@l(4)
63+
; TEST32LARGE-NEXT: stw 3, 0(4)
4764

4865
define dso_local i64 @read_ll() {
4966
entry:
@@ -70,6 +87,15 @@ define dso_local i64 @read_ll() {
7087
; TEST64: ld 3, L..C0(2)
7188
; TEST64-NEXT: ld 3, 0(3)
7289

90+
; CHECK32LARGE: name: read_ll
91+
; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @ll
92+
; CHECK32LARGE: LWZtocL @ll, killed %[[SCRATCH1]] :: (load (s32) from got)
93+
94+
; TEST32LARGE: .read_ll:
95+
; TEST32LARGE: addis 3, L..C0@u(2)
96+
; TEST32LARGE-NEXT: lwz 4, L..C0@l(3)
97+
; TEST32LARGE-NEXT: lwz 3, 0(4)
98+
; TEST32LARGE-NEXT: lwz 4, 4(4)
7399

74100
define dso_local float @read_float() {
75101
entry:
@@ -96,6 +122,15 @@ define dso_local float @read_float() {
96122
; TEST64: la 3, f[TD](2)
97123
; TEST64-NEXT: lfs 1, 0(3)
98124

125+
; CHECK32LARGE: name: read_float
126+
; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @f
127+
; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc_and_gprc_nor0 = ADDItocL killed %[[SCRATCH1]], @f
128+
; CHECK32LARGE-NEXT: LFS 0, killed %[[SCRATCH2]] :: (dereferenceable load (s32) from @f)
129+
130+
; TEST32LARGE: .read_float:
131+
; TEST32LARGE: addis 3, f[TD]@u(2)
132+
; TEST32LARGE-NEXT: la 3, f[TD]@l(3)
133+
; TEST32LARGE-NEXT: lfs 1, 0(3)
99134

100135
define dso_local void @write_double(double %in) {
101136
entry:
@@ -121,6 +156,14 @@ define dso_local void @write_double(double %in) {
121156
; TEST64: ld 3, L..C1(2)
122157
; TEST64-NEXT: stfd 1, 0(3)
123158

159+
; CHECK32LARGE: name: write_double
160+
; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @d
161+
; CHECK32LARGE: LWZtocL @d, killed %[[SCRATCH1]] :: (load (s32) from got)
162+
163+
; TEST32LARGE: .write_double:
164+
; TEST32LARGE: addis 3, L..C1@u(2)
165+
; TEST32LARGE-NEXT: lwz 3, L..C1@l(3)
166+
; TEST32LARGE-NEXT: stfd 1, 0(3)
124167

125168
define dso_local nonnull ptr @addr() {
126169
entry:
@@ -144,6 +187,15 @@ define dso_local nonnull ptr @addr() {
144187
; TEST64: .addr
145188
; TEST64: la 3, i[TD](2)
146189

190+
; CHECK32LARGE: name: addr
191+
; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @i
192+
; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc = ADDItocL killed %[[SCRATCH1]], @i
193+
; CHECK32LARGE-NEXT: $r3 = COPY %[[SCRATCH2]]
194+
195+
; TEST32LARGE: .addr:
196+
; TEST32LARGE: addis 3, i[TD]@u(2)
197+
; TEST32LARGE-NEXT: la 3, i[TD]@l(3)
198+
147199
; TEST32: .toc
148200
; TEST32: .tc ll[TC],ll[RW]
149201
; TEST32-NOT: .csect ll[TD]
@@ -170,4 +222,17 @@ define dso_local nonnull ptr @addr() {
170222
; TEST64-NEXT: .globl f[TD]
171223
; TEST64-NOT: .tc f[TD],f[RW]
172224

225+
; TEST32LARGE: .toc
226+
; TEST32LARGE: .tc ll[TE],ll[RW]
227+
; TEST32LARGE-NOT: .csect ll[TD]
228+
; TEST32LARGE: .tc d[TE],d[RW]
229+
; TEST32LARGE-NOT: .csect d[TD],2
230+
; TEST32LARGE: .csect i[TD],2
231+
; TEST32LARGE-NEXT: .globl i[TD]
232+
; TEST32LARGE-NEXT: .align 2
233+
; TEST32LARGE-NOT: .tc i[TE],i[RW]
234+
; TEST32LARGE: .csect f[TD],2
235+
; TEST32LARGE-NEXT: .globl f[TD]
236+
; TEST32LARGE-NOT: .tc f[TE],f[RW]
237+
173238
attributes #0 = { "toc-data" }

0 commit comments

Comments
 (0)