; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ ; RUN: -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | FileCheck %s ; The tests check the behavior of the tail call decision when the callee is speculatable. ; Callee should be tail called in this function since it is at a tail call position. define dso_local double @speculatable_callee_return_use_only (double* nocapture %res, double %a) #0 { ; CHECK-LABEL: speculatable_callee_return_use_only: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: b callee entry: %value = tail call double @callee(double %a) #2 ret double %value } ; Callee should not be tail called since it is not at a tail call position. define dso_local void @speculatable_callee_non_return_use_only (double* nocapture %res, double %a) #0 { ; CHECK-LABEL: speculatable_callee_non_return_use_only: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: mflr r0 ; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: std r0, 16(r1) ; CHECK-NEXT: stdu r1, -48(r1) ; CHECK-NEXT: mr r30, r3 ; CHECK-NEXT: bl callee ; CHECK-NEXT: stfd f1, 0(r30) ; CHECK-NEXT: addi r1, r1, 48 ; CHECK-NEXT: ld r0, 16(r1) ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: mtlr r0 ; CHECK-NEXT: blr entry: %call = tail call double @callee(double %a) #2 store double %call, double* %res, align 8 ret void } ; Callee should not be tail called since it is not at a tail call position. define dso_local double @speculatable_callee_multi_use (double* nocapture %res, double %a) #0 { ; CHECK-LABEL: speculatable_callee_multi_use: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: mflr r0 ; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: std r0, 16(r1) ; CHECK-NEXT: stdu r1, -48(r1) ; CHECK-NEXT: mr r30, r3 ; CHECK-NEXT: bl callee ; CHECK-NEXT: stfd f1, 0(r30) ; CHECK-NEXT: addi r1, r1, 48 ; CHECK-NEXT: ld r0, 16(r1) ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: mtlr r0 ; CHECK-NEXT: blr entry: %call = tail call double @callee(double %a) #2 store double %call, double* %res, align 8 ret double %call } ; Callee should not be tail called since it is not at a tail call position. ; FIXME: A speculatable callee can be tail called if it is moved into a valid tail call position. define dso_local double @speculatable_callee_intermediate_instructions (double* nocapture %res, double %a) #0 { ; CHECK-LABEL: speculatable_callee_intermediate_instructions: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: mflr r0 ; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill ; CHECK-NEXT: std r0, 16(r1) ; CHECK-NEXT: stdu r1, -48(r1) ; CHECK-NEXT: mr r30, r3 ; CHECK-NEXT: bl callee ; CHECK-NEXT: lis r3, 4101 ; CHECK-NEXT: ori r3, r3, 13107 ; CHECK-NEXT: rldic r3, r3, 34, 1 ; CHECK-NEXT: oris r3, r3, 52428 ; CHECK-NEXT: ori r3, r3, 52429 ; CHECK-NEXT: std r3, 0(r30) ; CHECK-NEXT: addi r1, r1, 48 ; CHECK-NEXT: ld r0, 16(r1) ; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload ; CHECK-NEXT: mtlr r0 ; CHECK-NEXT: blr entry: %call = tail call double @callee(double %a) #2 store double 5.2, double* %res, align 8 ret double %call } define dso_local double @callee(double) #1 { ret double 4.5 } attributes #0 = { nounwind } attributes #1 = { readnone speculatable } attributes #2 = { nounwind noinline }