1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -tailcallopt | FileCheck %s 2 3declare fastcc void @callee_stack0() 4declare fastcc void @callee_stack8([8 x i32], i64) 5declare fastcc void @callee_stack16([8 x i32], i64, i64) 6 7define 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 15define 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 24define 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 37define 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 49define 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 65define 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 78define 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