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