brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · d7e41fb Raw
220 lines · plain
1; Test saving and restoring of call-saved GPRs.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5; This function should require all GPRs, but no other spill slots.  The caller6; allocates room for the GPR save slots, so we shouldn't need to allocate any7; extra space.8;9; The function only modifies the low 32 bits of each register, which in10; itself would allow STM and LM to be used instead of STMG and LMG.11; However, the ABI defines the offset of each register, so we always12; use the 64-bit form.13;14; Use a different address for the final store, so that we can check that15; %r15 isn't referenced again until after that.16define void @f1(ptr %ptr) {17; CHECK-LABEL: f1:18; CHECK: stmg %r6, %r15, 48(%r15)19; CHECK-NOT: %r1520; CHECK: .cfi_offset %r6, -11221; CHECK: .cfi_offset %r7, -10422; CHECK: .cfi_offset %r8, -9623; CHECK: .cfi_offset %r9, -8824; CHECK: .cfi_offset %r10, -8025; CHECK: .cfi_offset %r11, -7226; CHECK: .cfi_offset %r12, -6427; CHECK: .cfi_offset %r13, -5628; CHECK: .cfi_offset %r14, -4829; CHECK: .cfi_offset %r15, -4030; ...main function body...31; CHECK-NOT: %r1532; CHECK: st {{.*}}, 4(%r2)33; CHECK: lmg %r6, %r15, 48(%r15)34; CHECK: br %r1435  %l0 = load volatile i32, ptr %ptr36  %l1 = load volatile i32, ptr %ptr37  %l3 = load volatile i32, ptr %ptr38  %l4 = load volatile i32, ptr %ptr39  %l5 = load volatile i32, ptr %ptr40  %l6 = load volatile i32, ptr %ptr41  %l7 = load volatile i32, ptr %ptr42  %l8 = load volatile i32, ptr %ptr43  %l9 = load volatile i32, ptr %ptr44  %l10 = load volatile i32, ptr %ptr45  %l11 = load volatile i32, ptr %ptr46  %l12 = load volatile i32, ptr %ptr47  %l13 = load volatile i32, ptr %ptr48  %l14 = load volatile i32, ptr %ptr49  %add0 = add i32 %l0, %l050  %add1 = add i32 %l1, %add051  %add3 = add i32 %l3, %add152  %add4 = add i32 %l4, %add353  %add5 = add i32 %l5, %add454  %add6 = add i32 %l6, %add555  %add7 = add i32 %l7, %add656  %add8 = add i32 %l8, %add757  %add9 = add i32 %l9, %add858  %add10 = add i32 %l10, %add959  %add11 = add i32 %l11, %add1060  %add12 = add i32 %l12, %add1161  %add13 = add i32 %l13, %add1262  %add14 = add i32 %l14, %add1363  store volatile i32 %add0, ptr %ptr64  store volatile i32 %add1, ptr %ptr65  store volatile i32 %add3, ptr %ptr66  store volatile i32 %add4, ptr %ptr67  store volatile i32 %add5, ptr %ptr68  store volatile i32 %add6, ptr %ptr69  store volatile i32 %add7, ptr %ptr70  store volatile i32 %add8, ptr %ptr71  store volatile i32 %add9, ptr %ptr72  store volatile i32 %add10, ptr %ptr73  store volatile i32 %add11, ptr %ptr74  store volatile i32 %add12, ptr %ptr75  store volatile i32 %add13, ptr %ptr76  %final = getelementptr i32, ptr %ptr, i32 177  store volatile i32 %add14, ptr %final78  ret void79}80 81; Like f1, but requires one fewer GPR.  We allocate the call-saved GPRs82; from %r14 down, so that the STMG/LMG sequences aren't any longer than83; they need to be.84define void @f2(ptr %ptr) {85; CHECK-LABEL: f2:86; CHECK: stmg %r7, %r15, 56(%r15)87; CHECK-NOT: %r1588; CHECK: .cfi_offset %r7, -10489; CHECK: .cfi_offset %r8, -9690; CHECK: .cfi_offset %r9, -8891; CHECK: .cfi_offset %r10, -8092; CHECK: .cfi_offset %r11, -7293; CHECK: .cfi_offset %r12, -6494; CHECK: .cfi_offset %r13, -5695; CHECK: .cfi_offset %r14, -4896; CHECK: .cfi_offset %r15, -4097; ...main function body...98; CHECK-NOT: %r1599; CHECK-NOT: %r6100; CHECK: st {{.*}}, 4(%r2)101; CHECK: lmg %r7, %r15, 56(%r15)102; CHECK: br %r14103  %l0 = load volatile i32, ptr %ptr104  %l1 = load volatile i32, ptr %ptr105  %l3 = load volatile i32, ptr %ptr106  %l4 = load volatile i32, ptr %ptr107  %l5 = load volatile i32, ptr %ptr108  %l7 = load volatile i32, ptr %ptr109  %l8 = load volatile i32, ptr %ptr110  %l9 = load volatile i32, ptr %ptr111  %l10 = load volatile i32, ptr %ptr112  %l11 = load volatile i32, ptr %ptr113  %l12 = load volatile i32, ptr %ptr114  %l13 = load volatile i32, ptr %ptr115  %l14 = load volatile i32, ptr %ptr116  %add0 = add i32 %l0, %l0117  %add1 = add i32 %l1, %add0118  %add3 = add i32 %l3, %add1119  %add4 = add i32 %l4, %add3120  %add5 = add i32 %l5, %add4121  %add7 = add i32 %l7, %add5122  %add8 = add i32 %l8, %add7123  %add9 = add i32 %l9, %add8124  %add10 = add i32 %l10, %add9125  %add11 = add i32 %l11, %add10126  %add12 = add i32 %l12, %add11127  %add13 = add i32 %l13, %add12128  %add14 = add i32 %l14, %add13129  store volatile i32 %add0, ptr %ptr130  store volatile i32 %add1, ptr %ptr131  store volatile i32 %add3, ptr %ptr132  store volatile i32 %add4, ptr %ptr133  store volatile i32 %add5, ptr %ptr134  store volatile i32 %add7, ptr %ptr135  store volatile i32 %add8, ptr %ptr136  store volatile i32 %add9, ptr %ptr137  store volatile i32 %add10, ptr %ptr138  store volatile i32 %add11, ptr %ptr139  store volatile i32 %add12, ptr %ptr140  store volatile i32 %add13, ptr %ptr141  %final = getelementptr i32, ptr %ptr, i32 1142  store volatile i32 %add14, ptr %final143  ret void144}145 146; Like f1, but only needs one call-saved GPR, which ought to be %r14.147define void @f3(ptr %ptr) {148; CHECK-LABEL: f3:149; CHECK: stmg %r14, %r15, 112(%r15)150; CHECK-NOT: %r15151; CHECK: .cfi_offset %r14, -48152; CHECK: .cfi_offset %r15, -40153; ...main function body...154; CHECK-NOT: %r15155; CHECK-NOT: %r6156; CHECK-NOT: %r7157; CHECK-NOT: %r8158; CHECK-NOT: %r9159; CHECK-NOT: %r10160; CHECK-NOT: %r11161; CHECK-NOT: %r12162; CHECK-NOT: %r13163; CHECK: st {{.*}}, 4(%r2)164; CHECK: lmg %r14, %r15, 112(%r15)165; CHECK: br %r14166  %l0 = load volatile i32, ptr %ptr167  %l1 = load volatile i32, ptr %ptr168  %l3 = load volatile i32, ptr %ptr169  %l4 = load volatile i32, ptr %ptr170  %l5 = load volatile i32, ptr %ptr171  %l14 = load volatile i32, ptr %ptr172  %add0 = add i32 %l0, %l0173  %add1 = add i32 %l1, %add0174  %add3 = add i32 %l3, %add1175  %add4 = add i32 %l4, %add3176  %add5 = add i32 %l5, %add4177  %add14 = add i32 %l14, %add5178  store volatile i32 %add0, ptr %ptr179  store volatile i32 %add1, ptr %ptr180  store volatile i32 %add3, ptr %ptr181  store volatile i32 %add4, ptr %ptr182  store volatile i32 %add5, ptr %ptr183  %final = getelementptr i32, ptr %ptr, i32 1184  store volatile i32 %add14, ptr %final185  ret void186}187 188; This function should use all call-clobbered GPRs but no call-saved ones.189; It shouldn't need to touch the stack at all.190define void @f4(ptr %ptr) {191; CHECK-LABEL: f4:192; CHECK-NOT: %r15193; CHECK-NOT: %r6194; CHECK-NOT: %r7195; CHECK-NOT: %r8196; CHECK-NOT: %r9197; CHECK-NOT: %r10198; CHECK-NOT: %r11199; CHECK-NOT: %r12200; CHECK-NOT: %r13201; CHECK: br %r14202  %l0 = load volatile i32, ptr %ptr203  %l1 = load volatile i32, ptr %ptr204  %l3 = load volatile i32, ptr %ptr205  %l4 = load volatile i32, ptr %ptr206  %l5 = load volatile i32, ptr %ptr207  %add0 = add i32 %l0, %l0208  %add1 = add i32 %l1, %add0209  %add3 = add i32 %l3, %add1210  %add4 = add i32 %l4, %add3211  %add5 = add i32 %l5, %add4212  store volatile i32 %add0, ptr %ptr213  store volatile i32 %add1, ptr %ptr214  store volatile i32 %add3, ptr %ptr215  store volatile i32 %add4, ptr %ptr216  %final = getelementptr i32, ptr %ptr, i32 1217  store volatile i32 %add5, ptr %final218  ret void219}220