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