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 87define 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 { 88entry: 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: stp x19, x30, [sp, #-16]! 102; CHECK: sub sp, 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: stp x20, x19, [sp, #-32]! 121; Check that the frame pointer is created: 122; CHECK-MACHO: stp x29, x30, [sp, #16] 123; CHECK-MACHO: add x29, sp, #16 124; Check correctness of cfi pseudo-instructions 125; CHECK-MACHO: .cfi_def_cfa w29, 16 126; CHECK-MACHO: .cfi_offset w30, -8 127; CHECK-MACHO: .cfi_offset w29, -16 128; CHECK-MACHO: .cfi_offset w19, -24 129; CHECK-MACHO: .cfi_offset w20, -32 130; Check correct access to arguments passed on the stack, through frame pointer 131; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 132; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 133; Check correct access to local variable on the stack, through stack pointer 134; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [sp, #12] 135; Check epilogue: 136; CHECK-MACHO: ldp x29, x30, [sp, #16] 137; CHECK-MACHO: ldp x20, x19, [sp], #32 138; CHECK-MACHO: ret 139; CHECK-MACHO: .cfi_endproc 140 141 142declare i32 @g() #0 143 144; Function Attrs: nounwind 145define 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 { 146entry: 147 %l1 = alloca i32, align 4 148 %conv = fptosi double %d10 to i32 149 %add = add nsw i32 %conv, %i10 150 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4 151 %add1 = add nsw i32 %add, %l1.0.l1.0. 152 ret i32 %add1 153} 154; CHECK-LABEL: novla_nodynamicrealign_nocall 155; Check that space is reserved for one local variable on the stack. 156; CHECK: sub sp, sp, #16 // =16 157; Check correct access to arguments passed on the stack, through stack pointer 158; CHECK: ldr d[[DARG:[0-9]+]], [sp, #40] 159; CHECK: ldr w[[IARG:[0-9]+]], [sp, #24] 160; Check correct access to local variable on the stack, through stack pointer 161; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12] 162; Check epilogue: 163; CHECK: add sp, sp, #16 // =16 164; CHECK: ret 165 166 167define 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 { 168entry: 169 %l1 = alloca i32, align 128 170 %conv = fptosi double %d10 to i32 171 %add = add nsw i32 %conv, %i10 172 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 173 %add1 = add nsw i32 %add, %l1.0.l1.0. 174 %call = tail call i32 @g() 175 %add2 = add nsw i32 %add1, %call 176 ret i32 %add2 177} 178 179; CHECK-LABEL: novla_dynamicrealign_call 180; CHECK: .cfi_startproc 181; Check that used callee-saved registers are saved 182; CHECK: str x19, [sp, #-32]! 183; Check that the frame pointer is created: 184; CHECK: stp x29, x30, [sp, #16] 185; CHECK: add x29, sp, #16 186; Check the dynamic realignment of the stack pointer to a 128-byte boundary 187; CHECK: sub x9, sp, #96 188; CHECK: and sp, x9, #0xffffffffffffff80 189; Check correctness of cfi pseudo-instructions 190; CHECK: .cfi_def_cfa w29, 16 191; CHECK: .cfi_offset w30, -8 192; CHECK: .cfi_offset w29, -16 193; CHECK: .cfi_offset w19, -32 194; Check correct access to arguments passed on the stack, through frame pointer 195; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 196; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 197; Check correct access to local variable on the stack, through re-aligned stack pointer 198; CHECK: ldr w[[ILOC:[0-9]+]], [sp] 199; Check epilogue: 200; Check that stack pointer get restored from frame pointer. 201; CHECK: sub sp, x29, #16 // =16 202; CHECK: ldp x29, x30, [sp, #16] 203; CHECK: ldr x19, [sp], #32 204; CHECK: ret 205; CHECK: .cfi_endproc 206 207; CHECK-MACHO-LABEL: _novla_dynamicrealign_call: 208; CHECK-MACHO: .cfi_startproc 209; Check that used callee-saved registers are saved 210; CHECK-MACHO: stp x20, x19, [sp, #-32]! 211; Check that the frame pointer is created: 212; CHECK-MACHO: stp x29, x30, [sp, #16] 213; CHECK-MACHO: add x29, sp, #16 214; Check the dynamic realignment of the stack pointer to a 128-byte boundary 215; CHECK-MACHO: sub x9, sp, #96 216; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 217; Check correctness of cfi pseudo-instructions 218; CHECK-MACHO: .cfi_def_cfa w29, 16 219; CHECK-MACHO: .cfi_offset w30, -8 220; CHECK-MACHO: .cfi_offset w29, -16 221; CHECK-MACHO: .cfi_offset w19, -24 222; CHECK-MACHO: .cfi_offset w20, -32 223; Check correct access to arguments passed on the stack, through frame pointer 224; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 225; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 226; Check correct access to local variable on the stack, through re-aligned stack pointer 227; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [sp] 228; Check epilogue: 229; Check that stack pointer get restored from frame pointer. 230; CHECK-MACHO: sub sp, x29, #16 231; CHECK-MACHO: ldp x29, x30, [sp, #16] 232; CHECK-MACHO: ldp x20, x19, [sp], #32 233; CHECK-MACHO: ret 234; CHECK-MACHO: .cfi_endproc 235 236 237; Function Attrs: nounwind 238define 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 { 239entry: 240 %l1 = alloca i32, align 128 241 %conv = fptosi double %d10 to i32 242 %add = add nsw i32 %conv, %i10 243 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 244 %add1 = add nsw i32 %add, %l1.0.l1.0. 245 ret i32 %add1 246} 247 248; CHECK-LABEL: novla_dynamicrealign_nocall 249; Check that the frame pointer is created: 250; CHECK: stp x29, x30, [sp, #-16]! 251; CHECK: mov x29, sp 252; Check the dynamic realignment of the stack pointer to a 128-byte boundary 253; CHECK: sub x9, sp, #112 254; CHECK: and sp, x9, #0xffffffffffffff80 255; Check correct access to arguments passed on the stack, through frame pointer 256; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 257; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 258; Check correct access to local variable on the stack, through re-aligned stack pointer 259; CHECK: ldr w[[ILOC:[0-9]+]], [sp] 260; Check epilogue: 261; Check that stack pointer get restored from frame pointer. 262; CHECK: mov sp, x29 263; CHECK: ldp x29, x30, [sp], #16 264; CHECK: ret 265 266 267define 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 { 268entry: 269 %l1 = alloca i32, align 4 270 %0 = zext i32 %i1 to i64 271 %vla = alloca i32, i64 %0, align 4 272 %conv = fptosi double %d10 to i32 273 %add = add nsw i32 %conv, %i10 274 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4 275 %add1 = add nsw i32 %add, %l1.0.l1.0. 276 %call = tail call i32 @g() 277 %add2 = add nsw i32 %add1, %call 278 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 279 %add3 = add nsw i32 %add2, %1 280 ret i32 %add3 281} 282 283; CHECK-LABEL: vla_nodynamicrealign_call 284; CHECK: .cfi_startproc 285; Check that used callee-saved registers are saved 286; CHECK: stp x20, x19, [sp, #-32]! 287; Check that the frame pointer is created: 288; CHECK: stp x29, x30, [sp, #16] 289; CHECK: add x29, sp, #16 290; Check that space is reserved on the stack for the local variable, 291; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned. 292; CHECK: sub sp, sp, #16 293; Check correctness of cfi pseudo-instructions 294; CHECK: .cfi_def_cfa w29, 16 295; CHECK: .cfi_offset w30, -8 296; CHECK: .cfi_offset w29, -16 297; CHECK: .cfi_offset w19, -24 298; CHECK: .cfi_offset w20, -32 299; Check correct access to arguments passed on the stack, through frame pointer 300; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 301; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 302; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 303; CHECK: mov w9, w0 304; CHECK: mov x10, sp 305; CHECK: lsl x9, x9, #2 306; CHECK: add x9, x9, #15 307; CHECK: and x9, x9, #0x7fffffff0 308; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 309; CHECK: mov sp, x[[VLASPTMP]] 310; Check correct access to local variable, through frame pointer 311; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-20] 312; Check correct accessing of the VLA variable through the base pointer 313; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 314; Check epilogue: 315; Check that stack pointer get restored from frame pointer. 316; CHECK: sub sp, x29, #16 // =16 317; CHECK: ldp x29, x30, [sp, #16] 318; CHECK: ldp x20, x19, [sp], #32 319; CHECK: ret 320; CHECK: .cfi_endproc 321 322 323; Function Attrs: nounwind 324define 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 { 325entry: 326 %l1 = alloca i32, align 4 327 %0 = zext i32 %i1 to i64 328 %vla = alloca i32, i64 %0, align 4 329 %conv = fptosi double %d10 to i32 330 %add = add nsw i32 %conv, %i10 331 %l1.0.l1.0. = load volatile i32, i32* %l1, align 4 332 %add1 = add nsw i32 %add, %l1.0.l1.0. 333 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 334 %add2 = add nsw i32 %add1, %1 335 ret i32 %add2 336} 337 338; CHECK-LABEL: vla_nodynamicrealign_nocall 339; Check that the frame pointer is created: 340; CHECK: stp x29, x30, [sp, #-16]! 341; CHECK: mov x29, sp 342; Check that space is reserved on the stack for the local variable, 343; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned. 344; CHECK: sub sp, sp, #16 345; Check correctness of cfi pseudo-instructions 346; Check correct access to arguments passed on the stack, through frame pointer 347; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 348; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 349; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 350; CHECK: mov w9, w0 351; CHECK: mov x10, sp 352; CHECK: lsl x9, x9, #2 353; CHECK: add x9, x9, #15 354; CHECK: and x9, x9, #0x7fffffff0 355; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 356; CHECK: mov sp, x[[VLASPTMP]] 357; Check correct access to local variable, through frame pointer 358; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4] 359; Check correct accessing of the VLA variable through the base pointer 360; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 361; Check epilogue: 362; Check that stack pointer get restored from frame pointer. 363; CHECK: mov sp, x29 364; CHECK: ldp x29, x30, [sp], #16 365; CHECK: ret 366 367 368define 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 { 369entry: 370 %l1 = alloca i32, align 128 371 %0 = zext i32 %i1 to i64 372 %vla = alloca i32, i64 %0, align 4 373 %conv = fptosi double %d10 to i32 374 %add = add nsw i32 %conv, %i10 375 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 376 %add1 = add nsw i32 %add, %l1.0.l1.0. 377 %call = tail call i32 @g() 378 %add2 = add nsw i32 %add1, %call 379 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 380 %add3 = add nsw i32 %add2, %1 381 ret i32 %add3 382} 383 384; CHECK-LABEL: vla_dynamicrealign_call 385; CHECK: .cfi_startproc 386; Check that used callee-saved registers are saved 387; CHECK: str x21, [sp, #-48]! 388; CHECK: stp x20, x19, [sp, #16] 389; Check that the frame pointer is created: 390; CHECK: stp x29, x30, [sp, #32] 391; CHECK: add x29, sp, #32 392; Check that the stack pointer gets re-aligned to 128 393; bytes & the base pointer (x19) gets initialized to 394; this 128-byte aligned area for local variables & 395; spill slots 396; CHECK: sub x9, sp, #80 // =80 397; CHECK: and sp, x9, #0xffffffffffffff80 398; CHECK: mov x19, sp 399; Check correctness of cfi pseudo-instructions 400; CHECK: .cfi_def_cfa w29, 16 401; CHECK: .cfi_offset w30, -8 402; CHECK: .cfi_offset w29, -16 403; CHECK: .cfi_offset w19, -24 404; CHECK: .cfi_offset w20, -32 405; CHECK: .cfi_offset w21, -48 406; Check correct access to arguments passed on the stack, through frame pointer 407; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 408; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 409; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 410; and set-up of base pointer (x19). 411; CHECK: mov w9, w0 412; CHECK: mov x10, sp 413; CHECK: lsl x9, x9, #2 414; CHECK: add x9, x9, #15 415; CHECK: and x9, x9, #0x7fffffff0 416; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 417; CHECK: mov sp, x[[VLASPTMP]] 418; Check correct access to local variable, through base pointer 419; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 420; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 421; Check epilogue: 422; Check that stack pointer get restored from frame pointer. 423; CHECK: sub sp, x29, #32 424; CHECK: ldp x29, x30, [sp, #32] 425; CHECK: ldp x20, x19, [sp, #16] 426; CHECK: ldr x21, [sp], #48 427; CHECK: ret 428; CHECK: .cfi_endproc 429 430; CHECK-MACHO-LABEL: _vla_dynamicrealign_call: 431; CHECK-MACHO: .cfi_startproc 432; Check that used callee-saved registers are saved 433; CHECK-MACHO: stp x22, x21, [sp, #-48]! 434; CHECK-MACHO: stp x20, x19, [sp, #16] 435; Check that the frame pointer is created: 436; CHECK-MACHO: stp x29, x30, [sp, #32] 437; CHECK-MACHO: add x29, sp, #32 438; Check that the stack pointer gets re-aligned to 128 439; bytes & the base pointer (x19) gets initialized to 440; this 128-byte aligned area for local variables & 441; spill slots 442; CHECK-MACHO: sub x9, sp, #80 443; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 444; CHECK-MACHO: mov x19, sp 445; Check correctness of cfi pseudo-instructions 446; CHECK-MACHO: .cfi_def_cfa w29, 16 447; CHECK-MACHO: .cfi_offset w30, -8 448; CHECK-MACHO: .cfi_offset w29, -16 449; CHECK-MACHO: .cfi_offset w19, -24 450; CHECK-MACHO: .cfi_offset w20, -32 451; CHECK-MACHO: .cfi_offset w21, -40 452; CHECK-MACHO: .cfi_offset w22, -48 453; Check correct access to arguments passed on the stack, through frame pointer 454; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 455; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 456; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 457; and set-up of base pointer (x19). 458; CHECK-MACHO: mov w9, w0 459; CHECK-MACHO: mov x10, sp 460; CHECK-MACHO: lsl x9, x9, #2 461; CHECK-MACHO: add x9, x9, #15 462; CHECK-MACHO: and x9, x9, #0x7fffffff0 463; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9 464; CHECK-MACHO: mov sp, x[[VLASPTMP]] 465; Check correct access to local variable, through base pointer 466; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 467; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 468; Check epilogue: 469; Check that stack pointer get restored from frame pointer. 470; CHECK-MACHO: sub sp, x29, #32 471; CHECK-MACHO: ldp x29, x30, [sp, #32] 472; CHECK-MACHO: ldp x20, x19, [sp, #16] 473; CHECK-MACHO: ldp x22, x21, [sp], #48 474; CHECK-MACHO: ret 475; CHECK-MACHO: .cfi_endproc 476 477 478; Function Attrs: nounwind 479define 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 { 480entry: 481 %l1 = alloca i32, align 128 482 %0 = zext i32 %i1 to i64 483 %vla = alloca i32, i64 %0, align 4 484 %conv = fptosi double %d10 to i32 485 %add = add nsw i32 %conv, %i10 486 %l1.0.l1.0. = load volatile i32, i32* %l1, align 128 487 %add1 = add nsw i32 %add, %l1.0.l1.0. 488 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 489 %add2 = add nsw i32 %add1, %1 490 ret i32 %add2 491} 492 493; CHECK-LABEL: vla_dynamicrealign_nocall 494; Check that used callee-saved registers are saved 495; CHECK: str x19, [sp, #-32]! 496; Check that the frame pointer is created: 497; CHECK: stp x29, x30, [sp, #16] 498; CHECK: add x29, sp, #16 499; Check that the stack pointer gets re-aligned to 128 500; bytes & the base pointer (x19) gets initialized to 501; this 128-byte aligned area for local variables & 502; spill slots 503; CHECK: sub x9, sp, #96 504; CHECK: and sp, x9, #0xffffffffffffff80 505; CHECK: mov x19, sp 506; Check correct access to arguments passed on the stack, through frame pointer 507; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 508; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 509; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 510; and set-up of base pointer (x19). 511; CHECK: mov w9, w0 512; CHECK: mov x10, sp 513; CHECK: lsl x9, x9, #2 514; CHECK: add x9, x9, #15 515; CHECK: and x9, x9, #0x7fffffff0 516; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 517; CHECK: mov sp, x[[VLASPTMP]] 518; Check correct access to local variable, through base pointer 519; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 520; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 521; Check epilogue: 522; Check that stack pointer get restored from frame pointer. 523; CHECK: sub sp, x29, #16 524; CHECK: ldp x29, x30, [sp, #16] 525; CHECK: ldr x19, [sp], #32 526; CHECK: ret 527 528; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall: 529; Check that used callee-saved registers are saved 530; CHECK-MACHO: stp x20, x19, [sp, #-32]! 531; Check that the frame pointer is created: 532; CHECK-MACHO: stp x29, x30, [sp, #16] 533; CHECK-MACHO: add x29, sp, #16 534; Check that the stack pointer gets re-aligned to 128 535; bytes & the base pointer (x19) gets initialized to 536; this 128-byte aligned area for local variables & 537; spill slots 538; CHECK-MACHO: sub x9, sp, #96 539; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 540; CHECK-MACHO: mov x19, sp 541; Check correct access to arguments passed on the stack, through frame pointer 542; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 543; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 544; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 545; and set-up of base pointer (x19). 546; CHECK-MACHO: mov w9, w0 547; CHECK-MACHO: mov x10, sp 548; CHECK-MACHO: lsl x9, x9, #2 549; CHECK-MACHO: add x9, x9, #15 550; CHECK-MACHO: and x9, x9, #0x7fffffff0 551; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9 552; CHECK-MACHO: mov sp, x[[VLASPTMP]] 553; Check correct access to local variable, through base pointer 554; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 555; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 556; Check epilogue: 557; Check that stack pointer get restored from frame pointer. 558; CHECK-MACHO: sub sp, x29, #16 559; CHECK-MACHO: ldp x29, x30, [sp, #16] 560; CHECK-MACHO: ldp x20, x19, [sp], #32 561; CHECK-MACHO: ret 562 563 564; Function Attrs: nounwind 565define 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 { 566entry: 567 %l1 = alloca i32, align 32768 568 %0 = zext i32 %i1 to i64 569 %vla = alloca i32, i64 %0, align 4 570 %conv = fptosi double %d10 to i32 571 %add = add nsw i32 %conv, %i10 572 %l1.0.l1.0. = load volatile i32, i32* %l1, align 32768 573 %add1 = add nsw i32 %add, %l1.0.l1.0. 574 %1 = load volatile i32, i32* %vla, align 4, !tbaa !1 575 %add2 = add nsw i32 %add1, %1 576 ret i32 %add2 577} 578 579; CHECK-LABEL: vla_dynamicrealign_nocall_large_align 580; Check that used callee-saved registers are saved 581; CHECK: stp x28, x19, [sp, #-32]! 582; Check that the frame pointer is created: 583; CHECK: stp x29, x30, [sp, #16] 584; CHECK: add x29, sp, #16 585; Check that the stack pointer gets re-aligned to 128 586; bytes & the base pointer (x19) gets initialized to 587; this 128-byte aligned area for local variables & 588; spill slots 589; CHECK: sub x9, sp, #7, lsl #12 590; CHECK: and sp, x9, #0xffffffffffff8000 591; CHECK: mov x19, sp 592; Check correct access to arguments passed on the stack, through frame pointer 593; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 594; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 595; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 596; and set-up of base pointer (x19). 597; CHECK: mov w9, w0 598; CHECK: mov x10, sp 599; CHECK: lsl x9, x9, #2 600; CHECK: add x9, x9, #15 601; CHECK: and x9, x9, #0x7fffffff0 602; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 603; CHECK: mov sp, x[[VLASPTMP]] 604; Check correct access to local variable, through base pointer 605; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 606; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 607; Check epilogue: 608; Check that stack pointer get restored from frame pointer. 609; CHECK: sub sp, x29, #16 610; CHECK: ldp x29, x30, [sp, #16] 611; CHECK: ldp x28, x19, [sp], #32 612; CHECK: ret 613 614; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align: 615; Check that used callee-saved registers are saved 616; CHECK-MACHO: stp x20, x19, [sp, #-32]! 617; Check that the frame pointer is created: 618; CHECK-MACHO: stp x29, x30, [sp, #16] 619; CHECK-MACHO: add x29, sp, #16 620; Check that the stack pointer gets re-aligned to 128 621; bytes & the base pointer (x19) gets initialized to 622; this 128-byte aligned area for local variables & 623; spill slots 624; CHECK-MACHO: sub x9, sp, #7, lsl #12 625; CHECK-MACHO: and sp, x9, #0xffffffffffff8000 626; CHECK-MACHO: mov x19, sp 627; Check correct access to arguments passed on the stack, through frame pointer 628; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 629; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 630; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 631; and set-up of base pointer (x19). 632; CHECK-MACHO: mov w9, w0 633; CHECK-MACHO: mov x10, sp 634; CHECK-MACHO: lsl x9, x9, #2 635; CHECK-MACHO: add x9, x9, #15 636; CHECK-MACHO: and x9, x9, #0x7fffffff0 637; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x9 638; CHECK-MACHO: mov sp, x[[VLASPTMP]] 639; Check correct access to local variable, through base pointer 640; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 641; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 642; Check epilogue: 643; Check that stack pointer get restored from frame pointer. 644; CHECK-MACHO: sub sp, x29, #16 645; CHECK-MACHO: ldp x29, x30, [sp, #16] 646; CHECK-MACHO: ldp x20, x19, [sp], #32 647; CHECK-MACHO: ret 648 649 650define void @realign_conditional(i1 %b) { 651entry: 652 br i1 %b, label %bb0, label %bb1 653 654bb0: 655 %MyAlloca = alloca i8, i64 64, align 32 656 br label %bb1 657 658bb1: 659 ret void 660} 661 662; CHECK-LABEL: realign_conditional 663; No realignment in the prologue. 664; CHECK-NOT: and 665; CHECK-NOT: 0xffffffffffffffe0 666; CHECK: tbz {{.*}} .[[LABEL:.*]] 667; Stack is realigned in a non-entry BB. 668; CHECK: sub [[REG:x[01-9]+]], sp, #64 669; CHECK: and sp, [[REG]], #0xffffffffffffffe0 670; CHECK: .[[LABEL]]: 671; CHECK: ret 672 673 674define void @realign_conditional2(i1 %b) { 675entry: 676 %tmp = alloca i8, i32 4 677 br i1 %b, label %bb0, label %bb1 678 679bb0: 680 %MyAlloca = alloca i8, i64 64, align 32 681 br label %bb1 682 683bb1: 684 ret void 685} 686 687; CHECK-LABEL: realign_conditional2 688; Extra realignment in the prologue (performance issue). 689; CHECK: tbz {{.*}} .[[LABEL:.*]] 690; CHECK: sub x9, sp, #32 // =32 691; CHECK: and sp, x9, #0xffffffffffffffe0 692; CHECK: mov x19, sp 693; Stack is realigned in a non-entry BB. 694; CHECK: sub [[REG:x[01-9]+]], sp, #64 695; CHECK: and sp, [[REG]], #0xffffffffffffffe0 696; CHECK: .[[LABEL]]: 697; CHECK: ret 698 699attributes #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" } 700attributes #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" } 701 702!1 = !{!2, !2, i64 0} 703!2 = !{!"int", !3, i64 0} 704!3 = !{!"omnipotent char", !4, i64 0} 705!4 = !{!"Simple C/C++ TBAA"} 706