diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp --- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp +++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp @@ -1555,8 +1555,8 @@ if (!Callee && !Symbol) return false; - // Allow SelectionDAG isel to handle tail calls. - if (IsTailCall) + // Allow SelectionDAG isel to handle tail calls and long calls. + if (IsTailCall || Subtarget->useLongCalls()) return false; // Let SDISel handle vararg functions. diff --git a/llvm/test/CodeGen/PowerPC/longcall.ll b/llvm/test/CodeGen/PowerPC/longcall.ll --- a/llvm/test/CodeGen/PowerPC/longcall.ll +++ b/llvm/test/CodeGen/PowerPC/longcall.ll @@ -1,14 +1,29 @@ ; RUN: llc < %s | FileCheck %s +; RUN: llc --fast-isel < %s | FileCheck %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" ; Function Attrs: nounwind -define void @bar() local_unnamed_addr #0 { +define void @tail() local_unnamed_addr #0 { entry: tail call void @foo() #1 ret void -; CHECK-LABEL: @bar +; CHECK-LABEL: @tail +; CHECK: ld [[FD:[0-9]+]], .LC0@toc@l({{[0-9]+}}) +; CHECK: ld [[ADDR:[0-9]+]], 0([[FD]]) +; CHECK: mtctr [[ADDR]] +; CHECK: bctrl +; CHECK-NOT: bl foo +; CHECK: blr +} + +define void @notail() local_unnamed_addr #0 { +entry: + call void @foo() #1 + ret void + +; CHECK-LABEL: @notail ; CHECK: ld [[FD:[0-9]+]], .LC0@toc@l({{[0-9]+}}) ; CHECK: ld [[ADDR:[0-9]+]], 0([[FD]]) ; CHECK: mtctr [[ADDR]]