704 lines · plain
1; RUN: llc -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -disable-post-ra < %s | FileCheck %s2; RUN: llc -verify-machineinstrs -mtriple=arm64-apple-ios -frame-pointer=all -disable-post-ra < %s | FileCheck %s --check-prefix=CHECK-MACHO3 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 product7; of:8; . a function having a VLA/noVLA9; . 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 frame12; layout and which pointer to use to access various part of the13; frame (bp,sp,fp).14;15; Furthermore: in every test function:16; . there is always one integer and 1 floating point argument to be able17; to check those are accessed correctly.18; . there is always one local variable to check that is accessed19; correctly20;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 490 %conv = fptosi double %d10 to i3291 %add = add nsw i32 %conv, %i1092 %l1.0.l1.0. = load volatile i32, ptr %l1, align 493 %add1 = or i32 %add, %l1.0.l1.0.94 %call = tail call i32 @g()95 %add2 = add nsw i32 %add1, %call96 ret i32 %add297}98; CHECK-LABEL: novla_nodynamicrealign_call99; CHECK: .cfi_startproc100; Check that used callee-saved registers are saved101; CHECK: sub sp, sp, #32102; CHECK: stp x30, x19, [sp, #16]103; Check correctness of cfi pseudo-instructions104; CHECK: .cfi_def_cfa_offset 32105; CHECK: .cfi_offset w19, -8106; CHECK: .cfi_offset w30, -16107; Check correct access to arguments passed on the stack, through stack pointer108; 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 pointer111; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12]112; Check epilogue:113; CHECK: ldp x30, x19, [sp, #16]114; CHECK: ret115; CHECK: .cfi_endproc116 117; CHECK-MACHO-LABEL: _novla_nodynamicrealign_call:118; CHECK-MACHO: .cfi_startproc119; Check that used callee-saved registers are saved120; CHECK-MACHO: sub sp, sp, #48121; 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, #32125; Check correctness of cfi pseudo-instructions126; CHECK-MACHO: .cfi_def_cfa w29, 16127; CHECK-MACHO: .cfi_offset w30, -8128; CHECK-MACHO: .cfi_offset w29, -16129; CHECK-MACHO: .cfi_offset w19, -24130; CHECK-MACHO: .cfi_offset w20, -32131; Check correct access to arguments passed on the stack, through frame pointer132; 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 pointer135; 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: ret140; CHECK-MACHO: .cfi_endproc141 142 143declare i32 @g() #0144 145; Function Attrs: nounwind146define 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 4149 %conv = fptosi double %d10 to i32150 %add = add nsw i32 %conv, %i10151 %l1.0.l1.0. = load volatile i32, ptr %l1, align 4152 %add1 = add nsw i32 %add, %l1.0.l1.0.153 ret i32 %add1154}155; CHECK-LABEL: novla_nodynamicrealign_nocall156; Check that space is reserved for one local variable on the stack.157; CHECK: sub sp, sp, #16158; Check correct access to arguments passed on the stack, through stack pointer159; 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 pointer162; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12]163; Check epilogue:164; CHECK: add sp, sp, #16165; CHECK: ret166 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 128171 %conv = fptosi double %d10 to i32172 %add = add nsw i32 %conv, %i10173 %l1.0.l1.0. = load volatile i32, ptr %l1, align 128174 %add1 = or i32 %add, %l1.0.l1.0.175 %call = tail call i32 @g()176 %add2 = add nsw i32 %add1, %call177 ret i32 %add2178}179 180; CHECK-LABEL: novla_dynamicrealign_call181; CHECK: .cfi_startproc182; Check that used callee-saved registers are saved183; CHECK: stp x29, x30, [sp, #-32]!184; Check that the frame pointer is created:185; CHECK: str x19, [sp, #16]186; CHECK: mov x29, sp187; Check the dynamic realignment of the stack pointer to a 128-byte boundary188; CHECK: sub x9, sp, #96189; CHECK: and sp, x9, #0xffffffffffffff80190; Check correctness of cfi pseudo-instructions191; CHECK: .cfi_def_cfa w29, 32192; CHECK: .cfi_offset w19, -16193; CHECK: .cfi_offset w30, -24194; CHECK: .cfi_offset w29, -32195; Check correct access to arguments passed on the stack, through frame pointer196; 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 pointer199; CHECK: ldr w[[ILOC:[0-9]+]], [sp]200; Check epilogue:201; Check that stack pointer get restored from frame pointer.202; CHECK: mov sp, x29203; CHECK: ldr x19, [sp, #16]204; CHECK: ldp x29, x30, [sp], #32205; CHECK: ret206; CHECK: .cfi_endproc207 208; CHECK-MACHO-LABEL: _novla_dynamicrealign_call:209; CHECK-MACHO: .cfi_startproc210; Check that used callee-saved registers are saved211; 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, #16215; Check the dynamic realignment of the stack pointer to a 128-byte boundary216; CHECK-MACHO: sub x9, sp, #96217; CHECK-MACHO: and sp, x9, #0xffffffffffffff80218; Check correctness of cfi pseudo-instructions219; CHECK-MACHO: .cfi_def_cfa w29, 16220; CHECK-MACHO: .cfi_offset w30, -8221; CHECK-MACHO: .cfi_offset w29, -16222; CHECK-MACHO: .cfi_offset w19, -24223; CHECK-MACHO: .cfi_offset w20, -32224; Check correct access to arguments passed on the stack, through frame pointer225; 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 pointer228; 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, #16232; CHECK-MACHO: ldp x29, x30, [sp, #16]233; CHECK-MACHO: ldp x20, x19, [sp], #32234; CHECK-MACHO: ret235; CHECK-MACHO: .cfi_endproc236 237 238; Function Attrs: nounwind239define 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 128242 %conv = fptosi double %d10 to i32243 %add = add nsw i32 %conv, %i10244 %l1.0.l1.0. = load volatile i32, ptr %l1, align 128245 %add1 = add nsw i32 %add, %l1.0.l1.0.246 ret i32 %add1247}248 249; CHECK-LABEL: novla_dynamicrealign_nocall250; Check that the frame pointer is created:251; CHECK: stp x29, x30, [sp, #-16]!252; CHECK: mov x29, sp253; Check the dynamic realignment of the stack pointer to a 128-byte boundary254; CHECK: sub x9, sp, #112255; CHECK: and sp, x9, #0xffffffffffffff80256; Check correct access to arguments passed on the stack, through frame pointer257; 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 pointer260; CHECK: ldr w[[ILOC:[0-9]+]], [sp]261; Check epilogue:262; Check that stack pointer get restored from frame pointer.263; CHECK: mov sp, x29264; CHECK: ldp x29, x30, [sp], #16265; CHECK: ret266 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 4271 %0 = zext i32 %i1 to i64272 %vla = alloca i32, i64 %0, align 4273 %conv = fptosi double %d10 to i32274 %add = add nsw i32 %conv, %i10275 %l1.0.l1.0. = load volatile i32, ptr %l1, align 4276 %add1 = or i32 %add, %l1.0.l1.0.277 %call = tail call i32 @g()278 %add2 = add nsw i32 %add1, %call279 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1280 %add3 = add nsw i32 %add2, %1281 ret i32 %add3282}283 284; CHECK-LABEL: vla_nodynamicrealign_call285; CHECK: .cfi_startproc286; Check that used callee-saved registers are saved287; 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, sp291; 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, #16294; Check correctness of cfi pseudo-instructions295; CHECK: .cfi_def_cfa w29, 32296; CHECK: .cfi_offset w19, -8297; CHECK: .cfi_offset w20, -16298; CHECK: .cfi_offset w30, -24299; CHECK: .cfi_offset w29, -32300; Check correct reservation of 16-byte aligned VLA (size in w0) on stack301; CHECK: ubfiz x8, x0, #2, #32302; Check correct access to arguments passed on the stack, through frame pointer303; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40]304; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56]305; CHECK: add x8, x8, #15306; CHECK: and x8, x8, #0x7fffffff0307; CHECK: mov x10, sp308; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8309; CHECK: mov sp, x[[VLASPTMP]]310; Check correct access to local variable, through frame pointer311; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4]312; Check correct accessing of the VLA variable through the base pointer313; 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, x29317; CHECK: ldp x20, x19, [sp, #16]318; CHECK: ldp x29, x30, [sp], #32319; CHECK: ret320; CHECK: .cfi_endproc321 322 323; Function Attrs: nounwind324define 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 4327 %0 = zext i32 %i1 to i64328 %vla = alloca i32, i64 %0, align 4329 %conv = fptosi double %d10 to i32330 %add = add nsw i32 %conv, %i10331 %l1.0.l1.0. = load volatile i32, ptr %l1, align 4332 %add1 = add nsw i32 %add, %l1.0.l1.0.333 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1334 %add2 = add nsw i32 %add1, %1335 ret i32 %add2336}337 338; CHECK-LABEL: vla_nodynamicrealign_nocall339; Check that the frame pointer is created:340; CHECK: stp x29, x30, [sp, #-16]!341; CHECK: mov x29, sp342; 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, #16345; Check correct reservation of 16-byte aligned VLA (size in w0) on stack346; CHECK: ubfiz x8, x0, #2, #32347; Check correctness of cfi pseudo-instructions348; Check correct access to arguments passed on the stack, through frame pointer349; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24]350; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40]351; CHECK: add x8, x8, #15352; CHECK: and x8, x8, #0x7fffffff0353; CHECK: mov x10, sp354; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8355; CHECK: mov sp, x[[VLASPTMP]]356; Check correct access to local variable, through frame pointer357; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4]358; Check correct accessing of the VLA variable through the base pointer359; 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, x29363; CHECK: ldp x29, x30, [sp], #16364; CHECK: ret365 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 128370 %0 = zext i32 %i1 to i64371 %vla = alloca i32, i64 %0, align 4372 %conv = fptosi double %d10 to i32373 %add = add nsw i32 %conv, %i10374 %l1.0.l1.0. = load volatile i32, ptr %l1, align 128375 %add1 = or i32 %add, %l1.0.l1.0.376 %call = tail call i32 @g()377 %add2 = add nsw i32 %add1, %call378 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1379 %add3 = add nsw i32 %add2, %1380 ret i32 %add3381}382 383; CHECK-LABEL: vla_dynamicrealign_call384; CHECK: .cfi_startproc385; Check that used callee-saved registers are saved386; 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, sp391; Check that the stack pointer gets re-aligned to 128392; bytes & the base pointer (x19) gets initialized to393; this 128-byte aligned area for local variables &394; spill slots395; CHECK: sub x9, sp, #80396; CHECK: and sp, x9, #0xffffffffffffff80397; CHECK: mov x19, sp398; Check correctness of cfi pseudo-instructions399; CHECK: .cfi_def_cfa w29, 48400; CHECK: .cfi_offset w19, -8401; CHECK: .cfi_offset w20, -16402; CHECK: .cfi_offset w21, -32403; CHECK: .cfi_offset w30, -40404; CHECK: .cfi_offset w29, -48405; Check correct reservation of 16-byte aligned VLA (size in w0) on stack406; and set-up of base pointer (x19).407; CHECK: ubfiz x8, x0, #2, #32408; Check correct access to arguments passed on the stack, through frame pointer409; CHECK: ldr w[[IARG:[0-9]+]], [x29, #56]410; CHECK: ldr d[[DARG:[0-9]+]], [x29, #72]411; CHECK: add x8, x8, #15412; CHECK: and x8, x8, #0x7fffffff0413; CHECK: mov x10, sp414; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8415; CHECK: mov sp, x[[VLASPTMP]]416; Check correct access to local variable, through base pointer417; 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, x29422; CHECK: ldp x20, x19, [sp, #32]423; CHECK: ldr x21, [sp, #16]424; CHECK: ldp x29, x30, [sp], #48425; CHECK: ret426; CHECK: .cfi_endproc427 428; CHECK-MACHO-LABEL: _vla_dynamicrealign_call:429; CHECK-MACHO: .cfi_startproc430; Check that used callee-saved registers are saved431; 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, #32436; Check that the stack pointer gets re-aligned to 128437; bytes & the base pointer (x19) gets initialized to438; this 128-byte aligned area for local variables &439; spill slots440; CHECK-MACHO: sub x9, sp, #80441; CHECK-MACHO: and sp, x9, #0xffffffffffffff80442; CHECK-MACHO: mov x19, sp443; Check correctness of cfi pseudo-instructions444; CHECK-MACHO: .cfi_def_cfa w29, 16445; CHECK-MACHO: .cfi_offset w30, -8446; CHECK-MACHO: .cfi_offset w29, -16447; CHECK-MACHO: .cfi_offset w19, -24448; CHECK-MACHO: .cfi_offset w20, -32449; CHECK-MACHO: .cfi_offset w21, -40450; CHECK-MACHO: .cfi_offset w22, -48451; Check correct reservation of 16-byte aligned VLA (size in w0) on stack452; and set-up of base pointer (x19).453; CHECK-MACHO: ubfiz x8, x0, #2, #32454; Check correct access to arguments passed on the stack, through frame pointer455; 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, #15458; CHECK-MACHO: and x8, x8, #0x7fffffff0459; CHECK-MACHO: mov x10, sp460; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x8461; CHECK-MACHO: mov sp, x[[VLASPTMP]]462; Check correct access to local variable, through base pointer463; 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, #32468; CHECK-MACHO: ldp x29, x30, [sp, #32]469; CHECK-MACHO: ldp x20, x19, [sp, #16]470; CHECK-MACHO: ldp x22, x21, [sp], #48471; CHECK-MACHO: ret472; CHECK-MACHO: .cfi_endproc473 474 475; Function Attrs: nounwind476define 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 128479 %0 = zext i32 %i1 to i64480 %vla = alloca i32, i64 %0, align 4481 %conv = fptosi double %d10 to i32482 %add = add nsw i32 %conv, %i10483 %l1.0.l1.0. = load volatile i32, ptr %l1, align 128484 %add1 = add nsw i32 %add, %l1.0.l1.0.485 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1486 %add2 = add nsw i32 %add1, %1487 ret i32 %add2488}489 490; CHECK-LABEL: vla_dynamicrealign_nocall491; Check that used callee-saved registers are saved492; CHECK: stp x29, x30, [sp, #-32]!493; CHECK: str x19, [sp, #16]494; Check that the frame pointer is created:495; CHECK: mov x29, sp496; Check that the stack pointer gets re-aligned to 128497; bytes & the base pointer (x19) gets initialized to498; this 128-byte aligned area for local variables &499; spill slots500; CHECK: sub x9, sp, #96501; CHECK: and sp, x9, #0xffffffffffffff80502; CHECK: mov x19, sp503; Check correct reservation of 16-byte aligned VLA (size in w0) on stack504; and set-up of base pointer (x19).505; CHECK: ubfiz x8, x0, #2, #32506; Check correct access to arguments passed on the stack, through frame pointer507; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40]508; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56]509; CHECK: add x8, x8, #15510; CHECK: and x8, x8, #0x7fffffff0511; CHECK: mov x10, sp512; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8513; CHECK: mov sp, x[[VLASPTMP]]514; Check correct access to local variable, through base pointer515; 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, x29520; CHECK: ldr x19, [sp, #16]521; CHECK: ldp x29, x30, [sp], #32522; CHECK: ret523 524; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall:525; Check that used callee-saved registers are saved526; 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, #16530; Check that the stack pointer gets re-aligned to 128531; bytes & the base pointer (x19) gets initialized to532; this 128-byte aligned area for local variables &533; spill slots534; CHECK-MACHO: sub x9, sp, #96535; CHECK-MACHO: and sp, x9, #0xffffffffffffff80536; CHECK-MACHO: mov x19, sp537; Check correct reservation of 16-byte aligned VLA (size in w0) on stack538; and set-up of base pointer (x19).539; CHECK-MACHO: ubfiz x8, x0, #2, #32540; Check correct access to arguments passed on the stack, through frame pointer541; 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, #15544; CHECK-MACHO: and x8, x8, #0x7fffffff0545; CHECK-MACHO: mov x10, sp546; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x8547; CHECK-MACHO: mov sp, x[[VLASPTMP]]548; Check correct access to local variable, through base pointer549; 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, #16554; CHECK-MACHO: ldp x29, x30, [sp, #16]555; CHECK-MACHO: ldp x20, x19, [sp], #32556; CHECK-MACHO: ret557 558 559; Function Attrs: nounwind560define 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 32768563 %0 = zext i32 %i1 to i64564 %vla = alloca i32, i64 %0, align 4565 %conv = fptosi double %d10 to i32566 %add = add nsw i32 %conv, %i10567 %l1.0.l1.0. = load volatile i32, ptr %l1, align 32768568 %add1 = add nsw i32 %add, %l1.0.l1.0.569 %1 = load volatile i32, ptr %vla, align 4, !tbaa !1570 %add2 = add nsw i32 %add1, %1571 ret i32 %add2572}573 574; CHECK-LABEL: vla_dynamicrealign_nocall_large_align575; Check that used callee-saved registers are saved576; CHECK: stp x29, x30, [sp, #-32]!577; CHECK: str x19, [sp, #16]578; Check that the frame pointer is created:579; CHECK: mov x29, sp580; Check that the stack pointer gets re-aligned to 128581; bytes & the base pointer (x19) gets initialized to582; this 128-byte aligned area for local variables &583; spill slots584; CHECK: sub x9, sp, #7, lsl #12585; CHECK: and sp, x9, #0xffffffffffff8000586; CHECK: mov x19, sp587; Check correct reservation of 16-byte aligned VLA (size in w0) on stack588; and set-up of base pointer (x19).589; CHECK: ubfiz x8, x0, #2, #32590; Check correct access to arguments passed on the stack, through frame pointer591; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40]592; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56]593; CHECK: add x8, x8, #15594; CHECK: and x8, x8, #0x7fffffff0595; CHECK: mov x10, sp596; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x8597; CHECK: mov sp, x[[VLASPTMP]]598; Check correct access to local variable, through base pointer599; 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, x29604; CHECK: ldr x19, [sp, #16]605; CHECK: ldp x29, x30, [sp], #32606; CHECK: ret607 608; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align:609; Check that used callee-saved registers are saved610; 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, #16614; Check that the stack pointer gets re-aligned to 128615; bytes & the base pointer (x19) gets initialized to616; this 128-byte aligned area for local variables &617; spill slots618; CHECK-MACHO: sub x9, sp, #7, lsl #12619; CHECK-MACHO: and sp, x9, #0xffffffffffff8000620; CHECK-MACHO: mov x19, sp621; Check correct reservation of 16-byte aligned VLA (size in w0) on stack622; and set-up of base pointer (x19).623; CHECK-MACHO: ubfiz x8, x0, #2, #32624; Check correct access to arguments passed on the stack, through frame pointer625; 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, #15628; CHECK-MACHO: and x8, x8, #0x7fffffff0629; CHECK-MACHO: mov x10, sp630; CHECK-MACHO: sub x[[VLASPTMP:[0-9]+]], x10, x8631; CHECK-MACHO: mov sp, x[[VLASPTMP]]632; Check correct access to local variable, through base pointer633; 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, #16638; CHECK-MACHO: ldp x29, x30, [sp, #16]639; CHECK-MACHO: ldp x20, x19, [sp], #32640; CHECK-MACHO: ret641 642declare void @use(ptr)643 644define void @realign_conditional(i1 %b, ptr %p) {645entry:646 br i1 %b, label %bb0, label %bb1647 648bb0:649 %MyAlloca = alloca i8, i64 64, align 32650 store ptr %MyAlloca, ptr %p651 br label %bb1652 653bb1:654 ret void655}656 657; CHECK-LABEL: realign_conditional658; No realignment in the prologue.659; CHECK-NOT: and660; CHECK-NOT: 0xffffffffffffffe0661; CHECK: tbz {{.*}} .[[LABEL:.*]]662; Stack is realigned in a non-entry BB.663; CHECK: sub [[REG:x[01-9]+]], sp, #64664; CHECK: and [[REG]], [[REG]], #0xffffffffffffffe0665; CHECK: mov sp, [[REG]]666; CHECK: .[[LABEL]]:667; CHECK: ret668 669 670define void @realign_conditional2(i1 %b, ptr %p) {671entry:672 %tmp = alloca i8, i32 16673 br i1 %b, label %bb0, label %bb1674 675bb0:676 %MyAlloca = alloca i8, i64 64, align 32677 store ptr %MyAlloca, ptr %p678 br label %bb1679 680bb1:681 ret void682}683 684; CHECK-LABEL: realign_conditional2685; Extra realignment in the prologue (performance issue).686; CHECK: tbz {{.*}} .[[LABEL:.*]]687; CHECK: sub x9, sp, #32688; CHECK: and sp, x9, #0xffffffffffffffe0689; CHECK: mov x19, sp690; Stack is realigned in a non-entry BB.691; CHECK: sub [[REG:x[01-9]+]], sp, #64692; CHECK: and [[REG]], [[REG]], #0xffffffffffffffe0693; CHECK: mov sp, [[REG]]694; CHECK: .[[LABEL]]:695; CHECK: ret696 697attributes #0 = { "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "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" "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