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 -frame-pointer=all -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, ptr %l1, align 4 93 %add1 = or 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 x30, x19, [sp, #16] 103; Check correctness of cfi pseudo-instructions 104; CHECK: .cfi_def_cfa_offset 32 105; CHECK: .cfi_offset w19, -8 106; CHECK: .cfi_offset w30, -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 x30, x19, [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 143declare i32 @g() #0 144 145; Function Attrs: nounwind 146define 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 { 147entry: 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, ptr %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 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 165; CHECK: ret 166 167 168define 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 { 169entry: 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, ptr %l1, align 128 174 %add1 = or 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: stp x29, x30, [sp, #-32]! 184; Check that the frame pointer is created: 185; CHECK: str x19, [sp, #16] 186; CHECK: mov x29, sp 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, 32 192; CHECK: .cfi_offset w19, -16 193; CHECK: .cfi_offset w30, -24 194; CHECK: .cfi_offset w29, -32 195; Check correct access to arguments passed on the stack, through frame pointer 196; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56] 197; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40] 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: mov sp, x29 203; CHECK: ldr x19, [sp, #16] 204; CHECK: ldp x29, x30, [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 239define 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 { 240entry: 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, ptr %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 268define 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 { 269entry: 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, ptr %l1, align 4 276 %add1 = or i32 %add, %l1.0.l1.0. 277 %call = tail call i32 @g() 278 %add2 = add nsw i32 %add1, %call 279 %1 = load volatile i32, ptr %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 x29, x30, [sp, #-32]! 288; Check that the frame pointer is created: 289; CHECK: stp x20, x19, [sp, #16] 290; CHECK: mov x29, sp 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, 32 296; CHECK: .cfi_offset w19, -8 297; CHECK: .cfi_offset w20, -16 298; CHECK: .cfi_offset w30, -24 299; CHECK: .cfi_offset w29, -32 300; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 301; CHECK: ubfiz x8, x0, #2, #32 302; Check correct access to arguments passed on the stack, through frame pointer 303; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40] 304; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56] 305; CHECK: add x8, x8, #15 306; CHECK: and x8, x8, #0x7fffffff0 307; CHECK: mov x10, sp 308; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8 309; CHECK: mov sp, x[[VLASPTMP]] 310; Check correct access to local variable, through frame pointer 311; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4] 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: mov sp, x29 317; CHECK: ldp x20, x19, [sp, #16] 318; CHECK: ldp x29, x30, [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, ptr %l1, align 4 332 %add1 = add nsw i32 %add, %l1.0.l1.0. 333 %1 = load volatile i32, ptr %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 correct reservation of 16-byte aligned VLA (size in w0) on stack 346; CHECK: ubfiz x8, x0, #2, #32 347; Check correctness of cfi pseudo-instructions 348; Check correct access to arguments passed on the stack, through frame pointer 349; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] 350; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] 351; CHECK: add x8, x8, #15 352; CHECK: and x8, x8, #0x7fffffff0 353; CHECK: mov x10, sp 354; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8 355; CHECK: mov sp, x[[VLASPTMP]] 356; Check correct access to local variable, through frame pointer 357; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4] 358; Check correct accessing of the VLA variable through the base pointer 359; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 360; Check epilogue: 361; Check that stack pointer get restored from frame pointer. 362; CHECK: mov sp, x29 363; CHECK: ldp x29, x30, [sp], #16 364; CHECK: ret 365 366 367define 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 { 368entry: 369 %l1 = alloca i32, align 128 370 %0 = zext i32 %i1 to i64 371 %vla = alloca i32, i64 %0, align 4 372 %conv = fptosi double %d10 to i32 373 %add = add nsw i32 %conv, %i10 374 %l1.0.l1.0. = load volatile i32, ptr %l1, align 128 375 %add1 = or i32 %add, %l1.0.l1.0. 376 %call = tail call i32 @g() 377 %add2 = add nsw i32 %add1, %call 378 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1 379 %add3 = add nsw i32 %add2, %1 380 ret i32 %add3 381} 382 383; CHECK-LABEL: vla_dynamicrealign_call 384; CHECK: .cfi_startproc 385; Check that used callee-saved registers are saved 386; CHECK: stp x29, x30, [sp, #-48]! 387; CHECK: str x21, [sp, #16] 388; CHECK: stp x20, x19, [sp, #32] 389; Check that the frame pointer is created: 390; CHECK: mov x29, sp 391; Check that the stack pointer gets re-aligned to 128 392; bytes & the base pointer (x19) gets initialized to 393; this 128-byte aligned area for local variables & 394; spill slots 395; CHECK: sub x9, sp, #80 396; CHECK: and sp, x9, #0xffffffffffffff80 397; CHECK: mov x19, sp 398; Check correctness of cfi pseudo-instructions 399; CHECK: .cfi_def_cfa w29, 48 400; CHECK: .cfi_offset w19, -8 401; CHECK: .cfi_offset w20, -16 402; CHECK: .cfi_offset w21, -32 403; CHECK: .cfi_offset w30, -40 404; CHECK: .cfi_offset w29, -48 405; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 406; and set-up of base pointer (x19). 407; CHECK: ubfiz x8, x0, #2, #32 408; Check correct access to arguments passed on the stack, through frame pointer 409; CHECK: ldr w[[IARG:[0-9]+]], [x29, #56] 410; CHECK: ldr d[[DARG:[0-9]+]], [x29, #72] 411; CHECK: add x8, x8, #15 412; CHECK: and x8, x8, #0x7fffffff0 413; CHECK: mov x10, sp 414; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8 415; CHECK: mov sp, x[[VLASPTMP]] 416; Check correct access to local variable, through base pointer 417; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 418; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 419; Check epilogue: 420; Check that stack pointer get restored from frame pointer. 421; CHECK: mov sp, x29 422; CHECK: ldp x20, x19, [sp, #32] 423; CHECK: ldr x21, [sp, #16] 424; CHECK: ldp x29, x30, [sp], #48 425; CHECK: ret 426; CHECK: .cfi_endproc 427 428; CHECK-MACHO-LABEL: _vla_dynamicrealign_call: 429; CHECK-MACHO: .cfi_startproc 430; Check that used callee-saved registers are saved 431; CHECK-MACHO: stp x22, x21, [sp, #-48]! 432; CHECK-MACHO: stp x20, x19, [sp, #16] 433; Check that the frame pointer is created: 434; CHECK-MACHO: stp x29, x30, [sp, #32] 435; CHECK-MACHO: add x29, sp, #32 436; Check that the stack pointer gets re-aligned to 128 437; bytes & the base pointer (x19) gets initialized to 438; this 128-byte aligned area for local variables & 439; spill slots 440; CHECK-MACHO: sub x9, sp, #80 441; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 442; CHECK-MACHO: mov x19, sp 443; Check correctness of cfi pseudo-instructions 444; CHECK-MACHO: .cfi_def_cfa w29, 16 445; CHECK-MACHO: .cfi_offset w30, -8 446; CHECK-MACHO: .cfi_offset w29, -16 447; CHECK-MACHO: .cfi_offset w19, -24 448; CHECK-MACHO: .cfi_offset w20, -32 449; CHECK-MACHO: .cfi_offset w21, -40 450; CHECK-MACHO: .cfi_offset w22, -48 451; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 452; and set-up of base pointer (x19). 453; CHECK-MACHO: ubfiz x8, x0, #2, #32 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-MACHO: add x8, x8, #15 458; CHECK-MACHO: and x8, x8, #0x7fffffff0 459; CHECK-MACHO: mov x10, sp 460; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x8 461; CHECK-MACHO: mov sp, x[[VLASPTMP]] 462; Check correct access to local variable, through base pointer 463; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 464; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 465; Check epilogue: 466; Check that stack pointer get restored from frame pointer. 467; CHECK-MACHO: sub sp, x29, #32 468; CHECK-MACHO: ldp x29, x30, [sp, #32] 469; CHECK-MACHO: ldp x20, x19, [sp, #16] 470; CHECK-MACHO: ldp x22, x21, [sp], #48 471; CHECK-MACHO: ret 472; CHECK-MACHO: .cfi_endproc 473 474 475; Function Attrs: nounwind 476define 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 { 477entry: 478 %l1 = alloca i32, align 128 479 %0 = zext i32 %i1 to i64 480 %vla = alloca i32, i64 %0, align 4 481 %conv = fptosi double %d10 to i32 482 %add = add nsw i32 %conv, %i10 483 %l1.0.l1.0. = load volatile i32, ptr %l1, align 128 484 %add1 = add nsw i32 %add, %l1.0.l1.0. 485 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1 486 %add2 = add nsw i32 %add1, %1 487 ret i32 %add2 488} 489 490; CHECK-LABEL: vla_dynamicrealign_nocall 491; Check that used callee-saved registers are saved 492; CHECK: stp x29, x30, [sp, #-32]! 493; CHECK: str x19, [sp, #16] 494; Check that the frame pointer is created: 495; CHECK: mov x29, sp 496; Check that the stack pointer gets re-aligned to 128 497; bytes & the base pointer (x19) gets initialized to 498; this 128-byte aligned area for local variables & 499; spill slots 500; CHECK: sub x9, sp, #96 501; CHECK: and sp, x9, #0xffffffffffffff80 502; CHECK: mov x19, sp 503; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 504; and set-up of base pointer (x19). 505; CHECK: ubfiz x8, x0, #2, #32 506; Check correct access to arguments passed on the stack, through frame pointer 507; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40] 508; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56] 509; CHECK: add x8, x8, #15 510; CHECK: and x8, x8, #0x7fffffff0 511; CHECK: mov x10, sp 512; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8 513; CHECK: mov sp, x[[VLASPTMP]] 514; Check correct access to local variable, through base pointer 515; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 516; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 517; Check epilogue: 518; Check that stack pointer get restored from frame pointer. 519; CHECK: mov sp, x29 520; CHECK: ldr x19, [sp, #16] 521; CHECK: ldp x29, x30, [sp], #32 522; CHECK: ret 523 524; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall: 525; Check that used callee-saved registers are saved 526; CHECK-MACHO: stp x20, x19, [sp, #-32]! 527; Check that the frame pointer is created: 528; CHECK-MACHO: stp x29, x30, [sp, #16] 529; CHECK-MACHO: add x29, sp, #16 530; Check that the stack pointer gets re-aligned to 128 531; bytes & the base pointer (x19) gets initialized to 532; this 128-byte aligned area for local variables & 533; spill slots 534; CHECK-MACHO: sub x9, sp, #96 535; CHECK-MACHO: and sp, x9, #0xffffffffffffff80 536; CHECK-MACHO: mov x19, sp 537; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 538; and set-up of base pointer (x19). 539; CHECK-MACHO: ubfiz x8, x0, #2, #32 540; Check correct access to arguments passed on the stack, through frame pointer 541; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 542; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 543; CHECK-MACHO: add x8, x8, #15 544; CHECK-MACHO: and x8, x8, #0x7fffffff0 545; CHECK-MACHO: mov x10, sp 546; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x8 547; CHECK-MACHO: mov sp, x[[VLASPTMP]] 548; Check correct access to local variable, through base pointer 549; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 550; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 551; Check epilogue: 552; Check that stack pointer get restored from frame pointer. 553; CHECK-MACHO: sub sp, x29, #16 554; CHECK-MACHO: ldp x29, x30, [sp, #16] 555; CHECK-MACHO: ldp x20, x19, [sp], #32 556; CHECK-MACHO: ret 557 558 559; Function Attrs: nounwind 560define 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 { 561entry: 562 %l1 = alloca i32, align 32768 563 %0 = zext i32 %i1 to i64 564 %vla = alloca i32, i64 %0, align 4 565 %conv = fptosi double %d10 to i32 566 %add = add nsw i32 %conv, %i10 567 %l1.0.l1.0. = load volatile i32, ptr %l1, align 32768 568 %add1 = add nsw i32 %add, %l1.0.l1.0. 569 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1 570 %add2 = add nsw i32 %add1, %1 571 ret i32 %add2 572} 573 574; CHECK-LABEL: vla_dynamicrealign_nocall_large_align 575; Check that used callee-saved registers are saved 576; CHECK: stp x29, x30, [sp, #-32]! 577; CHECK: str x19, [sp, #16] 578; Check that the frame pointer is created: 579; CHECK: mov x29, sp 580; Check that the stack pointer gets re-aligned to 128 581; bytes & the base pointer (x19) gets initialized to 582; this 128-byte aligned area for local variables & 583; spill slots 584; CHECK: sub x9, sp, #7, lsl #12 585; CHECK: and sp, x9, #0xffffffffffff8000 586; CHECK: mov x19, sp 587; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 588; and set-up of base pointer (x19). 589; CHECK: ubfiz x8, x0, #2, #32 590; Check correct access to arguments passed on the stack, through frame pointer 591; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40] 592; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56] 593; CHECK: add x8, x8, #15 594; CHECK: and x8, x8, #0x7fffffff0 595; CHECK: mov x10, sp 596; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8 597; CHECK: mov sp, x[[VLASPTMP]] 598; Check correct access to local variable, through base pointer 599; CHECK: ldr w[[ILOC:[0-9]+]], [x19] 600; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 601; Check epilogue: 602; Check that stack pointer get restored from frame pointer. 603; CHECK: mov sp, x29 604; CHECK: ldr x19, [sp, #16] 605; CHECK: ldp x29, x30, [sp], #32 606; CHECK: ret 607 608; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align: 609; Check that used callee-saved registers are saved 610; CHECK-MACHO: stp x20, x19, [sp, #-32]! 611; Check that the frame pointer is created: 612; CHECK-MACHO: stp x29, x30, [sp, #16] 613; CHECK-MACHO: add x29, sp, #16 614; Check that the stack pointer gets re-aligned to 128 615; bytes & the base pointer (x19) gets initialized to 616; this 128-byte aligned area for local variables & 617; spill slots 618; CHECK-MACHO: sub x9, sp, #7, lsl #12 619; CHECK-MACHO: and sp, x9, #0xffffffffffff8000 620; CHECK-MACHO: mov x19, sp 621; Check correct reservation of 16-byte aligned VLA (size in w0) on stack 622; and set-up of base pointer (x19). 623; CHECK-MACHO: ubfiz x8, x0, #2, #32 624; Check correct access to arguments passed on the stack, through frame pointer 625; CHECK-MACHO: ldr w[[IARG:[0-9]+]], [x29, #20] 626; CHECK-MACHO: ldr d[[DARG:[0-9]+]], [x29, #32] 627; CHECK-MACHO: add x8, x8, #15 628; CHECK-MACHO: and x8, x8, #0x7fffffff0 629; CHECK-MACHO: mov x10, sp 630; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x8 631; CHECK-MACHO: mov sp, x[[VLASPTMP]] 632; Check correct access to local variable, through base pointer 633; CHECK-MACHO: ldr w[[ILOC:[0-9]+]], [x19] 634; CHECK-MACHO: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] 635; Check epilogue: 636; Check that stack pointer get restored from frame pointer. 637; CHECK-MACHO: sub sp, x29, #16 638; CHECK-MACHO: ldp x29, x30, [sp, #16] 639; CHECK-MACHO: ldp x20, x19, [sp], #32 640; CHECK-MACHO: ret 641 642declare void @use(ptr) 643 644define void @realign_conditional(i1 %b, ptr %p) { 645entry: 646 br i1 %b, label %bb0, label %bb1 647 648bb0: 649 %MyAlloca = alloca i8, i64 64, align 32 650 store ptr %MyAlloca, ptr %p 651 br label %bb1 652 653bb1: 654 ret void 655} 656 657; CHECK-LABEL: realign_conditional 658; No realignment in the prologue. 659; CHECK-NOT: and 660; CHECK-NOT: 0xffffffffffffffe0 661; CHECK: tbz {{.*}} .[[LABEL:.*]] 662; Stack is realigned in a non-entry BB. 663; CHECK: sub [[REG:x[01-9]+]], sp, #64 664; CHECK: and [[REG]], [[REG]], #0xffffffffffffffe0 665; CHECK: mov sp, [[REG]] 666; CHECK: .[[LABEL]]: 667; CHECK: ret 668 669 670define void @realign_conditional2(i1 %b, ptr %p) { 671entry: 672 %tmp = alloca i8, i32 16 673 br i1 %b, label %bb0, label %bb1 674 675bb0: 676 %MyAlloca = alloca i8, i64 64, align 32 677 store ptr %MyAlloca, ptr %p 678 br label %bb1 679 680bb1: 681 ret void 682} 683 684; CHECK-LABEL: realign_conditional2 685; Extra realignment in the prologue (performance issue). 686; CHECK: tbz {{.*}} .[[LABEL:.*]] 687; CHECK: sub x9, sp, #32 688; CHECK: and sp, x9, #0xffffffffffffffe0 689; CHECK: mov x19, sp 690; Stack is realigned in a non-entry BB. 691; CHECK: sub [[REG:x[01-9]+]], sp, #64 692; CHECK: and [[REG]], [[REG]], #0xffffffffffffffe0 693; CHECK: mov sp, [[REG]] 694; CHECK: .[[LABEL]]: 695; CHECK: ret 696 697attributes #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" } 698attributes #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" } 699 700!1 = !{!2, !2, i64 0} 701!2 = !{!"int", !3, i64 0} 702!3 = !{!"omnipotent char", !4, i64 0} 703!4 = !{!"Simple C/C++ TBAA"} 704