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 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 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 57define 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 108define 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. 152define 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. 183define 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. 219define 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