1 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -disable-fp-elim -tailcallopt | FileCheck %s -check-prefix CHECK-TAIL 2 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -disable-fp-elim | FileCheck %s 3 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -disable-fp-elim -tailcallopt -aarch64-redzone | FileCheck %s -check-prefix CHECK-TAIL-RZ 4 5 ; Without tailcallopt fastcc still means the caller cleans up the 6 ; stack, so try to make sure this is respected. 7 8 define fastcc void @func_stack0() { 9 ; CHECK-LABEL: func_stack0: 10 ; CHECK: sub sp, sp, #48 11 ; CHECK: add x29, sp, #32 12 ; CHECK: str w{{[0-9]+}}, [sp] 13 14 ; CHECK-TAIL-LABEL: func_stack0: 15 ; CHECK-TAIL: sub sp, sp, #48 16 ; CHECK-TAIL-NEXT: stp x29, x30, [sp, #32] 17 ; CHECK-TAIL-NEXT: add x29, sp, #32 18 ; CHECK-TAIL: str w{{[0-9]+}}, [sp] 19 20 21 call fastcc void @func_stack8([8 x i32] undef, i32 42) 22 ; CHECK: bl func_stack8 23 ; CHECK-NOT: sub sp, sp, 24 25 ; CHECK-TAIL: bl func_stack8 26 ; CHECK-TAIL: sub sp, sp, #16 27 28 29 call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) 30 ; CHECK: bl func_stack32 31 ; CHECK-NOT: sub sp, sp, 32 33 34 ; CHECK-TAIL: bl func_stack32 35 ; CHECK-TAIL: sub sp, sp, #32 36 37 38 call fastcc void @func_stack0() 39 ; CHECK: bl func_stack0 40 ; CHECK-NOT: sub sp, sp 41 42 43 ; CHECK-TAIL: bl func_stack0 44 ; CHECK-TAIL-NOT: sub sp, sp 45 46 ret void 47 ; CHECK: ldp x29, x30, [sp, #32] 48 ; CHECK-NEXT: add sp, sp, #48 49 ; CHECK-NEXT: ret 50 51 52 ; CHECK-TAIL: ldp x29, x30, [sp, #32] 53 ; CHECK-TAIL-NEXT: add sp, sp, #48 54 ; CHECK-TAIL-NEXT: ret 55 } 56 57 define fastcc void @func_stack8([8 x i32], i32 %stacked) { 58 ; CHECK-LABEL: func_stack8: 59 ; CHECK: sub sp, sp, #48 60 ; CHECK: stp x29, x30, [sp, #32] 61 ; CHECK: add x29, sp, #32 62 ; CHECK: str w{{[0-9]+}}, [sp] 63 64 65 ; CHECK-TAIL-LABEL: func_stack8: 66 ; CHECK-TAIL: sub sp, sp, #48 67 ; CHECK-TAIL: stp x29, x30, [sp, #32] 68 ; CHECK-TAIL: add x29, sp, #32 69 ; CHECK-TAIL: str w{{[0-9]+}}, [sp] 70 71 72 call fastcc void @func_stack8([8 x i32] undef, i32 42) 73 ; CHECK: bl func_stack8 74 ; CHECK-NOT: sub sp, sp, 75 76 77 ; CHECK-TAIL: bl func_stack8 78 ; CHECK-TAIL: sub sp, sp, #16 79 80 81 call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) 82 ; CHECK: bl func_stack32 83 ; CHECK-NOT: sub sp, sp, 84 85 86 ; CHECK-TAIL: bl func_stack32 87 ; CHECK-TAIL: sub sp, sp, #32 88 89 90 call fastcc void @func_stack0() 91 ; CHECK: bl func_stack0 92 ; CHECK-NOT: sub sp, sp 93 94 ; CHECK-TAIL: bl func_stack0 95 ; CHECK-TAIL-NOT: sub sp, sp 96 97 ret void 98 ; CHECK-NEXT: ldp x29, x30, [sp, #32] 99 ; CHECK: add sp, sp, #48 100 ; CHECK-NEXT: ret 101 102 103 ; CHECK-TAIL: ldp x29, x30, [sp, #32] 104 ; CHECK-TAIL-NEXT: add sp, sp, #64 105 ; CHECK-TAIL-NEXT: ret 106 } 107 108 define fastcc void @func_stack32([8 x i32], i128 %stacked0, i128 %stacked1) { 109 ; CHECK-LABEL: func_stack32: 110 ; CHECK: add x29, sp, #32 111 112 ; CHECK-TAIL-LABEL: func_stack32: 113 ; CHECK-TAIL: add x29, sp, #32 114 115 116 call fastcc void @func_stack8([8 x i32] undef, i32 42) 117 ; CHECK: bl func_stack8 118 ; CHECK-NOT: sub sp, sp, 119 120 ; CHECK-TAIL: bl func_stack8 121 ; CHECK-TAIL: sub sp, sp, #16 122 123 124 call fastcc void @func_stack32([8 x i32] undef, i128 0, i128 9) 125 ; CHECK: bl func_stack32 126 ; CHECK-NOT: sub sp, sp, 127 128 129 ; CHECK-TAIL: bl func_stack32 130 ; CHECK-TAIL: sub sp, sp, #32 131 132 133 call fastcc void @func_stack0() 134 ; CHECK: bl func_stack0 135 ; CHECK-NOT: sub sp, sp 136 137 138 ; CHECK-TAIL: bl func_stack0 139 ; CHECK-TAIL-NOT: sub sp, sp 140 141 ret void 142 ; CHECK: ldp x29, x30, [sp, #32] 143 ; CHECK-NEXT: add sp, sp, #48 144 ; CHECK-NEXT: ret 145 146 ; CHECK-TAIL: ldp x29, x30, [sp, #32] 147 ; CHECK-TAIL-NEXT: add sp, sp, #80 148 ; CHECK-TAIL-NEXT: ret 149 } 150 151 ; Check that arg stack pop is done after callee-save restore when no frame pointer is used. 152 define fastcc void @func_stack32_leaf([8 x i32], i128 %stacked0, i128 %stacked1) { 153 ; CHECK-LABEL: func_stack32_leaf: 154 ; CHECK: str x20, [sp, #-16]! 155 ; CHECK: nop 156 ; CHECK-NEXT: //NO_APP 157 ; CHECK-NEXT: ldr x20, [sp], #16 158 ; CHECK-NEXT: ret 159 160 ; CHECK-TAIL-LABEL: func_stack32_leaf: 161 ; CHECK-TAIL: str x20, [sp, #-16]! 162 ; CHECK-TAIL: nop 163 ; CHECK-TAIL-NEXT: //NO_APP 164 ; CHECK-TAIL-NEXT: ldr x20, [sp], #16 165 ; CHECK-TAIL-NEXT: add sp, sp, #32 166 ; CHECK-TAIL-NEXT: ret 167 168 ; CHECK-TAIL-RZ-LABEL: func_stack32_leaf: 169 ; CHECK-TAIL-RZ: str x20, [sp, #-16]! 170 ; CHECK-TAIL-RZ-NOT: sub sp, sp 171 ; CHECK-TAIL-RZ: nop 172 ; CHECK-TAIL-RZ-NEXT: //NO_APP 173 ; CHECK-TAIL-RZ-NEXT: ldr x20, [sp], #16 174 ; CHECK-TAIL-RZ-NEXT: add sp, sp, #32 175 ; CHECK-TAIL-RZ-NEXT: ret 176 177 ; Make sure there is a callee-save register to save/restore. 178 call void asm sideeffect "nop", "~{x20}"() nounwind 179 ret void 180 } 181 182 ; Check that arg stack pop is done after callee-save restore when no frame pointer is used. 183 define fastcc void @func_stack32_leaf_local([8 x i32], i128 %stacked0, i128 %stacked1) { 184 ; CHECK-LABEL: func_stack32_leaf_local: 185 ; CHECK: sub sp, sp, #32 186 ; CHECK-NEXT: str x20, [sp, #16] 187 ; CHECK: nop 188 ; CHECK-NEXT: //NO_APP 189 ; CHECK-NEXT: ldr x20, [sp, #16] 190 ; CHECK-NEXT: add sp, sp, #32 191 ; CHECK-NEXT: ret 192 193 ; CHECK-TAIL-LABEL: func_stack32_leaf_local: 194 ; CHECK-TAIL: sub sp, sp, #32 195 ; CHECK-TAIL-NEXT: str x20, [sp, #16] 196 ; CHECK-TAIL: nop 197 ; CHECK-TAIL-NEXT: //NO_APP 198 ; CHECK-TAIL-NEXT: ldr x20, [sp, #16] 199 ; CHECK-TAIL-NEXT: add sp, sp, #64 200 ; CHECK-TAIL-NEXT: ret 201 202 ; CHECK-TAIL-RZ-LABEL: func_stack32_leaf_local: 203 ; CHECK-TAIL-RZ: str x20, [sp, #-16]! 204 ; CHECK-TAIL-RZ-NOT: sub sp, sp 205 ; CHECK-TAIL-RZ: nop 206 ; CHECK-TAIL-RZ-NEXT: //NO_APP 207 ; CHECK-TAIL-RZ-NEXT: ldr x20, [sp], #16 208 ; CHECK-TAIL-RZ-NEXT: add sp, sp, #32 209 ; CHECK-TAIL-RZ-NEXT: ret 210 211 %val0 = alloca [2 x i64], align 8 212 213 ; Make sure there is a callee-save register to save/restore. 214 call void asm sideeffect "nop", "~{x20}"() nounwind 215 ret void 216 } 217 218 ; Check that arg stack pop is done after callee-save restore when no frame pointer is used. 219 define fastcc void @func_stack32_leaf_local_nocs([8 x i32], i128 %stacked0, i128 %stacked1) { 220 ; CHECK-LABEL: func_stack32_leaf_local_nocs: 221 ; CHECK: sub sp, sp, #16 222 ; CHECK: add sp, sp, #16 223 ; CHECK-NEXT: ret 224 225 ; CHECK-TAIL-LABEL: func_stack32_leaf_local_nocs: 226 ; CHECK-TAIL: sub sp, sp, #16 227 ; CHECK-TAIL: add sp, sp, #48 228 ; CHECK-TAIL-NEXT: ret 229 230 ; CHECK-TAIL-RZ-LABEL: func_stack32_leaf_local_nocs: 231 ; CHECK-TAIL-RZ: add sp, sp, #32 232 ; CHECK-TAIL-RZ-NEXT: ret 233 234 %val0 = alloca [2 x i64], align 8 235 236 ret void 237 } 238