1 ; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -disable-post-ra < %s | FileCheck %s 2 ; RUN: llc -verify-machineinstrs -mtriple=arm64-apple-ios -disable-fp-elim -disable-post-ra < %s | FileCheck %s --check-prefix=CHECK-MACHO 3 4 ; This test aims to check basic correctness of frame layout & 5 ; frame access code. There are 8 functions in this test file, 6 ; each function implements one element in the cartesian product 7 ; of: 8 ; . a function having a VLA/noVLA 9 ; . a function with dynamic stack realignment/no dynamic stack realignment. 10 ; . a function needing a frame pionter/no frame pointer, 11 ; since the presence/absence of these has influence on the frame 12 ; layout and which pointer to use to access various part of the 13 ; frame (bp,sp,fp). 14 ; 15 ; Furthermore: in every test function: 16 ; . there is always one integer and 1 floating point argument to be able 17 ; to check those are accessed correctly. 18 ; . there is always one local variable to check that is accessed 19 ; correctly 20 ; 21 ; The LLVM-IR below was produced by clang on the following C++ code: 22 ;extern "C" int g(); 23 ;extern "C" int novla_nodynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 24 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 25 ;{ 26 ; // use an argument passed on the stack. 27 ; volatile int l1; 28 ; return i10 + (int)d10 + l1 + g(); 29 ;} 30 ;extern "C" int novla_nodynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 31 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 32 ;{ 33 ; // use an argument passed on the stack. 34 ; volatile int l1; 35 ; return i10 + (int)d10 + l1; 36 ;} 37 ;extern "C" int novla_dynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 38 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 39 ;{ 40 ; // use an argument passed on the stack. 41 ; alignas(128) volatile int l1; 42 ; return i10 + (int)d10 + l1 + g(); 43 ;} 44 ;extern "C" int novla_dynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 45 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 46 ;{ 47 ; // use an argument passed on the stack. 48 ; alignas(128) volatile int l1; 49 ; return i10 + (int)d10 + l1; 50 ;} 51 ; 52 ;extern "C" int vla_nodynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 53 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 54 ;{ 55 ; // use an argument passed on the stack. 56 ; volatile int l1; 57 ; volatile int vla[i1]; 58 ; return i10 + (int)d10 + l1 + g() + vla[0]; 59 ;} 60 ;extern "C" int vla_nodynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 61 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 62 ;{ 63 ; // use an argument passed on the stack. 64 ; volatile int l1; 65 ; volatile int vla[i1]; 66 ; return i10 + (int)d10 + l1 + vla[0]; 67 ;} 68 ;extern "C" int vla_dynamicrealign_call(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 69 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 70 ;{ 71 ; // use an argument passed on the stack. 72 ; alignas(128) volatile int l1; 73 ; volatile int vla[i1]; 74 ; return i10 + (int)d10 + l1 + g() + vla[0]; 75 ;} 76 ;extern "C" int vla_dynamicrealign_nocall(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, 77 ; double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8, double d9, double d10) 78 ;{ 79 ; // use an argument passed on the stack. 80 ; alignas(128) volatile int l1; 81 ; volatile int vla[i1]; 82 ; return i10 + (int)d10 + l1 + vla[0]; 83 ;} 84 85 86 87 define i32 @novla_nodynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 { 88 entry: 89 %l1 = alloca i32, align 4 90 %conv = fptosi double %d10 to i32 91 %add = add nsw i32 %conv, %i10 92 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4 93 %add1 = add nsw i32 %add, %l1.0.l1.0. 94 %call = tail call i32 @g() 95 %add2 = add nsw i32 %add1, %call 96 ret i32 %add2 97 } 98 ; CHECK-LABEL: novla_nodynamicrealign_call 99 ; CHECK: .cfi_startproc 100 ; Check that used callee-saved registers are saved 101 ; CHECK: sub sp, sp, #32 102 ; CHECK: stp x19, x30, [sp, #16] 103 ; Check correctness of cfi pseudo-instructions 104 ; CHECK: .cfi_def_cfa_offset 32 105 ; CHECK: .cfi_offset w30, -8 106 ; CHECK: .cfi_offset w19, -16 107 ; Check correct access to arguments passed on the stack, through stack pointer 108 ; CHECK: ldr d[[DARG:[0-9]+]], [sp, #56] 109 ; CHECK: ldr w[[IARG:[0-9]+]], [sp, #40] 110 ; Check correct access to local variable on the stack, through stack pointer 111 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12] 112 ; Check epilogue: 113 ; CHECK: ldp x19, x30, [sp, #16] 114 ; CHECK: ret 115 ; CHECK: .cfi_endproc 116 117 ; CHECK-MACHO-LABEL: _novla_nodynamicrealign_call: 118 ; CHECK-MACHO: .cfi_startproc 119 ; Check that used callee-saved registers are saved 120 ; CHECK-MACHO: sub sp, sp, #48 121 ; CHECK-MACHO: stp x20, x19, [sp, #16] 122 ; Check that the frame pointer is created: 123 ; CHECK-MACHO: stp x29, x30, [sp, #32] 124 ; CHECK-MACHO: add x29, sp, #32 125 ; Check correctness of cfi pseudo-instructions 126 ; CHECK-MACHO: .cfi_def_cfa w29, 16 127 ; CHECK-MACHO: .cfi_offset w30, -8 128 ; CHECK-MACHO: .cfi_offset w29, -16 129 ; CHECK-MACHO: .cfi_offset w19, -24 130 ; CHECK-MACHO: .cfi_offset w20, -32 131 ; Check correct access to arguments passed on the stack, through frame pointer 132 ; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 133 ; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 134 ; Check correct access to local variable on the stack, through stack pointer 135 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [sp, #12] 136 ; Check epilogue: 137 ; CHECK-MACHO: ldp x29, x30, [sp, #32] 138 ; CHECK-MACHO: ldp x20, x19, [sp, #16] 139 ; CHECK-MACHO: ret 140 ; CHECK-MACHO: .cfi_endproc 141 142 143 declare i32 @g() #0 144 145 ; Function Attrs: nounwind 146 define i32 @novla_nodynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 { 147 entry: 148 %l1 = alloca i32, align 4 149 %conv = fptosi double %d10 to i32 150 %add = add nsw i32 %conv, %i10 151 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4 152 %add1 = add nsw i32 %add, %l1.0.l1.0. 153 ret i32 %add1 154 } 155 ; CHECK-LABEL: novla_nodynamicrealign_nocall 156 ; Check that space is reserved for one local variable on the stack. 157 ; CHECK: sub sp, sp, #16 // =16 158 ; Check correct access to arguments passed on the stack, through stack pointer 159 ; CHECK: ldr d[[DARG:[0-9]+]], [sp, #40] 160 ; CHECK: ldr w[[IARG:[0-9]+]], [sp, #24] 161 ; Check correct access to local variable on the stack, through stack pointer 162 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12] 163 ; Check epilogue: 164 ; CHECK: add sp, sp, #16 // =16 165 ; CHECK: ret 166 167 168 define i32 @novla_dynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 { 169 entry: 170 %l1 = alloca i32, align 128 171 %conv = fptosi double %d10 to i32 172 %add = add nsw i32 %conv, %i10 173 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 174 %add1 = add nsw i32 %add, %l1.0.l1.0. 175 %call = tail call i32 @g() 176 %add2 = add nsw i32 %add1, %call 177 ret i32 %add2 178 } 179 180 ; CHECK-LABEL: novla_dynamicrealign_call 181 ; CHECK: .cfi_startproc 182 ; Check that used callee-saved registers are saved 183 ; CHECK: str x19, [sp, #-32]! 184 ; Check that the frame pointer is created: 185 ; CHECK: stp x29, x30, [sp, #16] 186 ; CHECK: add x29, sp, #16 187 ; Check the dynamic realignment of the stack pointer to a 128-byte boundary 188 ; CHECK: sub x9, sp, #96 189 ; CHECK: and sp, x9, #0xffffffffffffff80 190 ; Check correctness of cfi pseudo-instructions 191 ; CHECK: .cfi_def_cfa w29, 16 192 ; CHECK: .cfi_offset w30, -8 193 ; CHECK: .cfi_offset w29, -16 194 ; CHECK: .cfi_offset w19, -32 195 ; Check correct access to arguments passed on the stack, through frame pointer 196 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 197 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 198 ; Check correct access to local variable on the stack, through re-aligned stack pointer 199 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp] 200 ; Check epilogue: 201 ; Check that stack pointer get restored from frame pointer. 202 ; CHECK: sub sp, x29, #16 // =16 203 ; CHECK: ldp x29, x30, [sp, #16] 204 ; CHECK: ldr x19, [sp], #32 205 ; CHECK: ret 206 ; CHECK: .cfi_endproc 207 208 ; CHECK-MACHO-LABEL: _novla_dynamicrealign_call: 209 ; CHECK-MACHO: .cfi_startproc 210 ; Check that used callee-saved registers are saved 211 ; CHECK-MACHO: stp x20, x19, [sp, #-32]! 212 ; Check that the frame pointer is created: 213 ; CHECK-MACHO: stp x29, x30, [sp, #16] 214 ; CHECK-MACHO: add x29, sp, #16 215 ; Check the dynamic realignment of the stack pointer to a 128-byte boundary 216 ; CHECK-MACHO: sub x9, sp, #96 217 ; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 218 ; Check correctness of cfi pseudo-instructions 219 ; CHECK-MACHO: .cfi_def_cfa w29, 16 220 ; CHECK-MACHO: .cfi_offset w30, -8 221 ; CHECK-MACHO: .cfi_offset w29, -16 222 ; CHECK-MACHO: .cfi_offset w19, -24 223 ; CHECK-MACHO: .cfi_offset w20, -32 224 ; Check correct access to arguments passed on the stack, through frame pointer 225 ; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 226 ; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 227 ; Check correct access to local variable on the stack, through re-aligned stack pointer 228 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [sp] 229 ; Check epilogue: 230 ; Check that stack pointer get restored from frame pointer. 231 ; CHECK-MACHO: sub sp, x29, #16 232 ; CHECK-MACHO: ldp x29, x30, [sp, #16] 233 ; CHECK-MACHO: ldp x20, x19, [sp], #32 234 ; CHECK-MACHO: ret 235 ; CHECK-MACHO: .cfi_endproc 236 237 238 ; Function Attrs: nounwind 239 define i32 @novla_dynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 { 240 entry: 241 %l1 = alloca i32, align 128 242 %conv = fptosi double %d10 to i32 243 %add = add nsw i32 %conv, %i10 244 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 245 %add1 = add nsw i32 %add, %l1.0.l1.0. 246 ret i32 %add1 247 } 248 249 ; CHECK-LABEL: novla_dynamicrealign_nocall 250 ; Check that the frame pointer is created: 251 ; CHECK: stp x29, x30, [sp, #-16]! 252 ; CHECK: mov x29, sp 253 ; Check the dynamic realignment of the stack pointer to a 128-byte boundary 254 ; CHECK: sub x9, sp, #112 255 ; CHECK: and sp, x9, #0xffffffffffffff80 256 ; Check correct access to arguments passed on the stack, through frame pointer 257 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 258 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 259 ; Check correct access to local variable on the stack, through re-aligned stack pointer 260 ; CHECK: ldr w[[ILOC:[0-9]+]], [sp] 261 ; Check epilogue: 262 ; Check that stack pointer get restored from frame pointer. 263 ; CHECK: mov sp, x29 264 ; CHECK: ldp x29, x30, [sp], #16 265 ; CHECK: ret 266 267 268 define i32 @vla_nodynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 { 269 entry: 270 %l1 = alloca i32, align 4 271 %0 = zext i32 %i1 to i64 272 %vla = alloca i32, i64 %0, align 4 273 %conv = fptosi double %d10 to i32 274 %add = add nsw i32 %conv, %i10 275 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4 276 %add1 = add nsw i32 %add, %l1.0.l1.0. 277 %call = tail call i32 @g() 278 %add2 = add nsw i32 %add1, %call 279 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 280 %add3 = add nsw i32 %add2, %1 281 ret i32 %add3 282 } 283 284 ; CHECK-LABEL: vla_nodynamicrealign_call 285 ; CHECK: .cfi_startproc 286 ; Check that used callee-saved registers are saved 287 ; CHECK: stp x20, x19, [sp, #-32]! 288 ; Check that the frame pointer is created: 289 ; CHECK: stp x29, x30, [sp, #16] 290 ; CHECK: add x29, sp, #16 291 ; Check that space is reserved on the stack for the local variable, 292 ; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned. 293 ; CHECK: sub sp, sp, #16 294 ; Check correctness of cfi pseudo-instructions 295 ; CHECK: .cfi_def_cfa w29, 16 296 ; CHECK: .cfi_offset w30, -8 297 ; CHECK: .cfi_offset w29, -16 298 ; CHECK: .cfi_offset w19, -24 299 ; CHECK: .cfi_offset w20, -32 300 ; Check correct access to arguments passed on the stack, through frame pointer 301 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 302 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 303 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 304 ; CHECK: mov w9, w0 305 ; CHECK: mov x10, sp 306 ; CHECK: lsl x9, x9, #2 307 ; CHECK: add x9, x9, #15 308 ; CHECK: and x9, x9, #0x7fffffff0 309 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 310 ; CHECK: mov sp, x[[VLASPTMP]] 311 ; Check correct access to local variable, through frame pointer 312 ; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-20] 313 ; Check correct accessing of the VLA variable through the base pointer 314 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 315 ; Check epilogue: 316 ; Check that stack pointer get restored from frame pointer. 317 ; CHECK: sub sp, x29, #16 // =16 318 ; CHECK: ldp x29, x30, [sp, #16] 319 ; CHECK: ldp x20, x19, [sp], #32 320 ; CHECK: ret 321 ; CHECK: .cfi_endproc 322 323 324 ; Function Attrs: nounwind 325 define i32 @vla_nodynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 { 326 entry: 327 %l1 = alloca i32, align 4 328 %0 = zext i32 %i1 to i64 329 %vla = alloca i32, i64 %0, align 4 330 %conv = fptosi double %d10 to i32 331 %add = add nsw i32 %conv, %i10 332 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4 333 %add1 = add nsw i32 %add, %l1.0.l1.0. 334 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 335 %add2 = add nsw i32 %add1, %1 336 ret i32 %add2 337 } 338 339 ; CHECK-LABEL: vla_nodynamicrealign_nocall 340 ; Check that the frame pointer is created: 341 ; CHECK: stp x29, x30, [sp, #-16]! 342 ; CHECK: mov x29, sp 343 ; Check that space is reserved on the stack for the local variable, 344 ; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned. 345 ; CHECK: sub sp, sp, #16 346 ; Check correctness of cfi pseudo-instructions 347 ; Check correct access to arguments passed on the stack, through frame pointer 348 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 349 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 350 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 351 ; CHECK: mov w9, w0 352 ; CHECK: mov x10, sp 353 ; CHECK: lsl x9, x9, #2 354 ; CHECK: add x9, x9, #15 355 ; CHECK: and x9, x9, #0x7fffffff0 356 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 357 ; CHECK: mov sp, x[[VLASPTMP]] 358 ; Check correct access to local variable, through frame pointer 359 ; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4] 360 ; Check correct accessing of the VLA variable through the base pointer 361 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 362 ; Check epilogue: 363 ; Check that stack pointer get restored from frame pointer. 364 ; CHECK: mov sp, x29 365 ; CHECK: ldp x29, x30, [sp], #16 366 ; CHECK: ret 367 368 369 define i32 @vla_dynamicrealign_call(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #0 { 370 entry: 371 %l1 = alloca i32, align 128 372 %0 = zext i32 %i1 to i64 373 %vla = alloca i32, i64 %0, align 4 374 %conv = fptosi double %d10 to i32 375 %add = add nsw i32 %conv, %i10 376 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 377 %add1 = add nsw i32 %add, %l1.0.l1.0. 378 %call = tail call i32 @g() 379 %add2 = add nsw i32 %add1, %call 380 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 381 %add3 = add nsw i32 %add2, %1 382 ret i32 %add3 383 } 384 385 ; CHECK-LABEL: vla_dynamicrealign_call 386 ; CHECK: .cfi_startproc 387 ; Check that used callee-saved registers are saved 388 ; CHECK: str x21, [sp, #-48]! 389 ; CHECK: stp x20, x19, [sp, #16] 390 ; Check that the frame pointer is created: 391 ; CHECK: stp x29, x30, [sp, #32] 392 ; CHECK: add x29, sp, #32 393 ; Check that the stack pointer gets re-aligned to 128 394 ; bytes & the base pointer (x19) gets initialized to 395 ; this 128-byte aligned area for local variables & 396 ; spill slots 397 ; CHECK: sub x9, sp, #80 // =80 398 ; CHECK: and sp, x9, #0xffffffffffffff80 399 ; CHECK: mov x19, sp 400 ; Check correctness of cfi pseudo-instructions 401 ; CHECK: .cfi_def_cfa w29, 16 402 ; CHECK: .cfi_offset w30, -8 403 ; CHECK: .cfi_offset w29, -16 404 ; CHECK: .cfi_offset w19, -24 405 ; CHECK: .cfi_offset w20, -32 406 ; CHECK: .cfi_offset w21, -48 407 ; Check correct access to arguments passed on the stack, through frame pointer 408 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 409 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 410 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 411 ; and set-up of base pointer (x19). 412 ; CHECK: mov w9, w0 413 ; CHECK: mov x10, sp 414 ; CHECK: lsl x9, x9, #2 415 ; CHECK: add x9, x9, #15 416 ; CHECK: and x9, x9, #0x7fffffff0 417 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 418 ; CHECK: mov sp, x[[VLASPTMP]] 419 ; Check correct access to local variable, through base pointer 420 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 421 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 422 ; Check epilogue: 423 ; Check that stack pointer get restored from frame pointer. 424 ; CHECK: sub sp, x29, #32 425 ; CHECK: ldp x29, x30, [sp, #32] 426 ; CHECK: ldp x20, x19, [sp, #16] 427 ; CHECK: ldr x21, [sp], #48 428 ; CHECK: ret 429 ; CHECK: .cfi_endproc 430 431 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_call: 432 ; CHECK-MACHO: .cfi_startproc 433 ; Check that used callee-saved registers are saved 434 ; CHECK-MACHO: stp x22, x21, [sp, #-48]! 435 ; CHECK-MACHO: stp x20, x19, [sp, #16] 436 ; Check that the frame pointer is created: 437 ; CHECK-MACHO: stp x29, x30, [sp, #32] 438 ; CHECK-MACHO: add x29, sp, #32 439 ; Check that the stack pointer gets re-aligned to 128 440 ; bytes & the base pointer (x19) gets initialized to 441 ; this 128-byte aligned area for local variables & 442 ; spill slots 443 ; CHECK-MACHO: sub x9, sp, #80 444 ; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 445 ; CHECK-MACHO: mov x19, sp 446 ; Check correctness of cfi pseudo-instructions 447 ; CHECK-MACHO: .cfi_def_cfa w29, 16 448 ; CHECK-MACHO: .cfi_offset w30, -8 449 ; CHECK-MACHO: .cfi_offset w29, -16 450 ; CHECK-MACHO: .cfi_offset w19, -24 451 ; CHECK-MACHO: .cfi_offset w20, -32 452 ; CHECK-MACHO: .cfi_offset w21, -40 453 ; CHECK-MACHO: .cfi_offset w22, -48 454 ; Check correct access to arguments passed on the stack, through frame pointer 455 ; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 456 ; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 457 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 458 ; and set-up of base pointer (x19). 459 ; CHECK-MACHO: mov w9, w0 460 ; CHECK-MACHO: mov x10, sp 461 ; CHECK-MACHO: lsl x9, x9, #2 462 ; CHECK-MACHO: add x9, x9, #15 463 ; CHECK-MACHO: and x9, x9, #0x7fffffff0 464 ; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9 465 ; CHECK-MACHO: mov sp, x[[VLASPTMP]] 466 ; Check correct access to local variable, through base pointer 467 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 468 ; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 469 ; Check epilogue: 470 ; Check that stack pointer get restored from frame pointer. 471 ; CHECK-MACHO: sub sp, x29, #32 472 ; CHECK-MACHO: ldp x29, x30, [sp, #32] 473 ; CHECK-MACHO: ldp x20, x19, [sp, #16] 474 ; CHECK-MACHO: ldp x22, x21, [sp], #48 475 ; CHECK-MACHO: ret 476 ; CHECK-MACHO: .cfi_endproc 477 478 479 ; Function Attrs: nounwind 480 define i32 @vla_dynamicrealign_nocall(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 { 481 entry: 482 %l1 = alloca i32, align 128 483 %0 = zext i32 %i1 to i64 484 %vla = alloca i32, i64 %0, align 4 485 %conv = fptosi double %d10 to i32 486 %add = add nsw i32 %conv, %i10 487 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 488 %add1 = add nsw i32 %add, %l1.0.l1.0. 489 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 490 %add2 = add nsw i32 %add1, %1 491 ret i32 %add2 492 } 493 494 ; CHECK-LABEL: vla_dynamicrealign_nocall 495 ; Check that used callee-saved registers are saved 496 ; CHECK: str x19, [sp, #-32]! 497 ; Check that the frame pointer is created: 498 ; CHECK: stp x29, x30, [sp, #16] 499 ; CHECK: add x29, sp, #16 500 ; Check that the stack pointer gets re-aligned to 128 501 ; bytes & the base pointer (x19) gets initialized to 502 ; this 128-byte aligned area for local variables & 503 ; spill slots 504 ; CHECK: sub x9, sp, #96 505 ; CHECK: and sp, x9, #0xffffffffffffff80 506 ; CHECK: mov x19, sp 507 ; Check correct access to arguments passed on the stack, through frame pointer 508 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 509 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 510 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 511 ; and set-up of base pointer (x19). 512 ; CHECK: mov w9, w0 513 ; CHECK: mov x10, sp 514 ; CHECK: lsl x9, x9, #2 515 ; CHECK: add x9, x9, #15 516 ; CHECK: and x9, x9, #0x7fffffff0 517 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 518 ; CHECK: mov sp, x[[VLASPTMP]] 519 ; Check correct access to local variable, through base pointer 520 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 521 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 522 ; Check epilogue: 523 ; Check that stack pointer get restored from frame pointer. 524 ; CHECK: sub sp, x29, #16 525 ; CHECK: ldp x29, x30, [sp, #16] 526 ; CHECK: ldr x19, [sp], #32 527 ; CHECK: ret 528 529 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall: 530 ; Check that used callee-saved registers are saved 531 ; CHECK-MACHO: stp x20, x19, [sp, #-32]! 532 ; Check that the frame pointer is created: 533 ; CHECK-MACHO: stp x29, x30, [sp, #16] 534 ; CHECK-MACHO: add x29, sp, #16 535 ; Check that the stack pointer gets re-aligned to 128 536 ; bytes & the base pointer (x19) gets initialized to 537 ; this 128-byte aligned area for local variables & 538 ; spill slots 539 ; CHECK-MACHO: sub x9, sp, #96 540 ; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 541 ; CHECK-MACHO: mov x19, sp 542 ; Check correct access to arguments passed on the stack, through frame pointer 543 ; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 544 ; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 545 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 546 ; and set-up of base pointer (x19). 547 ; CHECK-MACHO: mov w9, w0 548 ; CHECK-MACHO: mov x10, sp 549 ; CHECK-MACHO: lsl x9, x9, #2 550 ; CHECK-MACHO: add x9, x9, #15 551 ; CHECK-MACHO: and x9, x9, #0x7fffffff0 552 ; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9 553 ; CHECK-MACHO: mov sp, x[[VLASPTMP]] 554 ; Check correct access to local variable, through base pointer 555 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 556 ; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 557 ; Check epilogue: 558 ; Check that stack pointer get restored from frame pointer. 559 ; CHECK-MACHO: sub sp, x29, #16 560 ; CHECK-MACHO: ldp x29, x30, [sp, #16] 561 ; CHECK-MACHO: ldp x20, x19, [sp], #32 562 ; CHECK-MACHO: ret 563 564 565 ; Function Attrs: nounwind 566 define i32 @vla_dynamicrealign_nocall_large_align(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, double %d1, double %d2, double %d3, double %d4, double %d5, double %d6, double %d7, double %d8, double %d9, double %d10) #1 { 567 entry: 568 %l1 = alloca i32, align 32768 569 %0 = zext i32 %i1 to i64 570 %vla = alloca i32, i64 %0, align 4 571 %conv = fptosi double %d10 to i32 572 %add = add nsw i32 %conv, %i10 573 %l1.0.l1.0. = load volatile i32, i32* %l1, align 32768 574 %add1 = add nsw i32 %add, %l1.0.l1.0. 575 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 576 %add2 = add nsw i32 %add1, %1 577 ret i32 %add2 578 } 579 580 ; CHECK-LABEL: vla_dynamicrealign_nocall_large_align 581 ; Check that used callee-saved registers are saved 582 ; CHECK: stp x28, x19, [sp, #-32]! 583 ; Check that the frame pointer is created: 584 ; CHECK: stp x29, x30, [sp, #16] 585 ; CHECK: add x29, sp, #16 586 ; Check that the stack pointer gets re-aligned to 128 587 ; bytes & the base pointer (x19) gets initialized to 588 ; this 128-byte aligned area for local variables & 589 ; spill slots 590 ; CHECK: sub x9, sp, #7, lsl #12 591 ; CHECK: and sp, x9, #0xffffffffffff8000 592 ; CHECK: mov x19, sp 593 ; Check correct access to arguments passed on the stack, through frame pointer 594 ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 595 ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 596 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 597 ; and set-up of base pointer (x19). 598 ; CHECK: mov w9, w0 599 ; CHECK: mov x10, sp 600 ; CHECK: lsl x9, x9, #2 601 ; CHECK: add x9, x9, #15 602 ; CHECK: and x9, x9, #0x7fffffff0 603 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 604 ; CHECK: mov sp, x[[VLASPTMP]] 605 ; Check correct access to local variable, through base pointer 606 ; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 607 ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 608 ; Check epilogue: 609 ; Check that stack pointer get restored from frame pointer. 610 ; CHECK: sub sp, x29, #16 611 ; CHECK: ldp x29, x30, [sp, #16] 612 ; CHECK: ldp x28, x19, [sp], #32 613 ; CHECK: ret 614 615 ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align: 616 ; Check that used callee-saved registers are saved 617 ; CHECK-MACHO: stp x20, x19, [sp, #-32]! 618 ; Check that the frame pointer is created: 619 ; CHECK-MACHO: stp x29, x30, [sp, #16] 620 ; CHECK-MACHO: add x29, sp, #16 621 ; Check that the stack pointer gets re-aligned to 128 622 ; bytes & the base pointer (x19) gets initialized to 623 ; this 128-byte aligned area for local variables & 624 ; spill slots 625 ; CHECK-MACHO: sub x9, sp, #7, lsl #12 626 ; CHECK-MACHO: and sp, x9, #0xffffffffffff8000 627 ; CHECK-MACHO: mov x19, sp 628 ; Check correct access to arguments passed on the stack, through frame pointer 629 ; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 630 ; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 631 ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 632 ; and set-up of base pointer (x19). 633 ; CHECK-MACHO: mov w9, w0 634 ; CHECK-MACHO: mov x10, sp 635 ; CHECK-MACHO: lsl x9, x9, #2 636 ; CHECK-MACHO: add x9, x9, #15 637 ; CHECK-MACHO: and x9, x9, #0x7fffffff0 638 ; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9 639 ; CHECK-MACHO: mov sp, x[[VLASPTMP]] 640 ; Check correct access to local variable, through base pointer 641 ; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 642 ; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 643 ; Check epilogue: 644 ; Check that stack pointer get restored from frame pointer. 645 ; CHECK-MACHO: sub sp, x29, #16 646 ; CHECK-MACHO: ldp x29, x30, [sp, #16] 647 ; CHECK-MACHO: ldp x20, x19, [sp], #32 648 ; CHECK-MACHO: ret 649 650 651 define void @realign_conditional(i1 %b) { 652 entry: 653 br i1 %b, label %bb0, label %bb1 654 655 bb0: 656 %MyAlloca = alloca i8, i64 64, align 32 657 br label %bb1 658 659 bb1: 660 ret void 661 } 662 663 ; CHECK-LABEL: realign_conditional 664 ; No realignment in the prologue. 665 ; CHECK-NOT: and 666 ; CHECK-NOT: 0xffffffffffffffe0 667 ; CHECK: tbz {{.*}} .[[LABEL:.*]] 668 ; Stack is realigned in a non-entry BB. 669 ; CHECK: sub [[REG:x[01-9]+]], sp, #64 670 ; CHECK: and sp, [[REG]], #0xffffffffffffffe0 671 ; CHECK: .[[LABEL]]: 672 ; CHECK: ret 673 674 675 define void @realign_conditional2(i1 %b) { 676 entry: 677 %tmp = alloca i8, i32 16 678 br i1 %b, label %bb0, label %bb1 679 680 bb0: 681 %MyAlloca = alloca i8, i64 64, align 32 682 br label %bb1 683 684 bb1: 685 ret void 686 } 687 688 ; CHECK-LABEL: realign_conditional2 689 ; Extra realignment in the prologue (performance issue). 690 ; CHECK: tbz {{.*}} .[[LABEL:.*]] 691 ; CHECK: sub x9, sp, #32 // =32 692 ; CHECK: and sp, x9, #0xffffffffffffffe0 693 ; CHECK: mov x19, sp 694 ; Stack is realigned in a non-entry BB. 695 ; CHECK: sub [[REG:x[01-9]+]], sp, #64 696 ; CHECK: and sp, [[REG]], #0xffffffffffffffe0 697 ; CHECK: .[[LABEL]]: 698 ; CHECK: ret 699 700 attributes #0 = { "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 701 attributes #1 = { nounwind "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 702 703 !1 = !{!2, !2, i64 0} 704 !2 = !{!"int", !3, i64 0} 705 !3 = !{!"omnipotent char", !4, i64 0} 706 !4 = !{!"Simple C/C++ TBAA"} 707