diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2539,6 +2539,11 @@ return true; } +template static bool isValidPCRelNode(SDValue N) { + Ty *PCRelCand = dyn_cast(N); + return PCRelCand && (PCRelCand->getTargetFlags() & PPCII::MO_PCREL_FLAG); +} + /// Returns true if this address is a PC Relative address. /// PC Relative addresses are marked with the flag PPCII::MO_PCREL_FLAG. bool PPCTargetLowering::SelectAddressPCRel(SDValue N, SDValue &Base) const { @@ -2548,18 +2553,14 @@ return true; } - ConstantPoolSDNode *ConstPoolNode = - dyn_cast(N.getNode()); - bool ConstPool = ConstPoolNode && - ConstPoolNode->getTargetFlags() | PPCII::MO_PCREL_FLAG; - GlobalAddressSDNode *GSDN = dyn_cast(N.getNode()); - bool Global = GSDN && GSDN->getTargetFlags() | PPCII::MO_PCREL_FLAG; - JumpTableSDNode *JT = dyn_cast(N.getNode()); - bool JumpTable = JT && JT->getTargetFlags() | PPCII::MO_PCREL_FLAG; - if (ConstPool || Global || JumpTable) { + if (isValidPCRelNode(N) || + isValidPCRelNode(N) || + isValidPCRelNode(N) || + isValidPCRelNode(N)) { Base = N; return true; } + return false; } @@ -2891,6 +2892,16 @@ BlockAddressSDNode *BASDN = cast(Op); const BlockAddress *BA = BASDN->getBlockAddress(); + // isUsingPCRelativeCalls() returns true when PCRelative is enabled + if (Subtarget.isUsingPCRelativeCalls()) { + SDLoc DL(BASDN); + EVT Ty = getPointerTy(DAG.getDataLayout()); + SDValue GA = DAG.getTargetBlockAddress(BA, Ty, BASDN->getOffset(), + PPCII::MO_PCREL_FLAG); + SDValue MatAddr = DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, GA); + return MatAddr; + } + // 64-bit SVR4 ABI and AIX ABI code are always position-independent. // The actual BlockAddress is stored in the TOC. if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) { diff --git a/llvm/test/CodeGen/PowerPC/pcrel-block-address.ll b/llvm/test/CodeGen/PowerPC/pcrel-block-address.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/pcrel-block-address.ll @@ -0,0 +1,19 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=future -ppc-asm-full-reg-names < %s | FileCheck %s + +; The test checks for getting block address using PC Relative addressing. + +define dso_local void @blockaddress() { +; CHECK-LABEL: blockaddress: +; CHECK: # %bb.0: # %entry +; CHECK: paddi r3, 0, .Ltmp0@PCREL, 1 +; CHECK: bl helper@notoc +entry: + tail call void @helper(i8* blockaddress(@blockaddress, %label)) + br label %label + +label: ; preds = %entry + ret void +} + +declare void @helper(i8*)