117 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s3 4declare void @callee_stack0()5declare void @callee_stack8([8 x i64], i64)6declare void @callee_stack16([8 x i64], i64, i64)7 8define dso_local void @caller_to0_from0() nounwind {9; CHECK-LABEL: caller_to0_from0:10; CHECK: // %bb.0:11; CHECK-NEXT: b callee_stack012 tail call void @callee_stack0()13 ret void14}15 16define dso_local void @caller_to0_from8([8 x i64], i64) nounwind{17; CHECK-LABEL: caller_to0_from8:18; CHECK: // %bb.0:19; CHECK-NEXT: b callee_stack020 21 tail call void @callee_stack0()22 ret void23}24 25define dso_local void @caller_to8_from0() {26; CHECK-LABEL: caller_to8_from0:27; CHECK: // %bb.0:28; CHECK-NEXT: sub sp, sp, #3229; CHECK-NEXT: str x30, [sp, #16] // 8-byte Spill30; CHECK-NEXT: .cfi_def_cfa_offset 3231; CHECK-NEXT: .cfi_offset w30, -1632; CHECK-NEXT: mov w8, #42 // =0x2a33; CHECK-NEXT: str x8, [sp]34; CHECK-NEXT: bl callee_stack835; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Reload36; CHECK-NEXT: add sp, sp, #3237; CHECK-NEXT: ret38 39; Caller isn't going to clean up any extra stack we allocate, so it40; can't be a tail call.41 tail call void @callee_stack8([8 x i64] undef, i64 42)42 ret void43}44 45define dso_local void @caller_to8_from8([8 x i64], i64 %a) {46; CHECK-LABEL: caller_to8_from8:47; CHECK: // %bb.0:48; CHECK-NEXT: mov w8, #42 // =0x2a49; CHECK-NEXT: str x8, [sp]50; CHECK-NEXT: b callee_stack851 52; This should reuse our stack area for the 4253 tail call void @callee_stack8([8 x i64] undef, i64 42)54 ret void55}56 57define dso_local void @caller_to16_from8([8 x i64], i64 %a) {58; CHECK-LABEL: caller_to16_from8:59; CHECK: // %bb.0:60; CHECK-NEXT: sub sp, sp, #3261; CHECK-NEXT: str x30, [sp, #16] // 8-byte Spill62; CHECK-NEXT: .cfi_def_cfa_offset 3263; CHECK-NEXT: .cfi_offset w30, -1664; CHECK-NEXT: bl callee_stack1665; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Reload66; CHECK-NEXT: add sp, sp, #3267; CHECK-NEXT: ret68 69; Shouldn't be a tail call: we can't use SP+8 because our caller might70; have something there. This may sound obvious but implementation does71; some funky aligning.72 tail call void @callee_stack16([8 x i64] undef, i64 undef, i64 undef)73 ret void74}75 76define dso_local void @caller_to8_from24([8 x i64], i64 %a, i64 %b, i64 %c) {77; CHECK-LABEL: caller_to8_from24:78; CHECK: // %bb.0:79; CHECK-NEXT: mov w8, #42 // =0x2a80; CHECK-NEXT: str x8, [sp]81; CHECK-NEXT: b callee_stack882 83; Reuse our area, putting "42" at incoming sp84 tail call void @callee_stack8([8 x i64] undef, i64 42)85 ret void86}87 88define dso_local void @caller_to16_from16([8 x i64], i64 %a, i64 %b) {89; CHECK-LABEL: caller_to16_from16:90; CHECK: // %bb.0:91; CHECK-NEXT: ldp x8, x9, [sp]92; CHECK-NEXT: stp x9, x8, [sp]93; CHECK-NEXT: b callee_stack1694 95; Here we want to make sure that both loads happen before the stores:96; otherwise either %a or %b will be wrongly clobbered.97 tail call void @callee_stack16([8 x i64] undef, i64 %b, i64 %a)98 ret void99 100 101}102 103@func = dso_local global ptr null104 105define dso_local void @indirect_tail() {106; CHECK-LABEL: indirect_tail:107; CHECK: // %bb.0:108; CHECK-NEXT: adrp x8, func109; CHECK-NEXT: mov w0, #42 // =0x2a110; CHECK-NEXT: ldr x1, [x8, :lo12:func]111; CHECK-NEXT: br x1112 113 %fptr = load ptr, ptr @func114 tail call void %fptr(i32 42)115 ret void116}117