brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · e5f261f Raw
293 lines · plain
1; Test the handling of base + 12-bit displacement addresses for large frames,2; in cases where no 20-bit form exists.  The tests here assume z10 register3; pressure, without the high words being available.4;5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | \6; RUN:   FileCheck -check-prefix=CHECK-NOFP %s7; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -frame-pointer=all | \8; RUN:   FileCheck -check-prefix=CHECK-FP %s9 10; This file tests what happens when a displacement is converted from11; being relative to the start of a frame object to being relative to12; the frame itself.  In some cases the test is only possible if two13; objects are allocated.14;15; Rather than rely on a particular order for those objects, the tests16; instead allocate two objects of the same size and apply the test to17; both of them.  For consistency, all tests follow this model, even if18; one object would actually be enough.19 20; First check the highest in-range offset after conversion, which is 409221; for word-addressing instructions like MVHI.22;23; The last in-range doubleword offset is 4088.  Since the frame has two24; emergency spill slots at 160(%r15), the amount that we need to allocate25; in order to put another object at offset 4088 is (4088 - 176) / 4 = 97826; words.27define void @f1() {28; CHECK-NOFP-LABEL: f1:29; CHECK-NOFP: mvhi 4092(%r15), 4230; CHECK-NOFP: br %r1431;32; CHECK-FP-LABEL: f1:33; CHECK-FP: mvhi 4092(%r11), 4234; CHECK-FP: br %r1435  %region1 = alloca [978 x i32], align 836  %region2 = alloca [978 x i32], align 837  %ptr1 = getelementptr inbounds [978 x i32], ptr %region1, i64 0, i64 138  %ptr2 = getelementptr inbounds [978 x i32], ptr %region2, i64 0, i64 139  store volatile i32 42, ptr %ptr140  store volatile i32 42, ptr %ptr241  ret void42}43 44; Test the first out-of-range offset.  We cannot use an index register here.45define void @f2() {46; CHECK-NOFP-LABEL: f2:47; CHECK-NOFP: lay %r1, 4096(%r15)48; CHECK-NOFP: mvhi 0(%r1), 4249; CHECK-NOFP: br %r1450;51; CHECK-FP-LABEL: f2:52; CHECK-FP: lay %r1, 4096(%r11)53; CHECK-FP: mvhi 0(%r1), 4254; CHECK-FP: br %r1455  %region1 = alloca [978 x i32], align 856  %region2 = alloca [978 x i32], align 857  %ptr1 = getelementptr inbounds [978 x i32], ptr %region1, i64 0, i64 258  %ptr2 = getelementptr inbounds [978 x i32], ptr %region2, i64 0, i64 259  store volatile i32 42, ptr %ptr160  store volatile i32 42, ptr %ptr261  ret void62}63 64; Test the next offset after that.65define void @f3() {66; CHECK-NOFP-LABEL: f3:67; CHECK-NOFP: lay %r1, 4096(%r15)68; CHECK-NOFP: mvhi 4(%r1), 4269; CHECK-NOFP: br %r1470;71; CHECK-FP-LABEL: f3:72; CHECK-FP: lay %r1, 4096(%r11)73; CHECK-FP: mvhi 4(%r1), 4274; CHECK-FP: br %r1475  %region1 = alloca [978 x i32], align 876  %region2 = alloca [978 x i32], align 877  %ptr1 = getelementptr inbounds [978 x i32], ptr %region1, i64 0, i64 378  %ptr2 = getelementptr inbounds [978 x i32], ptr %region2, i64 0, i64 379  store volatile i32 42, ptr %ptr180  store volatile i32 42, ptr %ptr281  ret void82}83 84; Add 4096 bytes (1024 words) to the size of each object and repeat.85define void @f4() {86; CHECK-NOFP-LABEL: f4:87; CHECK-NOFP: lay %r1, 4096(%r15)88; CHECK-NOFP: mvhi 4092(%r1), 4289; CHECK-NOFP: br %r1490;91; CHECK-FP-LABEL: f4:92; CHECK-FP: lay %r1, 4096(%r11)93; CHECK-FP: mvhi 4092(%r1), 4294; CHECK-FP: br %r1495  %region1 = alloca [2002 x i32], align 896  %region2 = alloca [2002 x i32], align 897  %ptr1 = getelementptr inbounds [2002 x i32], ptr %region1, i64 0, i64 198  %ptr2 = getelementptr inbounds [2002 x i32], ptr %region2, i64 0, i64 199  store volatile i32 42, ptr %ptr1100  store volatile i32 42, ptr %ptr2101  ret void102}103 104; ...as above.105define void @f5() {106; CHECK-NOFP-LABEL: f5:107; CHECK-NOFP: lay %r1, 8192(%r15)108; CHECK-NOFP: mvhi 0(%r1), 42109; CHECK-NOFP: br %r14110;111; CHECK-FP-LABEL: f5:112; CHECK-FP: lay %r1, 8192(%r11)113; CHECK-FP: mvhi 0(%r1), 42114; CHECK-FP: br %r14115  %region1 = alloca [2002 x i32], align 8116  %region2 = alloca [2002 x i32], align 8117  %ptr1 = getelementptr inbounds [2002 x i32], ptr %region1, i64 0, i64 2118  %ptr2 = getelementptr inbounds [2002 x i32], ptr %region2, i64 0, i64 2119  store volatile i32 42, ptr %ptr1120  store volatile i32 42, ptr %ptr2121  ret void122}123 124; ...as above.125define void @f6() {126; CHECK-NOFP-LABEL: f6:127; CHECK-NOFP: lay %r1, 8192(%r15)128; CHECK-NOFP: mvhi 4(%r1), 42129; CHECK-NOFP: br %r14130;131; CHECK-FP-LABEL: f6:132; CHECK-FP: lay %r1, 8192(%r11)133; CHECK-FP: mvhi 4(%r1), 42134; CHECK-FP: br %r14135  %region1 = alloca [2002 x i32], align 8136  %region2 = alloca [2002 x i32], align 8137  %ptr1 = getelementptr inbounds [2002 x i32], ptr %region1, i64 0, i64 3138  %ptr2 = getelementptr inbounds [2002 x i32], ptr %region2, i64 0, i64 3139  store volatile i32 42, ptr %ptr1140  store volatile i32 42, ptr %ptr2141  ret void142}143 144; Now try an offset of 4092 from the start of the object, with the object145; being at offset 8192.  This time we need objects of (8192 - 176) / 4 = 2004146; words.147define void @f7() {148; CHECK-NOFP-LABEL: f7:149; CHECK-NOFP: lay %r1, 8192(%r15)150; CHECK-NOFP: mvhi 4092(%r1), 42151; CHECK-NOFP: br %r14152;153; CHECK-FP-LABEL: f7:154; CHECK-FP: lay %r1, 8192(%r11)155; CHECK-FP: mvhi 4092(%r1), 42156; CHECK-FP: br %r14157  %region1 = alloca [2004 x i32], align 8158  %region2 = alloca [2004 x i32], align 8159  %ptr1 = getelementptr inbounds [2004 x i32], ptr %region1, i64 0, i64 1023160  %ptr2 = getelementptr inbounds [2004 x i32], ptr %region2, i64 0, i64 1023161  store volatile i32 42, ptr %ptr1162  store volatile i32 42, ptr %ptr2163  ret void164}165 166; Keep the object-relative offset the same but bump the size of the167; objects by one doubleword.168define void @f8() {169; CHECK-NOFP-LABEL: f8:170; CHECK-NOFP: lay %r1, 12288(%r15)171; CHECK-NOFP: mvhi 4(%r1), 42172; CHECK-NOFP: br %r14173;174; CHECK-FP-LABEL: f8:175; CHECK-FP: lay %r1, 12288(%r11)176; CHECK-FP: mvhi 4(%r1), 42177; CHECK-FP: br %r14178  %region1 = alloca [2006 x i32], align 8179  %region2 = alloca [2006 x i32], align 8180  %ptr1 = getelementptr inbounds [2006 x i32], ptr %region1, i64 0, i64 1023181  %ptr2 = getelementptr inbounds [2006 x i32], ptr %region2, i64 0, i64 1023182  store volatile i32 42, ptr %ptr1183  store volatile i32 42, ptr %ptr2184  ret void185}186 187; Check a case where the original displacement is out of range.  The backend188; should force STY to be used instead.189define void @f9() {190; CHECK-NOFP-LABEL: f9:191; CHECK-NOFP: lhi [[TMP:%r[0-5]]], 42192; CHECK-NOFP: sty [[TMP]], 12296(%r15)193; CHECK-NOFP: br %r14194;195; CHECK-FP-LABEL: f9:196; CHECK-FP: lhi [[TMP:%r[0-5]]], 42197; CHECK-FP: sty [[TMP]], 12296(%r11)198; CHECK-FP: br %r14199  %region1 = alloca [2006 x i32], align 8200  %region2 = alloca [2006 x i32], align 8201  %ptr1 = getelementptr inbounds [2006 x i32], ptr %region1, i64 0, i64 1024202  %ptr2 = getelementptr inbounds [2006 x i32], ptr %region2, i64 0, i64 1024203  store volatile i32 42, ptr %ptr1204  store volatile i32 42, ptr %ptr2205  ret void206}207 208; Repeat f2 in a case that needs the emergency spill slots (because all209; call-clobbered registers are live and no call-saved ones have been210; allocated).211define void @f10(ptr %vptr) {212; CHECK-NOFP-LABEL: f10:213; CHECK-NOFP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r15)214; CHECK-NOFP: lay [[REGISTER]], 4096(%r15)215; CHECK-NOFP: mvhi 0([[REGISTER]]), 42216; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15)217; CHECK-NOFP: br %r14218;219; CHECK-FP-LABEL: f10:220; CHECK-FP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r11)221; CHECK-FP: lay [[REGISTER]], 4096(%r11)222; CHECK-FP: mvhi 0([[REGISTER]]), 42223; CHECK-FP: lg [[REGISTER]], [[OFFSET]](%r11)224; CHECK-FP: br %r14225  %i0 = load volatile i32, ptr %vptr226  %i1 = load volatile i32, ptr %vptr227  %i3 = load volatile i32, ptr %vptr228  %i4 = load volatile i32, ptr %vptr229  %i5 = load volatile i32, ptr %vptr230  %region1 = alloca [978 x i32], align 8231  %region2 = alloca [978 x i32], align 8232  %ptr1 = getelementptr inbounds [978 x i32], ptr %region1, i64 0, i64 2233  %ptr2 = getelementptr inbounds [978 x i32], ptr %region2, i64 0, i64 2234  store volatile i32 42, ptr %ptr1235  store volatile i32 42, ptr %ptr2236  store volatile i32 %i0, ptr %vptr237  store volatile i32 %i1, ptr %vptr238  store volatile i32 %i3, ptr %vptr239  store volatile i32 %i4, ptr %vptr240  store volatile i32 %i5, ptr %vptr241  ret void242}243 244; And again with maximum register pressure.  The only spill slots that the245; NOFP case needs are the emergency ones, so the offsets are the same as for f2.246; The FP case needs to spill an extra register and is too dependent on247; register allocation heuristics for a stable test.248define void @f11(ptr %vptr) {249; CHECK-NOFP-LABEL: f11:250; CHECK-NOFP: stmg %r6, %r15,251; CHECK-NOFP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r15)252; CHECK-NOFP: lay [[REGISTER]], 4096(%r15)253; CHECK-NOFP: mvhi 0([[REGISTER]]), 42254; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15)255; CHECK-NOFP: lmg %r6, %r15,256; CHECK-NOFP: br %r14257  %i0 = load volatile i32, ptr %vptr258  %i1 = load volatile i32, ptr %vptr259  %i3 = load volatile i32, ptr %vptr260  %i4 = load volatile i32, ptr %vptr261  %i5 = load volatile i32, ptr %vptr262  %i6 = load volatile i32, ptr %vptr263  %i7 = load volatile i32, ptr %vptr264  %i8 = load volatile i32, ptr %vptr265  %i9 = load volatile i32, ptr %vptr266  %i10 = load volatile i32, ptr %vptr267  %i11 = load volatile i32, ptr %vptr268  %i12 = load volatile i32, ptr %vptr269  %i13 = load volatile i32, ptr %vptr270  %i14 = load volatile i32, ptr %vptr271  %region1 = alloca [978 x i32], align 8272  %region2 = alloca [978 x i32], align 8273  %ptr1 = getelementptr inbounds [978 x i32], ptr %region1, i64 0, i64 2274  %ptr2 = getelementptr inbounds [978 x i32], ptr %region2, i64 0, i64 2275  store volatile i32 42, ptr %ptr1276  store volatile i32 42, ptr %ptr2277  store volatile i32 %i0, ptr %vptr278  store volatile i32 %i1, ptr %vptr279  store volatile i32 %i3, ptr %vptr280  store volatile i32 %i4, ptr %vptr281  store volatile i32 %i5, ptr %vptr282  store volatile i32 %i6, ptr %vptr283  store volatile i32 %i7, ptr %vptr284  store volatile i32 %i8, ptr %vptr285  store volatile i32 %i9, ptr %vptr286  store volatile i32 %i10, ptr %vptr287  store volatile i32 %i11, ptr %vptr288  store volatile i32 %i12, ptr %vptr289  store volatile i32 %i13, ptr %vptr290  store volatile i32 %i14, ptr %vptr291  ret void292}293