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: 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 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, 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 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, 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 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, 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 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, 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 325define 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 { 326entry: 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 369define 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 { 370entry: 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 480define 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 { 481entry: 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 566define 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 { 567entry: 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 651define void @realign_conditional(i1 %b) { 652entry: 653 br i1 %b, label %bb0, label %bb1 654 655bb0: 656 %MyAlloca = alloca i8, i64 64, align 32 657 br label %bb1 658 659bb1: 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 675define void @realign_conditional2(i1 %b) { 676entry: 677 %tmp = alloca i8, i32 16 678 br i1 %b, label %bb0, label %bb1 679 680bb0: 681 %MyAlloca = alloca i8, i64 64, align 32 682 br label %bb1 683 684bb1: 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 700attributes #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" } 701attributes #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