Skip to content

Commit 18b6050

Browse files
stefanp-synopsyskamaub
authored andcommitted
[PowerPC][Future] Initial support for PC Relative addressing for global values
This patch adds PC Relative support for global values that are known at link time. If a global value requires access through the global offset table (GOT) it is not covered in this patch. Differential Revision: https://reviews.llvm.org/D75280
1 parent d9085f6 commit 18b6050

File tree

5 files changed

+699
-56
lines changed

5 files changed

+699
-56
lines changed

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,17 +2588,19 @@ bool PPCTargetLowering::SelectAddressRegRegOnly(SDValue N, SDValue &Base,
25882588
}
25892589

25902590
/// Returns true if this address is a PC Relative address.
2591-
/// PC Relative addresses are marked with the flag PPCII::MO_PCREL_FLAG.
2591+
/// PC Relative addresses are marked with the flag PPCII::MO_PCREL_FLAG
2592+
/// or if the node opcode is PPCISD::MAT_PCREL_ADDR.
25922593
bool PPCTargetLowering::SelectAddressPCRel(SDValue N, SDValue &Base) const {
2593-
ConstantPoolSDNode *ConstPoolNode =
2594-
dyn_cast<ConstantPoolSDNode>(N.getNode());
2595-
bool HasFlag = ConstPoolNode &&
2596-
ConstPoolNode->getTargetFlags() == PPCII::MO_PCREL_FLAG;
2597-
bool HasNode = N.getOpcode() == PPCISD::MAT_PCREL_ADDR;
2598-
if (HasFlag || HasNode) {
2599-
Base = N;
2594+
// This is a materialize PC Relative node. Always select this as PC Relative.
2595+
Base = N;
2596+
if (N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
26002597
return true;
2601-
}
2598+
if (ConstantPoolSDNode *CPN = dyn_cast<ConstantPoolSDNode>(N))
2599+
if (CPN->getTargetFlags() & PPCII::MO_PCREL_FLAG)
2600+
return true;
2601+
if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(N))
2602+
if (GAN->getTargetFlags() & PPCII::MO_PCREL_FLAG)
2603+
return true;
26022604
return false;
26032605
}
26042606

@@ -3049,6 +3051,12 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
30493051
// 64-bit SVR4 ABI & AIX ABI code is always position-independent.
30503052
// The actual address of the GlobalValue is stored in the TOC.
30513053
if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3054+
if (!isAccessedAsGotIndirect(Op) && Subtarget.isUsingPCRelativeCalls()) {
3055+
EVT Ty = getPointerTy(DAG.getDataLayout());
3056+
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, Ty, GSDN->getOffset(),
3057+
PPCII::MO_PCREL_FLAG);
3058+
return DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, GA);
3059+
}
30523060
setUsesTOCBasePtr(DAG);
30533061
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset());
30543062
return getTOCEntry(DAG, DL, GA);

