Tail Calls were initially disabled for PC Relative code because it was not safe to make certain assumptions about the tail calls (namely that all compiled functions no longer used the TOC pointer in R2). However, once all of the TOC pointer references have been removed it is safe to tail call everything that was tail called prior to the PC relative additions as well as a number of new cases. For example, it is now possible to tail call indirect functions as there is no need to save and restore the TOC pointer for indirect functions if the caller is marked as may clobber R2 (st_other=1). For the same reason it is now also possible to tail call functions that are external. Differential Revision: https://reviews.llvm.org/D77788
28 lines
838 B
LLVM
28 lines
838 B
LLVM
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
|
|
; RUN: -mcpu=future -ppc-asm-full-reg-names < %s | FileCheck %s
|
|
|
|
; The test checks the behavior of PC Relative indirect calls. When using
|
|
; PC Relative, TOC save and restore are no longer required. Function pointer
|
|
; is passed as a parameter in this test.
|
|
|
|
; Function Attrs: noinline
|
|
define dso_local void @IndirectCallExternFuncPtr(void ()* nocapture %ptrfunc) {
|
|
; CHECK-LABEL: IndirectCallExternFuncPtr:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: mtctr r3
|
|
; CHECK-NEXT: mr r12, r3
|
|
; CHECK-NEXT: bctr
|
|
; CHECK-NEXT: #TC_RETURNr8 ctr
|
|
entry:
|
|
tail call void %ptrfunc()
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @FuncPtrPassAsParam() {
|
|
entry:
|
|
tail call void @IndirectCallExternFuncPtr(void ()* nonnull @Function)
|
|
ret void
|
|
}
|
|
|
|
declare void @Function()
|