393 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64 < %s -verify-machineinstrs -enable-post-misched=false | FileCheck %s3; RUN: llc -mtriple=aarch64 < %s -verify-machineinstrs -enable-post-misched=false -global-isel | FileCheck %s4 5; Tests for prolog sequences for stack probing, when using a 64KiB stack guard.6 7; 64k bytes is the largest frame we can probe in one go.8define void @static_65536(ptr %out) #0 {9; CHECK-LABEL: static_65536:10; CHECK: // %bb.0: // %entry11; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill12; CHECK-NEXT: .cfi_def_cfa_offset 1613; CHECK-NEXT: .cfi_offset w29, -1614; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =6553615; CHECK-NEXT: .cfi_def_cfa_offset 6555216; CHECK-NEXT: str xzr, [sp]17; CHECK-NEXT: mov x8, sp18; CHECK-NEXT: str x8, [x0]19; CHECK-NEXT: add sp, sp, #16, lsl #12 // =6553620; CHECK-NEXT: .cfi_def_cfa_offset 1621; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload22; CHECK-NEXT: .cfi_def_cfa_offset 023; CHECK-NEXT: .cfi_restore w2924; CHECK-NEXT: ret25entry:26 %v = alloca i8, i64 65536, align 127 store ptr %v, ptr %out, align 828 ret void29}30 31; 64k+16 bytes, still needs just one probe.32define void @static_65552(ptr %out) #0 {33; CHECK-LABEL: static_65552:34; CHECK: // %bb.0: // %entry35; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill36; CHECK-NEXT: .cfi_def_cfa_offset 1637; CHECK-NEXT: .cfi_offset w29, -1638; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =6553639; CHECK-NEXT: .cfi_def_cfa_offset 6555240; CHECK-NEXT: str xzr, [sp], #-1641; CHECK-NEXT: .cfi_def_cfa_offset 6556842; CHECK-NEXT: mov x8, sp43; CHECK-NEXT: str x8, [x0]44; CHECK-NEXT: add sp, sp, #16, lsl #12 // =6553645; CHECK-NEXT: .cfi_def_cfa_offset 3246; CHECK-NEXT: add sp, sp, #1647; CHECK-NEXT: .cfi_def_cfa_offset 1648; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload49; CHECK-NEXT: .cfi_def_cfa_offset 050; CHECK-NEXT: .cfi_restore w2951; CHECK-NEXT: ret52entry:53 %v = alloca i8, i64 65552, align 154 store ptr %v, ptr %out, align 855 ret void56}57 58; 64k+1024 bytes, the largest frame which needs just one probe.59define void @static_66560(ptr %out) #0 {60; CHECK-LABEL: static_66560:61; CHECK: // %bb.0: // %entry62; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill63; CHECK-NEXT: .cfi_def_cfa_offset 1664; CHECK-NEXT: .cfi_offset w29, -1665; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =6553666; CHECK-NEXT: .cfi_def_cfa_offset 6555267; CHECK-NEXT: str xzr, [sp]68; CHECK-NEXT: sub sp, sp, #102469; CHECK-NEXT: .cfi_def_cfa_offset 6657670; CHECK-NEXT: mov x8, sp71; CHECK-NEXT: str x8, [x0]72; CHECK-NEXT: add sp, sp, #16, lsl #12 // =6553673; CHECK-NEXT: .cfi_def_cfa_offset 104074; CHECK-NEXT: add sp, sp, #102475; CHECK-NEXT: .cfi_def_cfa_offset 1676; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload77; CHECK-NEXT: .cfi_def_cfa_offset 078; CHECK-NEXT: .cfi_restore w2979; CHECK-NEXT: ret80entry:81 %v = alloca i8, i64 66560, align 182 store ptr %v, ptr %out, align 883 ret void84}85 86; 64k+1024+16 bytes, the smallest frame which needs two probes.87define void @static_66576(ptr %out) #0 {88; CHECK-LABEL: static_66576:89; CHECK: // %bb.0: // %entry90; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill91; CHECK-NEXT: .cfi_def_cfa_offset 1692; CHECK-NEXT: .cfi_offset w29, -1693; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =6553694; CHECK-NEXT: .cfi_def_cfa_offset 6555295; CHECK-NEXT: str xzr, [sp]96; CHECK-NEXT: sub sp, sp, #104097; CHECK-NEXT: .cfi_def_cfa_offset 6659298; CHECK-NEXT: str xzr, [sp]99; CHECK-NEXT: mov x8, sp100; CHECK-NEXT: str x8, [x0]101; CHECK-NEXT: add sp, sp, #16, lsl #12 // =65536102; CHECK-NEXT: .cfi_def_cfa_offset 1056103; CHECK-NEXT: add sp, sp, #1040104; CHECK-NEXT: .cfi_def_cfa_offset 16105; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload106; CHECK-NEXT: .cfi_def_cfa_offset 0107; CHECK-NEXT: .cfi_restore w29108; CHECK-NEXT: ret109entry:110 %v = alloca i8, i64 66576, align 1111 store ptr %v, ptr %out, align 8112 ret void113}114 115; 2*64k+1024, the largest frame needing two probes.116define void @static_132096(ptr %out) #0 {117; CHECK-LABEL: static_132096:118; CHECK: // %bb.0: // %entry119; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill120; CHECK-NEXT: .cfi_def_cfa_offset 16121; CHECK-NEXT: .cfi_offset w29, -16122; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536123; CHECK-NEXT: .cfi_def_cfa_offset 65552124; CHECK-NEXT: str xzr, [sp]125; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536126; CHECK-NEXT: .cfi_def_cfa_offset 131088127; CHECK-NEXT: str xzr, [sp]128; CHECK-NEXT: sub sp, sp, #1024129; CHECK-NEXT: .cfi_def_cfa_offset 132112130; CHECK-NEXT: mov x8, sp131; CHECK-NEXT: str x8, [x0]132; CHECK-NEXT: add sp, sp, #32, lsl #12 // =131072133; CHECK-NEXT: .cfi_def_cfa_offset 1040134; CHECK-NEXT: add sp, sp, #1024135; CHECK-NEXT: .cfi_def_cfa_offset 16136; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload137; CHECK-NEXT: .cfi_def_cfa_offset 0138; CHECK-NEXT: .cfi_restore w29139; CHECK-NEXT: ret140entry:141 %v = alloca i8, i64 132096, align 1142 store ptr %v, ptr %out, align 8143 ret void144}145 146; 5*64k-16, the largest frame probed without a loop.147define void @static_327664(ptr %out) #0 {148; CHECK-LABEL: static_327664:149; CHECK: // %bb.0: // %entry150; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill151; CHECK-NEXT: .cfi_def_cfa_offset 16152; CHECK-NEXT: .cfi_offset w29, -16153; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536154; CHECK-NEXT: .cfi_def_cfa_offset 65552155; CHECK-NEXT: str xzr, [sp]156; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536157; CHECK-NEXT: .cfi_def_cfa_offset 131088158; CHECK-NEXT: str xzr, [sp]159; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536160; CHECK-NEXT: .cfi_def_cfa_offset 196624161; CHECK-NEXT: str xzr, [sp]162; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536163; CHECK-NEXT: .cfi_def_cfa_offset 262160164; CHECK-NEXT: str xzr, [sp]165; CHECK-NEXT: sub sp, sp, #15, lsl #12 // =61440166; CHECK-NEXT: .cfi_def_cfa_offset 323600167; CHECK-NEXT: sub sp, sp, #4080168; CHECK-NEXT: .cfi_def_cfa_offset 327680169; CHECK-NEXT: str xzr, [sp]170; CHECK-NEXT: mov x8, sp171; CHECK-NEXT: str x8, [x0]172; CHECK-NEXT: add sp, sp, #79, lsl #12 // =323584173; CHECK-NEXT: .cfi_def_cfa_offset 4096174; CHECK-NEXT: add sp, sp, #4080175; CHECK-NEXT: .cfi_def_cfa_offset 16176; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload177; CHECK-NEXT: .cfi_def_cfa_offset 0178; CHECK-NEXT: .cfi_restore w29179; CHECK-NEXT: ret180entry:181 %v = alloca i8, i64 327664, align 1182 store ptr %v, ptr %out, align 8183 ret void184}185 186; 5*64k, smallest frame probed with a loop.187define void @static_327680(ptr %out) #0 {188; CHECK-LABEL: static_327680:189; CHECK: // %bb.0: // %entry190; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill191; CHECK-NEXT: .cfi_def_cfa_offset 16192; CHECK-NEXT: .cfi_offset w29, -16193; CHECK-NEXT: sub x9, sp, #80, lsl #12 // =327680194; CHECK-NEXT: .cfi_def_cfa w9, 327696195; CHECK-NEXT: .LBB6_1: // %entry196; CHECK-NEXT: // =>This Inner Loop Header: Depth=1197; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536198; CHECK-NEXT: str xzr, [sp]199; CHECK-NEXT: cmp sp, x9200; CHECK-NEXT: b.ne .LBB6_1201; CHECK-NEXT: // %bb.2: // %entry202; CHECK-NEXT: .cfi_def_cfa_register wsp203; CHECK-NEXT: mov x8, sp204; CHECK-NEXT: str x8, [x0]205; CHECK-NEXT: add sp, sp, #80, lsl #12 // =327680206; CHECK-NEXT: .cfi_def_cfa_offset 16207; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload208; CHECK-NEXT: .cfi_def_cfa_offset 0209; CHECK-NEXT: .cfi_restore w29210; CHECK-NEXT: ret211entry:212 %v = alloca i8, i64 327680, align 1213 store ptr %v, ptr %out, align 8214 ret void215}216 217; 5*64k+1024, large enough to use a loop, but not a multiple of 64KiB218; so has a reminder, but no extra probe.219define void @static_328704(ptr %out) #0 {220; CHECK-LABEL: static_328704:221; CHECK: // %bb.0: // %entry222; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill223; CHECK-NEXT: .cfi_def_cfa_offset 16224; CHECK-NEXT: .cfi_offset w29, -16225; CHECK-NEXT: sub x9, sp, #80, lsl #12 // =327680226; CHECK-NEXT: .cfi_def_cfa w9, 327696227; CHECK-NEXT: .LBB7_1: // %entry228; CHECK-NEXT: // =>This Inner Loop Header: Depth=1229; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536230; CHECK-NEXT: str xzr, [sp]231; CHECK-NEXT: cmp sp, x9232; CHECK-NEXT: b.ne .LBB7_1233; CHECK-NEXT: // %bb.2: // %entry234; CHECK-NEXT: .cfi_def_cfa_register wsp235; CHECK-NEXT: sub sp, sp, #1024236; CHECK-NEXT: .cfi_def_cfa_offset 328720237; CHECK-NEXT: mov x8, sp238; CHECK-NEXT: str x8, [x0]239; CHECK-NEXT: add sp, sp, #80, lsl #12 // =327680240; CHECK-NEXT: .cfi_def_cfa_offset 1040241; CHECK-NEXT: add sp, sp, #1024242; CHECK-NEXT: .cfi_def_cfa_offset 16243; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload244; CHECK-NEXT: .cfi_def_cfa_offset 0245; CHECK-NEXT: .cfi_restore w29246; CHECK-NEXT: ret247entry:248 %v = alloca i8, i64 328704, align 1249 store ptr %v, ptr %out, align 8250 ret void251}252 253; 5*64k+1040, large enough to use a loop, has a reminder and254; an extra probe.255define void @static_328720(ptr %out) #0 {256; CHECK-LABEL: static_328720:257; CHECK: // %bb.0: // %entry258; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill259; CHECK-NEXT: .cfi_def_cfa_offset 16260; CHECK-NEXT: .cfi_offset w29, -16261; CHECK-NEXT: sub x9, sp, #80, lsl #12 // =327680262; CHECK-NEXT: .cfi_def_cfa w9, 327696263; CHECK-NEXT: .LBB8_1: // %entry264; CHECK-NEXT: // =>This Inner Loop Header: Depth=1265; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536266; CHECK-NEXT: str xzr, [sp]267; CHECK-NEXT: cmp sp, x9268; CHECK-NEXT: b.ne .LBB8_1269; CHECK-NEXT: // %bb.2: // %entry270; CHECK-NEXT: .cfi_def_cfa_register wsp271; CHECK-NEXT: sub sp, sp, #1040272; CHECK-NEXT: .cfi_def_cfa_offset 328736273; CHECK-NEXT: str xzr, [sp]274; CHECK-NEXT: mov x8, sp275; CHECK-NEXT: str x8, [x0]276; CHECK-NEXT: add sp, sp, #80, lsl #12 // =327680277; CHECK-NEXT: .cfi_def_cfa_offset 1056278; CHECK-NEXT: add sp, sp, #1040279; CHECK-NEXT: .cfi_def_cfa_offset 16280; CHECK-NEXT: ldr x29, [sp], #16 // 8-byte Folded Reload281; CHECK-NEXT: .cfi_def_cfa_offset 0282; CHECK-NEXT: .cfi_restore w29283; CHECK-NEXT: ret284entry:285 %v = alloca i8, i64 328720, align 1286 store ptr %v, ptr %out, align 8287 ret void288}289 290; A small allocation, but with a very large alignment requirement. We do this291; by moving SP far enough that a sufficiently-aligned block will exist292; somewhere in the stack frame, so must probe the whole of that larger SP move.293define void @static_16_align_131072(ptr %out) #0 {294; CHECK-LABEL: static_16_align_131072:295; CHECK: // %bb.0: // %entry296; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill297; CHECK-NEXT: .cfi_def_cfa_offset 16298; CHECK-NEXT: mov x29, sp299; CHECK-NEXT: .cfi_def_cfa w29, 16300; CHECK-NEXT: .cfi_offset w30, -8301; CHECK-NEXT: .cfi_offset w29, -16302; CHECK-NEXT: sub x9, sp, #31, lsl #12 // =126976303; CHECK-NEXT: sub x9, x9, #4080304; CHECK-NEXT: and x9, x9, #0xfffffffffffe0000305; CHECK-NEXT: .LBB9_1: // %entry306; CHECK-NEXT: // =>This Inner Loop Header: Depth=1307; CHECK-NEXT: sub sp, sp, #16, lsl #12 // =65536308; CHECK-NEXT: cmp sp, x9309; CHECK-NEXT: b.le .LBB9_3310; CHECK-NEXT: // %bb.2: // %entry311; CHECK-NEXT: // in Loop: Header=BB9_1 Depth=1312; CHECK-NEXT: str xzr, [sp]313; CHECK-NEXT: b .LBB9_1314; CHECK-NEXT: .LBB9_3: // %entry315; CHECK-NEXT: mov sp, x9316; CHECK-NEXT: ldr xzr, [sp]317; CHECK-NEXT: mov x8, sp318; CHECK-NEXT: str x8, [x0]319; CHECK-NEXT: mov sp, x29320; CHECK-NEXT: .cfi_def_cfa wsp, 16321; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload322; CHECK-NEXT: .cfi_def_cfa_offset 0323; CHECK-NEXT: .cfi_restore w30324; CHECK-NEXT: .cfi_restore w29325; CHECK-NEXT: ret326entry:327 %v = alloca i8, i64 16, align 131072328 store ptr %v, ptr %out, align 8329 ret void330}331 332; A small allocation, but with a very large alignment requirement which333; is nevertheless small enough as to not need a loop.334define void @static_16_align_8192(ptr %out) #0 {335; CHECK-LABEL: static_16_align_8192:336; CHECK: // %bb.0: // %entry337; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill338; CHECK-NEXT: .cfi_def_cfa_offset 16339; CHECK-NEXT: mov x29, sp340; CHECK-NEXT: .cfi_def_cfa w29, 16341; CHECK-NEXT: .cfi_offset w30, -8342; CHECK-NEXT: .cfi_offset w29, -16343; CHECK-NEXT: sub x9, sp, #1, lsl #12 // =4096344; CHECK-NEXT: sub x9, x9, #4080345; CHECK-NEXT: and sp, x9, #0xffffffffffffe000346; CHECK-NEXT: str xzr, [sp]347; CHECK-NEXT: mov x8, sp348; CHECK-NEXT: str x8, [x0]349; CHECK-NEXT: mov sp, x29350; CHECK-NEXT: .cfi_def_cfa wsp, 16351; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload352; CHECK-NEXT: .cfi_def_cfa_offset 0353; CHECK-NEXT: .cfi_restore w30354; CHECK-NEXT: .cfi_restore w29355; CHECK-NEXT: ret356entry:357 %v = alloca i8, i64 16, align 8192358 store ptr %v, ptr %out, align 8359 ret void360}361 362; A large allocation with a very large alignment requirement which363; is nevertheless small enough as to not need a loop.364define void @static_32752_align_32k(ptr %out) #0 {365; CHECK-LABEL: static_32752_align_32k:366; CHECK: // %bb.0: // %entry367; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill368; CHECK-NEXT: .cfi_def_cfa_offset 16369; CHECK-NEXT: mov x29, sp370; CHECK-NEXT: .cfi_def_cfa w29, 16371; CHECK-NEXT: .cfi_offset w30, -8372; CHECK-NEXT: .cfi_offset w29, -16373; CHECK-NEXT: sub x9, sp, #7, lsl #12 // =28672374; CHECK-NEXT: sub x9, x9, #4080375; CHECK-NEXT: and sp, x9, #0xffffffffffff8000376; CHECK-NEXT: str xzr, [sp]377; CHECK-NEXT: mov x8, sp378; CHECK-NEXT: str x8, [x0]379; CHECK-NEXT: mov sp, x29380; CHECK-NEXT: .cfi_def_cfa wsp, 16381; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload382; CHECK-NEXT: .cfi_def_cfa_offset 0383; CHECK-NEXT: .cfi_restore w30384; CHECK-NEXT: .cfi_restore w29385; CHECK-NEXT: ret386entry:387 %v = alloca i8, i64 32752, align 32768388 store ptr %v, ptr %out, align 8389 ret void390}391 392attributes #0 = { uwtable(async) "probe-stack"="inline-asm" "stack-probe-size"="65536" "frame-pointer"="none" }393