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 @@ -2588,6 +2588,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 /// or if the node opcode is PPCISD::MAT_PCREL_ADDR. @@ -2596,15 +2601,11 @@ Base = N; if (N.getOpcode() == PPCISD::MAT_PCREL_ADDR) return true; - if (ConstantPoolSDNode *CPN = dyn_cast(N)) - if (CPN->getTargetFlags() & PPCII::MO_PCREL_FLAG) - return true; - if (GlobalAddressSDNode *GAN = dyn_cast(N)) - if (GAN->getTargetFlags() & PPCII::MO_PCREL_FLAG) - return true; - if (JumpTableSDNode *JT = dyn_cast(N)) - if (JT->getTargetFlags() & PPCII::MO_PCREL_FLAG) - return true; + if (isValidPCRelNode(N) || + isValidPCRelNode(N) || + isValidPCRelNode(N) || + isValidPCRelNode(N)) + return true; return false; } @@ -2936,6 +2937,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,16 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=future -ppc-asm-full-reg-names < %s | FileCheck %s +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*)