1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -frame-pointer=non-leaf -tailcallopt | FileCheck %s -check-prefix CHECK-TAIL 2; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -frame-pointer=non-leaf | FileCheck %s 3; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -frame-pointer=non-leaf -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 8define 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 i64] 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 i64] 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 59define fastcc void @func_stack8([8 x i64], 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 i64] 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 i64] 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 112define fastcc void @func_stack32([8 x i64], 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 i64] 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 i64] 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. 158define fastcc void @func_stack32_leaf([8 x i64], 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. 189define fastcc void @func_stack32_leaf_local([8 x i64], 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. 225define fastcc void @func_stack32_leaf_local_nocs([8 x i64], 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