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 @@ -5102,9 +5102,10 @@ auto isLocalCallee = [&]() { const GlobalAddressSDNode *G = dyn_cast(Callee); const Module *Mod = DAG.getMachineFunction().getFunction().getParent(); + const GlobalValue *GV = G ? G->getGlobal() : nullptr; - return DAG.getTarget().shouldAssumeDSOLocal(*Mod, - G ? G->getGlobal() : nullptr); + return DAG.getTarget().shouldAssumeDSOLocal(*Mod, GV) && + !dyn_cast_or_null(GV); }; bool UsePlt = Subtarget.is32BitELFABI() && !isLocalCallee(); diff --git a/llvm/test/CodeGen/PowerPC/ifunc-dsolocal.ll b/llvm/test/CodeGen/PowerPC/ifunc-dsolocal.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/ifunc-dsolocal.ll @@ -0,0 +1,19 @@ +; RUN: llc %s -o - -mtriple=powerpc | FileCheck --check-prefix=REL %s +; RUN: llc %s -o - -mtriple=powerpc -relocation-model=pic | FileCheck --check-prefix=PLTREL %s +; RUN: llc %s -o - -mtriple=powerpc64 | FileCheck --check-prefix=REL %s +; RUN: llc %s -o - -mtriple=powerpc64 -relocation-model=pic | FileCheck --check-prefix=REL %s + +@ifunc1 = dso_local ifunc void(), i8*()* @resolver +@ifunc2 = ifunc void(), i8*()* @resolver + +define i8* @resolver() { ret i8* null } + +define void @foo() { + ; REL: bl ifunc1{{$}} + ; REL: bl ifunc2{{$}} + ; PLTREL: bl ifunc1@PLT + ; PLTREL: bl ifunc2@PLT + call void @ifunc1() + call void @ifunc2() + ret void +}