1 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s 2 3 declare fastcc void @callee_stack0() 4 declare fastcc void @callee_stack8([8 x i32], i64) 5 declare fastcc void @callee_stack16([8 x i32], i64, i64) 6 7 define fastcc void @caller_to0_from0() nounwind { 8 ; CHECK: caller_to0_from0: 9 ; CHECK-NEXT: // BB 10 tail call fastcc void @callee_stack0() 11 ret void 12 ; CHECK-NEXT: b callee_stack0 13 } 14 15 define fastcc void @caller_to0_from8([8 x i32], i64) { 16 ; CHECK: caller_to0_from8: 17 18 tail call fastcc void @callee_stack0() 19 ret void 20 ; CHECK: add sp, sp, #16 21 ; CHECK-NEXT: b callee_stack0 22 } 23 24 define fastcc void @caller_to8_from0() { 25 ; CHECK: caller_to8_from0: 26 ; CHECK: sub sp, sp, #32 27 28 ; Key point is that the "42" should go #16 below incoming stack 29 ; pointer (we didn't have arg space to reuse). 30 tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) 31 ret void 32 ; CHECK: str {{x[0-9]+}}, [sp, #16] 33 ; CHECK-NEXT: add sp, sp, #16 34 ; CHECK-NEXT: b callee_stack8 35 } 36 37 define fastcc void @caller_to8_from8([8 x i32], i64 %a) { 38 ; CHECK: caller_to8_from8: 39 ; CHECK: sub sp, sp, #16 40 41 ; Key point is that the "%a" should go where at SP on entry. 42 tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) 43 ret void 44 ; CHECK: str {{x[0-9]+}}, [sp, #16] 45 ; CHECK-NEXT: add sp, sp, #16 46 ; CHECK-NEXT: b callee_stack8 47 } 48 49 define fastcc void @caller_to16_from8([8 x i32], i64 %a) { 50 ; CHECK: caller_to16_from8: 51 ; CHECK: sub sp, sp, #16 52 53 ; Important point is that the call reuses the "dead" argument space 54 ; above %a on the stack. If it tries to go below incoming-SP then the 55 ; callee will not deallocate the space, even in fastcc. 56 tail call fastcc void @callee_stack16([8 x i32] undef, i64 42, i64 2) 57 ; CHECK: str {{x[0-9]+}}, [sp, #24] 58 ; CHECK: str {{x[0-9]+}}, [sp, #16] 59 ; CHECK: add sp, sp, #16 60 ; CHECK: b callee_stack16 61 ret void 62 } 63 64 65 define fastcc void @caller_to8_from24([8 x i32], i64 %a, i64 %b, i64 %c) { 66 ; CHECK: caller_to8_from24: 67 ; CHECK: sub sp, sp, #16 68 69 ; Key point is that the "%a" should go where at #16 above SP on entry. 70 tail call fastcc void @callee_stack8([8 x i32] undef, i64 42) 71 ret void 72 ; CHECK: str {{x[0-9]+}}, [sp, #32] 73 ; CHECK-NEXT: add sp, sp, #32 74 ; CHECK-NEXT: b callee_stack8 75 } 76 77 78 define fastcc void @caller_to16_from16([8 x i32], i64 %a, i64 %b) { 79 ; CHECK: caller_to16_from16: 80 ; CHECK: sub sp, sp, #16 81 82 ; Here we want to make sure that both loads happen before the stores: 83 ; otherwise either %a or %b will be wrongly clobbered. 84 tail call fastcc void @callee_stack16([8 x i32] undef, i64 %b, i64 %a) 85 ret void 86 87 ; CHECK: ldr x0, 88 ; CHECK: ldr x1, 89 ; CHECK: str x1, 90 ; CHECK: str x0, 91 92 ; CHECK: add sp, sp, #16 93 ; CHECK: b callee_stack16 94 } 95