272 lines · plain
1; Test the saving and restoring of GPRs in large frames.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5; This is the largest frame size that can use a plain LMG for %r6 and above.6; It is big enough to require two emergency spill slots at 160(%r15),7; so get a frame of size 524232 by allocating (524232 - 176) / 8 = 655078; extra doublewords.9define void @f1(ptr %ptr, i64 %x) {10; CHECK-LABEL: f1:11; CHECK: stmg %r6, %r15, 48(%r15)12; CHECK: .cfi_offset %r6, -11213; CHECK: .cfi_offset %r7, -10414; CHECK: .cfi_offset %r8, -9615; CHECK: .cfi_offset %r9, -8816; CHECK: .cfi_offset %r10, -8017; CHECK: .cfi_offset %r11, -7218; CHECK: .cfi_offset %r12, -6419; CHECK: .cfi_offset %r13, -5620; CHECK: .cfi_offset %r14, -4821; CHECK: .cfi_offset %r15, -4022; CHECK: agfi %r15, -52423223; CHECK: .cfi_def_cfa_offset 52439224; ...main function body...25; CHECK-NOT: ag26; CHECK: lmg %r6, %r15, 524280(%r15)27; CHECK: br %r1428 %l0 = load volatile i32, ptr %ptr29 %l1 = load volatile i32, ptr %ptr30 %l4 = load volatile i32, ptr %ptr31 %l5 = load volatile i32, ptr %ptr32 %l6 = load volatile i32, ptr %ptr33 %l7 = load volatile i32, ptr %ptr34 %l8 = load volatile i32, ptr %ptr35 %l9 = load volatile i32, ptr %ptr36 %l10 = load volatile i32, ptr %ptr37 %l11 = load volatile i32, ptr %ptr38 %l12 = load volatile i32, ptr %ptr39 %l13 = load volatile i32, ptr %ptr40 %l14 = load volatile i32, ptr %ptr41 %add0 = add i32 %l0, %l042 %add1 = add i32 %l1, %add043 %add4 = add i32 %l4, %add144 %add5 = add i32 %l5, %add445 %add6 = add i32 %l6, %add546 %add7 = add i32 %l7, %add647 %add8 = add i32 %l8, %add748 %add9 = add i32 %l9, %add849 %add10 = add i32 %l10, %add950 %add11 = add i32 %l11, %add1051 %add12 = add i32 %l12, %add1152 %add13 = add i32 %l13, %add1253 %add14 = add i32 %l14, %add1354 store volatile i32 %add0, ptr %ptr55 store volatile i32 %add1, ptr %ptr56 store volatile i32 %add4, ptr %ptr57 store volatile i32 %add5, ptr %ptr58 store volatile i32 %add6, ptr %ptr59 store volatile i32 %add7, ptr %ptr60 store volatile i32 %add8, ptr %ptr61 store volatile i32 %add9, ptr %ptr62 store volatile i32 %add10, ptr %ptr63 store volatile i32 %add11, ptr %ptr64 store volatile i32 %add12, ptr %ptr65 store volatile i32 %add13, ptr %ptr66 store volatile i32 %add14, ptr %ptr67 %y = alloca [65507 x i64], align 868 store volatile i64 %x, ptr %y69 ret void70}71 72; This is the largest frame size that can use a plain LMG for %r14 and above73; It is big enough to require two emergency spill slots at 160(%r15),74; so get a frame of size 524168 by allocating (524168 - 176) / 8 = 6549975; extra doublewords.76define void @f2(ptr %ptr, i64 %x) {77; CHECK-LABEL: f2:78; CHECK: stmg %r14, %r15, 112(%r15)79; CHECK: .cfi_offset %r14, -4880; CHECK: .cfi_offset %r15, -4081; CHECK: agfi %r15, -52416882; CHECK: .cfi_def_cfa_offset 52432883; ...main function body...84; CHECK-NOT: ag85; CHECK: lmg %r14, %r15, 524280(%r15)86; CHECK: br %r1487 %l0 = load volatile i32, ptr %ptr88 %l1 = load volatile i32, ptr %ptr89 %l4 = load volatile i32, ptr %ptr90 %l5 = load volatile i32, ptr %ptr91 %l14 = load volatile i32, ptr %ptr92 %add0 = add i32 %l0, %l093 %add1 = add i32 %l1, %add094 %add4 = add i32 %l4, %add195 %add5 = add i32 %l5, %add496 %add14 = add i32 %l14, %add597 store volatile i32 %add0, ptr %ptr98 store volatile i32 %add1, ptr %ptr99 store volatile i32 %add4, ptr %ptr100 store volatile i32 %add5, ptr %ptr101 store volatile i32 %add14, ptr %ptr102 %y = alloca [65499 x i64], align 8103 store volatile i64 %x, ptr %y104 ret void105}106 107; Like f1 but with a frame that is 8 bytes bigger. This is the smallest108; frame size that needs two instructions to perform the final LMG for109; %r6 and above.110define void @f3(ptr %ptr, i64 %x) {111; CHECK-LABEL: f3:112; CHECK: stmg %r6, %r15, 48(%r15)113; CHECK: .cfi_offset %r6, -112114; CHECK: .cfi_offset %r7, -104115; CHECK: .cfi_offset %r8, -96116; CHECK: .cfi_offset %r9, -88117; CHECK: .cfi_offset %r10, -80118; CHECK: .cfi_offset %r11, -72119; CHECK: .cfi_offset %r12, -64120; CHECK: .cfi_offset %r13, -56121; CHECK: .cfi_offset %r14, -48122; CHECK: .cfi_offset %r15, -40123; CHECK: agfi %r15, -524240124; CHECK: .cfi_def_cfa_offset 524400125; ...main function body...126; CHECK: aghi %r15, 8127; CHECK: lmg %r6, %r15, 524280(%r15)128; CHECK: br %r14129 %l0 = load volatile i32, ptr %ptr130 %l1 = load volatile i32, ptr %ptr131 %l4 = load volatile i32, ptr %ptr132 %l5 = load volatile i32, ptr %ptr133 %l6 = load volatile i32, ptr %ptr134 %l7 = load volatile i32, ptr %ptr135 %l8 = load volatile i32, ptr %ptr136 %l9 = load volatile i32, ptr %ptr137 %l10 = load volatile i32, ptr %ptr138 %l11 = load volatile i32, ptr %ptr139 %l12 = load volatile i32, ptr %ptr140 %l13 = load volatile i32, ptr %ptr141 %l14 = load volatile i32, ptr %ptr142 %add0 = add i32 %l0, %l0143 %add1 = add i32 %l1, %add0144 %add4 = add i32 %l4, %add1145 %add5 = add i32 %l5, %add4146 %add6 = add i32 %l6, %add5147 %add7 = add i32 %l7, %add6148 %add8 = add i32 %l8, %add7149 %add9 = add i32 %l9, %add8150 %add10 = add i32 %l10, %add9151 %add11 = add i32 %l11, %add10152 %add12 = add i32 %l12, %add11153 %add13 = add i32 %l13, %add12154 %add14 = add i32 %l14, %add13155 store volatile i32 %add0, ptr %ptr156 store volatile i32 %add1, ptr %ptr157 store volatile i32 %add4, ptr %ptr158 store volatile i32 %add5, ptr %ptr159 store volatile i32 %add6, ptr %ptr160 store volatile i32 %add7, ptr %ptr161 store volatile i32 %add8, ptr %ptr162 store volatile i32 %add9, ptr %ptr163 store volatile i32 %add10, ptr %ptr164 store volatile i32 %add11, ptr %ptr165 store volatile i32 %add12, ptr %ptr166 store volatile i32 %add13, ptr %ptr167 store volatile i32 %add14, ptr %ptr168 %y = alloca [65508 x i64], align 8169 store volatile i64 %x, ptr %y170 ret void171}172 173; Like f2 but with a frame that is 8 bytes bigger. This is the smallest174; frame size that needs two instructions to perform the final LMG for175; %r14 and %r15.176define void @f4(ptr %ptr, i64 %x) {177; CHECK-LABEL: f4:178; CHECK: stmg %r14, %r15, 112(%r15)179; CHECK: .cfi_offset %r14, -48180; CHECK: .cfi_offset %r15, -40181; CHECK: agfi %r15, -524176182; CHECK: .cfi_def_cfa_offset 524336183; ...main function body...184; CHECK: aghi %r15, 8185; CHECK: lmg %r14, %r15, 524280(%r15)186; CHECK: br %r14187 %l0 = load volatile i32, ptr %ptr188 %l1 = load volatile i32, ptr %ptr189 %l4 = load volatile i32, ptr %ptr190 %l5 = load volatile i32, ptr %ptr191 %l14 = load volatile i32, ptr %ptr192 %add0 = add i32 %l0, %l0193 %add1 = add i32 %l1, %add0194 %add4 = add i32 %l4, %add1195 %add5 = add i32 %l5, %add4196 %add14 = add i32 %l14, %add5197 store volatile i32 %add0, ptr %ptr198 store volatile i32 %add1, ptr %ptr199 store volatile i32 %add4, ptr %ptr200 store volatile i32 %add5, ptr %ptr201 store volatile i32 %add14, ptr %ptr202 %y = alloca [65500 x i64], align 8203 store volatile i64 %x, ptr %y204 ret void205}206 207; This is the largest frame size for which the preparatory increment for208; "lmg %r14, %r15, ..." can be done using AGHI.209define void @f5(ptr %ptr, i64 %x) {210; CHECK-LABEL: f5:211; CHECK: stmg %r14, %r15, 112(%r15)212; CHECK: .cfi_offset %r14, -48213; CHECK: .cfi_offset %r15, -40214; CHECK: agfi %r15, -556928215; CHECK: .cfi_def_cfa_offset 557088216; ...main function body...217; CHECK: aghi %r15, 32760218; CHECK: lmg %r14, %r15, 524280(%r15)219; CHECK: br %r14220 %l0 = load volatile i32, ptr %ptr221 %l1 = load volatile i32, ptr %ptr222 %l4 = load volatile i32, ptr %ptr223 %l5 = load volatile i32, ptr %ptr224 %l14 = load volatile i32, ptr %ptr225 %add0 = add i32 %l0, %l0226 %add1 = add i32 %l1, %add0227 %add4 = add i32 %l4, %add1228 %add5 = add i32 %l5, %add4229 %add14 = add i32 %l14, %add5230 store volatile i32 %add0, ptr %ptr231 store volatile i32 %add1, ptr %ptr232 store volatile i32 %add4, ptr %ptr233 store volatile i32 %add5, ptr %ptr234 store volatile i32 %add14, ptr %ptr235 %y = alloca [69594 x i64], align 8236 store volatile i64 %x, ptr %y237 ret void238}239 240; This is the smallest frame size for which the preparatory increment for241; "lmg %r14, %r15, ..." needs to be done using AGFI.242define void @f6(ptr %ptr, i64 %x) {243; CHECK-LABEL: f6:244; CHECK: stmg %r14, %r15, 112(%r15)245; CHECK: .cfi_offset %r14, -48246; CHECK: .cfi_offset %r15, -40247; CHECK: agfi %r15, -556936248; CHECK: .cfi_def_cfa_offset 557096249; ...main function body...250; CHECK: agfi %r15, 32768251; CHECK: lmg %r14, %r15, 524280(%r15)252; CHECK: br %r14253 %l0 = load volatile i32, ptr %ptr254 %l1 = load volatile i32, ptr %ptr255 %l4 = load volatile i32, ptr %ptr256 %l5 = load volatile i32, ptr %ptr257 %l14 = load volatile i32, ptr %ptr258 %add0 = add i32 %l0, %l0259 %add1 = add i32 %l1, %add0260 %add4 = add i32 %l4, %add1261 %add5 = add i32 %l5, %add4262 %add14 = add i32 %l14, %add5263 store volatile i32 %add0, ptr %ptr264 store volatile i32 %add1, ptr %ptr265 store volatile i32 %add4, ptr %ptr266 store volatile i32 %add5, ptr %ptr267 store volatile i32 %add14, ptr %ptr268 %y = alloca [69595 x i64], align 8269 store volatile i64 %x, ptr %y270 ret void271}272