llvm/lib/Target/PowerPC/PPCInstrPrefix.td

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,30 +348,153 @@ let Predicates = [PrefixInstrs] in {
348348
// follow-up patches will address this refactoring and the AddedComplexity will
349349
// be removed.
350350
let Predicates = [PCRelativeMemops], AddedComplexity = 500 in {
351+
// Load i32
352+
def : Pat<(i32 (zextloadi8 (PPCmatpcreladdr pcreladdr:$ga))),
353+
(PLBZpc $ga, 0)>;
354+
def : Pat<(i32 (extloadi8 (PPCmatpcreladdr pcreladdr:$ga))),
355+
(PLBZpc $ga, 0)>;
356+
def : Pat<(i32 (sextloadi16 (PPCmatpcreladdr pcreladdr:$ga))),
357+
(PLHApc $ga, 0)>;
358+
def : Pat<(i32 (zextloadi16 (PPCmatpcreladdr pcreladdr:$ga))),
359+
(PLHZpc $ga, 0)>;
360+
def : Pat<(i32 (extloadi16 (PPCmatpcreladdr pcreladdr:$ga))),
361+
(PLHZpc $ga, 0)>;
362+
def : Pat<(i32 (load (PPCmatpcreladdr pcreladdr:$ga))), (PLWZpc $ga, 0)>;
363+
364+
// Store i32
365+
def : Pat<(truncstorei8 i32:$RS, (PPCmatpcreladdr pcreladdr:$ga)),
366+
(PSTBpc $RS, $ga, 0)>;
367+
def : Pat<(truncstorei16 i32:$RS, (PPCmatpcreladdr pcreladdr:$ga)),
368+
(PSTHpc $RS, $ga, 0)>;
369+
def : Pat<(store i32:$RS, (PPCmatpcreladdr pcreladdr:$ga)),
370+
(PSTWpc $RS, $ga, 0)>;
371+
372+
// Load i64
373+
def : Pat<(i64 (zextloadi8 (PPCmatpcreladdr pcreladdr:$ga))),
374+
(PLBZ8pc $ga, 0)>;
375+
def : Pat<(i64 (extloadi8 (PPCmatpcreladdr pcreladdr:$ga))),
376+
(PLBZ8pc $ga, 0)>;
377+
def : Pat<(i64 (sextloadi16 (PPCmatpcreladdr pcreladdr:$ga))),
378+
(PLHA8pc $ga, 0)>;
379+
def : Pat<(i64 (zextloadi16 (PPCmatpcreladdr pcreladdr:$ga))),
380+
(PLHZ8pc $ga, 0)>;
381+
def : Pat<(i64 (extloadi16 (PPCmatpcreladdr pcreladdr:$ga))),
382+
(PLHZ8pc $ga, 0)>;
383+
def : Pat<(i64 (zextloadi32 (PPCmatpcreladdr pcreladdr:$ga))),
384+
(PLWZ8pc $ga, 0)>;
385+
def : Pat<(i64 (sextloadi32 (PPCmatpcreladdr pcreladdr:$ga))),
386+
(PLWA8pc $ga, 0)>;
387+
def : Pat<(i64 (extloadi32 (PPCmatpcreladdr pcreladdr:$ga))),
388+
(PLWZ8pc $ga, 0)>;
389+
def : Pat<(i64 (load (PPCmatpcreladdr pcreladdr:$ga))), (PLDpc $ga, 0)>;
390+
391+
// Store i64
392+
def : Pat<(truncstorei8 i64:$RS, (PPCmatpcreladdr pcreladdr:$ga)),
393+
(PSTB8pc $RS, $ga, 0)>;
394+
def : Pat<(truncstorei16 i64:$RS, (PPCmatpcreladdr pcreladdr:$ga)),
395+
(PSTH8pc $RS, $ga, 0)>;
396+
def : Pat<(truncstorei32 i64:$RS, (PPCmatpcreladdr pcreladdr:$ga)),
397+
(PSTW8pc $RS, $ga, 0)>;
398+
def : Pat<(store i64:$RS, (PPCmatpcreladdr pcreladdr:$ga)),
399+
(PSTDpc $RS, $ga, 0)>;
400+
351401
// Load f32
352402
def : Pat<(f32 (load (PPCmatpcreladdr pcreladdr:$addr))), (PLFSpc $addr, 0)>;
353403

404+
// Store f32
405+
def : Pat<(store f32:$FRS, (PPCmatpcreladdr pcreladdr:$ga)),
406+
(PSTFSpc $FRS, $ga, 0)>;
407+
354408
// Load f64
355409
def : Pat<(f64 (extloadf32 (PPCmatpcreladdr pcreladdr:$addr))),
356410
(COPY_TO_REGCLASS (PLFSpc $addr, 0), VSFRC)>;
357411
def : Pat<(f64 (load (PPCmatpcreladdr pcreladdr:$addr))), (PLFDpc $addr, 0)>;
358412

413+
// Store f64
414+
def : Pat<(store f64:$FRS, (PPCmatpcreladdr pcreladdr:$ga)),
415+
(PSTFDpc $FRS, $ga, 0)>;
416+
359417
// Load f128
360418
def : Pat<(f128 (load (PPCmatpcreladdr pcreladdr:$addr))),
361419
(COPY_TO_REGCLASS (PLXVpc $addr, 0), VRRC)>;
362420

421+
// Store f128
422+
def : Pat<(store f128:$XS, (PPCmatpcreladdr pcreladdr:$ga)),
423+
(PSTXVpc (COPY_TO_REGCLASS $XS, VSRC), $ga, 0)>;
424+
363425
// Load v4i32
364426
def : Pat<(v4i32 (load (PPCmatpcreladdr pcreladdr:$addr))), (PLXVpc $addr, 0)>;
365427

428+
// Store v4i32
429+
def : Pat<(store v4i32:$XS, (PPCmatpcreladdr pcreladdr:$ga)),
430+
(PSTXVpc $XS, $ga, 0)>;
431+
366432
// Load v2i64
367433
def : Pat<(v2i64 (load (PPCmatpcreladdr pcreladdr:$addr))), (PLXVpc $addr, 0)>;
368434

435+
// Store v2i64
436+
def : Pat<(store v2i64:$XS, (PPCmatpcreladdr pcreladdr:$ga)),
437+
(PSTXVpc $XS, $ga, 0)>;
438+
369439
// Load v4f32
370440
def : Pat<(v4f32 (load (PPCmatpcreladdr pcreladdr:$addr))), (PLXVpc $addr, 0)>;
371441

442+
// Store v4f32
443+
def : Pat<(store v4f32:$XS, (PPCmatpcreladdr pcreladdr:$ga)),
444+
(PSTXVpc $XS, $ga, 0)>;
445+
372446
// Load v2f64
373447
def : Pat<(v2f64 (load (PPCmatpcreladdr pcreladdr:$addr))), (PLXVpc $addr, 0)>;
374448

449+
// Store v2f64
450+
def : Pat<(store v2f64:$XS, (PPCmatpcreladdr pcreladdr:$ga)),
451+
(PSTXVpc $XS, $ga, 0)>;
452+
453+
// Atomic Load
454+
def : Pat<(atomic_load_8 (PPCmatpcreladdr pcreladdr:$ga)),
455+
(PLBZpc $ga, 0)>;
456+
def : Pat<(atomic_load_16 (PPCmatpcreladdr pcreladdr:$ga)),
457+
(PLHZpc $ga, 0)>;
458+
def : Pat<(atomic_load_32 (PPCmatpcreladdr pcreladdr:$ga)),
459+
(PLWZpc $ga, 0)>;
460+
def : Pat<(atomic_load_64 (PPCmatpcreladdr pcreladdr:$ga)),
461+
(PLDpc $ga, 0)>;
462+
463+
// Atomic Store
464+
def : Pat<(atomic_store_8 (PPCmatpcreladdr pcreladdr:$ga), i32:$RS),
465+
(PSTBpc $RS, $ga, 0)>;
466+
def : Pat<(atomic_store_16 (PPCmatpcreladdr pcreladdr:$ga), i32:$RS),
467+
(PSTHpc $RS, $ga, 0)>;
468+
def : Pat<(atomic_store_32 (PPCmatpcreladdr pcreladdr:$ga), i32:$RS),
469+
(PSTWpc $RS, $ga, 0)>;
470+
def : Pat<(atomic_store_8 (PPCmatpcreladdr pcreladdr:$ga), i64:$RS),
471+
(PSTB8pc $RS, $ga, 0)>;
472+
def : Pat<(atomic_store_16 (PPCmatpcreladdr pcreladdr:$ga), i64:$RS),
473+
(PSTH8pc $RS, $ga, 0)>;
474+
def : Pat<(atomic_store_32 (PPCmatpcreladdr pcreladdr:$ga), i64:$RS),
475+
(PSTW8pc $RS, $ga, 0)>;
476+
def : Pat<(atomic_store_64 (PPCmatpcreladdr pcreladdr:$ga), i64:$RS),
477+
(PSTDpc $RS, $ga, 0)>;
478+
479+
// Special Cases For PPCstore_scal_int_from_vsr
480+
def : Pat<(PPCstore_scal_int_from_vsr
481+
(f64 (PPCcv_fp_to_sint_in_vsr f64:$src)),
482+
(PPCmatpcreladdr pcreladdr:$dst), 8),
483+
(PSTXSDpc (XSCVDPSXDS f64:$src), $dst, 0)>;
484+
def : Pat<(PPCstore_scal_int_from_vsr
485+
(f64 (PPCcv_fp_to_sint_in_vsr f128:$src)),
486+
(PPCmatpcreladdr pcreladdr:$dst), 8),
487+
(PSTXSDpc (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), $dst, 0)>;
488+
489+
def : Pat<(PPCstore_scal_int_from_vsr
490+
(f64 (PPCcv_fp_to_uint_in_vsr f64:$src)),
491+
(PPCmatpcreladdr pcreladdr:$dst), 8),
492+
(PSTXSDpc (XSCVDPUXDS f64:$src), $dst, 0)>;
493+
def : Pat<(PPCstore_scal_int_from_vsr
494+
(f64 (PPCcv_fp_to_uint_in_vsr f128:$src)),
495+
(PPCmatpcreladdr pcreladdr:$dst), 8),
496+
(PSTXSDpc (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), $dst, 0)>;
497+
375498
// If the PPCmatpcreladdr node is not caught by any other pattern it should be
376499
// caught here and turned into a paddi instruction to materialize the address.
377500
def : Pat<(PPCmatpcreladdr pcreladdr:$addr), (PADDI8pc 0, $addr)>;

0 commit comments

Comments
 (0)