264 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 -O3 -verify-machineinstrs | FileCheck %s3;4; Test stack clash protection probing for static allocas.5 6; Small: one probe.7define i32 @fun0() #0 {8; CHECK-LABEL: fun0:9; CHECK: # %bb.0:10; CHECK-NEXT: aghi %r15, -56011; CHECK-NEXT: .cfi_def_cfa_offset 72012; CHECK-NEXT: cg %r0, 552(%r15)13; CHECK-NEXT: mvhi 552(%r15), 114; CHECK-NEXT: l %r2, 160(%r15)15; CHECK-NEXT: aghi %r15, 56016; CHECK-NEXT: br %r1417 18 %a = alloca i32, i64 10019 %b = getelementptr inbounds i32, ptr %a, i64 9820 store volatile i32 1, ptr %b21 %c = load volatile i32, ptr %a22 ret i32 %c23}24 25; Medium: two probes.26define i32 @fun1() #0 {27; CHECK-LABEL: fun1:28; CHECK: # %bb.0:29; CHECK-NEXT: aghi %r15, -409630; CHECK-NEXT: .cfi_def_cfa_offset 425631; CHECK-NEXT: cg %r0, 4088(%r15)32; CHECK-NEXT: aghi %r15, -408033; CHECK-NEXT: .cfi_def_cfa_offset 833634; CHECK-NEXT: cg %r0, 4072(%r15)35; CHECK-NEXT: mvhi 976(%r15), 136; CHECK-NEXT: l %r2, 176(%r15)37; CHECK-NEXT: aghi %r15, 817638; CHECK-NEXT: br %r1439 40 %a = alloca i32, i64 200041 %b = getelementptr inbounds i32, ptr %a, i64 20042 store volatile i32 1, ptr %b43 %c = load volatile i32, ptr %a44 ret i32 %c45}46 47; Large: Use a loop to allocate and probe in steps.48define i32 @fun2() #0 {49; CHECK-LABEL: fun2:50; CHECK: # %bb.0:51; CHECK-NEXT: lgr %r0, %r1552; CHECK-NEXT: .cfi_def_cfa_register %r053; CHECK-NEXT: agfi %r0, -6963254; CHECK-NEXT: .cfi_def_cfa_offset 6979255; CHECK-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=156; CHECK-NEXT: aghi %r15, -409657; CHECK-NEXT: cg %r0, 4088(%r15)58; CHECK-NEXT: clgrjh %r15, %r0, .LBB2_159; CHECK-NEXT: # %bb.2:60; CHECK-NEXT: .cfi_def_cfa_register %r1561; CHECK-NEXT: aghi %r15, -254462; CHECK-NEXT: .cfi_def_cfa_offset 7233663; CHECK-NEXT: cg %r0, 2536(%r15)64; CHECK-NEXT: lhi %r0, 165; CHECK-NEXT: mvhi 568(%r15), 166; CHECK-NEXT: sty %r0, 28968(%r15)67; CHECK-NEXT: l %r2, 176(%r15)68; CHECK-NEXT: agfi %r15, 7217669; CHECK-NEXT: br %r1470 71 %a = alloca i32, i64 1800072 %b0 = getelementptr inbounds i32, ptr %a, i64 9873 %b1 = getelementptr inbounds i32, ptr %a, i64 719874 store volatile i32 1, ptr %b075 store volatile i32 1, ptr %b176 %c = load volatile i32, ptr %a77 ret i32 %c78}79 80; Ends evenly on the step so no remainder needed.81define void @fun3() #0 {82; CHECK-LABEL: fun3:83; CHECK: # %bb.0: # %entry84; CHECK-NEXT: lgr %r0, %r1585; CHECK-NEXT: .cfi_def_cfa_register %r086; CHECK-NEXT: aghi %r0, -2867287; CHECK-NEXT: .cfi_def_cfa_offset 2883288; CHECK-NEXT: .LBB3_1: # %entry89; CHECK-NEXT: # =>This Inner Loop Header: Depth=190; CHECK-NEXT: aghi %r15, -409691; CHECK-NEXT: cg %r0, 4088(%r15)92; CHECK-NEXT: clgrjh %r15, %r0, .LBB3_193; CHECK-NEXT: # %bb.2: # %entry94; CHECK-NEXT: .cfi_def_cfa_register %r1595; CHECK-NEXT: mvhi 180(%r15), 096; CHECK-NEXT: l %r0, 180(%r15)97; CHECK-NEXT: aghi %r15, 2867298; CHECK-NEXT: br %r1499entry:100 %stack = alloca [7122 x i32], align 4101 %i = alloca i32, align 4102 store volatile i32 0, ptr %i, align 4103 %i.0.i.0.6 = load volatile i32, ptr %i, align 4104 ret void105}106 107; Loop with bigger step.108define void @fun4() #0 "stack-probe-size"="8192" {109; CHECK-LABEL: fun4:110; CHECK: # %bb.0: # %entry111; CHECK-NEXT: lgr %r0, %r15112; CHECK-NEXT: .cfi_def_cfa_register %r0113; CHECK-NEXT: aghi %r0, -24576114; CHECK-NEXT: .cfi_def_cfa_offset 24736115; CHECK-NEXT: .LBB4_1: # %entry116; CHECK-NEXT: # =>This Inner Loop Header: Depth=1117; CHECK-NEXT: aghi %r15, -8192118; CHECK-NEXT: cg %r0, 8184(%r15)119; CHECK-NEXT: clgrjh %r15, %r0, .LBB4_1120; CHECK-NEXT: # %bb.2: # %entry121; CHECK-NEXT: .cfi_def_cfa_register %r15122; CHECK-NEXT: aghi %r15, -7608123; CHECK-NEXT: .cfi_def_cfa_offset 32344124; CHECK-NEXT: cg %r0, 7600(%r15)125; CHECK-NEXT: mvhi 180(%r15), 0126; CHECK-NEXT: l %r0, 180(%r15)127; CHECK-NEXT: aghi %r15, 32184128; CHECK-NEXT: br %r14129entry:130 %stack = alloca [8000 x i32], align 4131 %i = alloca i32, align 4132 store volatile i32 0, ptr %i, align 4133 %i.0.i.0.6 = load volatile i32, ptr %i, align 4134 ret void135}136 137; Probe size should be modulo stack alignment.138define void @fun5() #0 "stack-probe-size"="4100" {139; CHECK-LABEL: fun5:140; CHECK: # %bb.0: # %entry141; CHECK-NEXT: aghi %r15, -4096142; CHECK-NEXT: .cfi_def_cfa_offset 4256143; CHECK-NEXT: cg %r0, 4088(%r15)144; CHECK-NEXT: aghi %r15, -88145; CHECK-NEXT: .cfi_def_cfa_offset 4344146; CHECK-NEXT: cg %r0, 80(%r15)147; CHECK-NEXT: mvhi 180(%r15), 0148; CHECK-NEXT: l %r0, 180(%r15)149; CHECK-NEXT: aghi %r15, 4184150; CHECK-NEXT: br %r14151entry:152 %stack = alloca [1000 x i32], align 4153 %i = alloca i32, align 4154 store volatile i32 0, ptr %i, align 4155 %i.0.i.0.6 = load volatile i32, ptr %i, align 4156 ret void157}158 159; The minimum probe size is the stack alignment.160define void @fun6() #0 "stack-probe-size"="5" {161; CHECK-LABEL: fun6:162; CHECK: # %bb.0: # %entry163; CHECK-NEXT: lgr %r0, %r15164; CHECK-NEXT: .cfi_def_cfa_register %r0165; CHECK-NEXT: aghi %r0, -4184166; CHECK-NEXT: .cfi_def_cfa_offset 4344167; CHECK-NEXT: .LBB6_1: # %entry168; CHECK-NEXT: # =>This Inner Loop Header: Depth=1169; CHECK-NEXT: aghi %r15, -8170; CHECK-NEXT: cg %r0, 0(%r15)171; CHECK-NEXT: clgrjh %r15, %r0, .LBB6_1172; CHECK-NEXT: # %bb.2: # %entry173; CHECK-NEXT: .cfi_def_cfa_register %r15174; CHECK-NEXT: mvhi 180(%r15), 0175; CHECK-NEXT: l %r0, 180(%r15)176; CHECK-NEXT: aghi %r15, 4184177; CHECK-NEXT: br %r14178entry:179 %stack = alloca [1000 x i32], align 4180 %i = alloca i32, align 4181 store volatile i32 0, ptr %i, align 4182 %i.0.i.0.6 = load volatile i32, ptr %i, align 4183 ret void184}185 186; Small with a natural probe (STMG) - needs no extra probe.187define i32 @fun7() #0 {188; CHECK-LABEL: fun7:189; CHECK: # %bb.0:190; CHECK-NEXT: stmg %r14, %r15, 112(%r15)191; CHECK-NEXT: .cfi_offset %r14, -48192; CHECK-NEXT: .cfi_offset %r15, -40193; CHECK-NEXT: aghi %r15, -3976194; CHECK-NEXT: .cfi_def_cfa_offset 4136195; CHECK-NEXT: brasl %r14, foo@PLT196; CHECK-NEXT: st %r2, 568(%r15)197; CHECK-NEXT: l %r2, 176(%r15)198; CHECK-NEXT: lmg %r14, %r15, 4088(%r15)199; CHECK-NEXT: br %r14200 %v = call i32 @foo()201 %a = alloca i32, i64 950202 %b = getelementptr inbounds i32, ptr %a, i64 98203 store volatile i32 %v, ptr %b204 %c = load volatile i32, ptr %a205 ret i32 %c206}207 208; Medium with an STMG - still needs probing.209define i32 @fun8() #0 {210; CHECK-LABEL: fun8:211; CHECK: # %bb.0:212; CHECK-NEXT: stmg %r14, %r15, 112(%r15)213; CHECK-NEXT: .cfi_offset %r14, -48214; CHECK-NEXT: .cfi_offset %r15, -40215; CHECK-NEXT: aghi %r15, -3984216; CHECK-NEXT: .cfi_def_cfa_offset 4144217; CHECK-NEXT: cg %r0, 3976(%r15)218; CHECK-NEXT: brasl %r14, foo@PLT219; CHECK-NEXT: st %r2, 976(%r15)220; CHECK-NEXT: l %r2, 176(%r15)221; CHECK-NEXT: lmg %r14, %r15, 4096(%r15)222; CHECK-NEXT: br %r14223 224 %v = call i32 @foo()225 %a = alloca i32, i64 952226 %b = getelementptr inbounds i32, ptr %a, i64 200227 store volatile i32 %v, ptr %b228 %c = load volatile i32, ptr %a229 ret i32 %c230}231 232define void @fun9() #0 "backchain" {233; CHECK-LABEL: fun9:234; CHECK: # %bb.0: # %entry235; CHECK-NEXT: lgr %r1, %r15236; CHECK-NEXT: lgr %r0, %r15237; CHECK-NEXT: .cfi_def_cfa_register %r0238; CHECK-NEXT: aghi %r0, -28672239; CHECK-NEXT: .cfi_def_cfa_offset 28832240; CHECK-NEXT: .LBB9_1: # %entry241; CHECK-NEXT: # =>This Inner Loop Header: Depth=1242; CHECK-NEXT: aghi %r15, -4096243; CHECK-NEXT: cg %r0, 4088(%r15)244; CHECK-NEXT: clgrjh %r15, %r0, .LBB9_1245; CHECK-NEXT: # %bb.2: # %entry246; CHECK-NEXT: .cfi_def_cfa_register %r15247; CHECK-NEXT: stg %r1, 0(%r15)248; CHECK-NEXT: mvhi 180(%r15), 0249; CHECK-NEXT: l %r0, 180(%r15)250; CHECK-NEXT: aghi %r15, 28672251; CHECK-NEXT: br %r14252entry:253 %stack = alloca [7122 x i32], align 4254 %i = alloca i32, align 4255 store volatile i32 0, ptr %i, align 4256 %i.0.i.0.6 = load volatile i32, ptr %i, align 4257 ret void258}259 260 261declare i32 @foo()262attributes #0 = { "probe-stack"="inline-asm" }263 264