brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.9 KiB · 5b51a0e Raw
334 lines · plain
1; Test the handling of base + index + 12-bit displacement addresses for2; large frames, in cases where no 20-bit form exists.  The tests here3; assume z10 register 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 10declare void @foo(ptr %ptr1, ptr %ptr2)11 12; This file tests what happens when a displacement is converted from13; being relative to the start of a frame object to being relative to14; the frame itself.  In some cases the test is only possible if two15; objects are allocated.16;17; Rather than rely on a particular order for those objects, the tests18; instead allocate two objects of the same size and apply the test to19; both of them.  For consistency, all tests follow this model, even if20; one object would actually be enough.21 22; First check the highest in-range offset after conversion, which is 409223; for word-addressing instructions like LDEB.24;25; The last in-range doubleword offset is 4088.  Since the frame has two26; emergency spill slots at 160(%r15), the amount that we need to allocate27; in order to put another object at offset 4088 is (4088 - 176) / 4 = 97828; words.29define void @f1(ptr %dst) {30; CHECK-NOFP-LABEL: f1:31; CHECK-NOFP: ldeb {{%f[0-7]}}, 4092(%r15)32; CHECK-NOFP: br %r1433;34; CHECK-FP-LABEL: f1:35; CHECK-FP: ldeb {{%f[0-7]}}, 4092(%r11)36; CHECK-FP: br %r1437  %region1 = alloca [978 x float], align 838  %region2 = alloca [978 x float], align 839  call void @foo(ptr %region1, ptr %region2)40  %ptr1 = getelementptr inbounds [978 x float], ptr %region1, i64 0, i64 141  %ptr2 = getelementptr inbounds [978 x float], ptr %region2, i64 0, i64 142  %float1 = load float, ptr %ptr143  %float2 = load float, ptr %ptr244  %double1 = fpext float %float1 to double45  %double2 = fpext float %float2 to double46  store volatile double %double1, ptr %dst47  store volatile double %double2, ptr %dst48  ret void49}50 51; Test the first out-of-range offset.52define void @f2(ptr %dst) {53; CHECK-NOFP-LABEL: f2:54; CHECK-NOFP: lghi %r1, 409655; CHECK-NOFP: ldeb {{%f[0-7]}}, 0(%r1,%r15)56; CHECK-NOFP: br %r1457;58; CHECK-FP-LABEL: f2:59; CHECK-FP: lghi %r1, 409660; CHECK-FP: ldeb {{%f[0-7]}}, 0(%r1,%r11)61; CHECK-FP: br %r1462  %region1 = alloca [978 x float], align 863  %region2 = alloca [978 x float], align 864  call void @foo(ptr %region1, ptr %region2)65  %ptr1 = getelementptr inbounds [978 x float], ptr %region1, i64 0, i64 266  %ptr2 = getelementptr inbounds [978 x float], ptr %region2, i64 0, i64 267  %float1 = load float, ptr %ptr168  %float2 = load float, ptr %ptr269  %double1 = fpext float %float1 to double70  %double2 = fpext float %float2 to double71  store volatile double %double1, ptr %dst72  store volatile double %double2, ptr %dst73  ret void74}75 76; Test the next offset after that.77define void @f3(ptr %dst) {78; CHECK-NOFP-LABEL: f3:79; CHECK-NOFP: lghi %r1, 409680; CHECK-NOFP: ldeb {{%f[0-7]}}, 4(%r1,%r15)81; CHECK-NOFP: br %r1482;83; CHECK-FP-LABEL: f3:84; CHECK-FP: lghi %r1, 409685; CHECK-FP: ldeb {{%f[0-7]}}, 4(%r1,%r11)86; CHECK-FP: br %r1487  %region1 = alloca [978 x float], align 888  %region2 = alloca [978 x float], align 889  call void @foo(ptr %region1, ptr %region2)90  %ptr1 = getelementptr inbounds [978 x float], ptr %region1, i64 0, i64 391  %ptr2 = getelementptr inbounds [978 x float], ptr %region2, i64 0, i64 392  %float1 = load float, ptr %ptr193  %float2 = load float, ptr %ptr294  %double1 = fpext float %float1 to double95  %double2 = fpext float %float2 to double96  store volatile double %double1, ptr %dst97  store volatile double %double2, ptr %dst98  ret void99}100 101; Add 4096 bytes (1024 words) to the size of each object and repeat.102define void @f4(ptr %dst) {103; CHECK-NOFP-LABEL: f4:104; CHECK-NOFP: lghi %r1, 4096105; CHECK-NOFP: ldeb {{%f[0-7]}}, 4092(%r1,%r15)106; CHECK-NOFP: br %r14107;108; CHECK-FP-LABEL: f4:109; CHECK-FP: lghi %r1, 4096110; CHECK-FP: ldeb {{%f[0-7]}}, 4092(%r1,%r11)111; CHECK-FP: br %r14112  %region1 = alloca [2002 x float], align 8113  %region2 = alloca [2002 x float], align 8114  call void @foo(ptr %region1, ptr %region2)115  %ptr1 = getelementptr inbounds [2002 x float], ptr %region1, i64 0, i64 1116  %ptr2 = getelementptr inbounds [2002 x float], ptr %region2, i64 0, i64 1117  %float1 = load float, ptr %ptr1118  %float2 = load float, ptr %ptr2119  %double1 = fpext float %float1 to double120  %double2 = fpext float %float2 to double121  store volatile double %double1, ptr %dst122  store volatile double %double2, ptr %dst123  ret void124}125 126; ...as above.127define void @f5(ptr %dst) {128; CHECK-NOFP-LABEL: f5:129; CHECK-NOFP: lghi %r1, 8192130; CHECK-NOFP: ldeb {{%f[0-7]}}, 0(%r1,%r15)131; CHECK-NOFP: br %r14132;133; CHECK-FP-LABEL: f5:134; CHECK-FP: lghi %r1, 8192135; CHECK-FP: ldeb {{%f[0-7]}}, 0(%r1,%r11)136; CHECK-FP: br %r14137  %region1 = alloca [2002 x float], align 8138  %region2 = alloca [2002 x float], align 8139  call void @foo(ptr %region1, ptr %region2)140  %ptr1 = getelementptr inbounds [2002 x float], ptr %region1, i64 0, i64 2141  %ptr2 = getelementptr inbounds [2002 x float], ptr %region2, i64 0, i64 2142  %float1 = load float, ptr %ptr1143  %float2 = load float, ptr %ptr2144  %double1 = fpext float %float1 to double145  %double2 = fpext float %float2 to double146  store volatile double %double1, ptr %dst147  store volatile double %double2, ptr %dst148  ret void149}150 151; ...as above.152define void @f6(ptr %dst) {153; CHECK-NOFP-LABEL: f6:154; CHECK-NOFP: lghi %r1, 8192155; CHECK-NOFP: ldeb {{%f[0-7]}}, 4(%r1,%r15)156; CHECK-NOFP: br %r14157;158; CHECK-FP-LABEL: f6:159; CHECK-FP: lghi %r1, 8192160; CHECK-FP: ldeb {{%f[0-7]}}, 4(%r1,%r11)161; CHECK-FP: br %r14162  %region1 = alloca [2002 x float], align 8163  %region2 = alloca [2002 x float], align 8164  call void @foo(ptr %region1, ptr %region2)165  %ptr1 = getelementptr inbounds [2002 x float], ptr %region1, i64 0, i64 3166  %ptr2 = getelementptr inbounds [2002 x float], ptr %region2, i64 0, i64 3167  %float1 = load float, ptr %ptr1168  %float2 = load float, ptr %ptr2169  %double1 = fpext float %float1 to double170  %double2 = fpext float %float2 to double171  store volatile double %double1, ptr %dst172  store volatile double %double2, ptr %dst173  ret void174}175 176; Now try an offset of 4092 from the start of the object, with the object177; being at offset 8192.  This time we need objects of (8192 - 168) / 4 = 2004178; words.179define void @f7(ptr %dst) {180; CHECK-NOFP-LABEL: f7:181; CHECK-NOFP: lghi %r1, 8192182; CHECK-NOFP: ldeb {{%f[0-7]}}, 4092(%r1,%r15)183; CHECK-NOFP: br %r14184;185; CHECK-FP-LABEL: f7:186; CHECK-FP: lghi %r1, 8192187; CHECK-FP: ldeb {{%f[0-7]}}, 4092(%r1,%r11)188; CHECK-FP: br %r14189  %region1 = alloca [2004 x float], align 8190  %region2 = alloca [2004 x float], align 8191  call void @foo(ptr %region1, ptr %region2)192  %ptr1 = getelementptr inbounds [2004 x float], ptr %region1, i64 0, i64 1023193  %ptr2 = getelementptr inbounds [2004 x float], ptr %region2, i64 0, i64 1023194  %float1 = load float, ptr %ptr1195  %float2 = load float, ptr %ptr2196  %double1 = fpext float %float1 to double197  %double2 = fpext float %float2 to double198  store volatile double %double1, ptr %dst199  store volatile double %double2, ptr %dst200  ret void201}202 203; Keep the object-relative offset the same but bump the size of the204; objects by one doubleword.205define void @f8(ptr %dst) {206; CHECK-NOFP-LABEL: f8:207; CHECK-NOFP: lghi %r1, 12288208; CHECK-NOFP: ldeb {{%f[0-7]}}, 4(%r1,%r15)209; CHECK-NOFP: br %r14210;211; CHECK-FP-LABEL: f8:212; CHECK-FP: lghi %r1, 12288213; CHECK-FP: ldeb {{%f[0-7]}}, 4(%r1,%r11)214; CHECK-FP: br %r14215  %region1 = alloca [2006 x float], align 8216  %region2 = alloca [2006 x float], align 8217  call void @foo(ptr %region1, ptr %region2)218  %ptr1 = getelementptr inbounds [2006 x float], ptr %region1, i64 0, i64 1023219  %ptr2 = getelementptr inbounds [2006 x float], ptr %region2, i64 0, i64 1023220  %float1 = load float, ptr %ptr1221  %float2 = load float, ptr %ptr2222  %double1 = fpext float %float1 to double223  %double2 = fpext float %float2 to double224  store volatile double %double1, ptr %dst225  store volatile double %double2, ptr %dst226  ret void227}228 229; Check a case where the original displacement is out of range.  The backend230; should force an LAY from the outset.  We don't yet do any kind of anchor231; optimization, so there should be no offset on the LDEB itself.232define void @f9(ptr %dst) {233; CHECK-NOFP-LABEL: f9:234; CHECK-NOFP: lay %r1, 12296(%r15)235; CHECK-NOFP: ldeb {{%f[0-7]}}, 0(%r1)236; CHECK-NOFP: br %r14237;238; CHECK-FP-LABEL: f9:239; CHECK-FP: lay %r1, 12296(%r11)240; CHECK-FP: ldeb {{%f[0-7]}}, 0(%r1)241; CHECK-FP: br %r14242  %region1 = alloca [2006 x float], align 8243  %region2 = alloca [2006 x float], align 8244  call void @foo(ptr %region1, ptr %region2)245  %ptr1 = getelementptr inbounds [2006 x float], ptr %region1, i64 0, i64 1024246  %ptr2 = getelementptr inbounds [2006 x float], ptr %region2, i64 0, i64 1024247  %float1 = load float, ptr %ptr1248  %float2 = load float, ptr %ptr2249  %double1 = fpext float %float1 to double250  %double2 = fpext float %float2 to double251  store volatile double %double1, ptr %dst252  store volatile double %double2, ptr %dst253  ret void254}255 256; Repeat f2 in a case that needs the emergency spill slots, because all257; call-clobbered and allocated call-saved registers are live.  Note that258; %vptr and %dst are copied to call-saved registers, freeing up %r2 and259; %r3 during the main test.260define void @f10(ptr %vptr, ptr %dst) {261; CHECK-NOFP-LABEL: f10:262; CHECK-NOFP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r15)263; CHECK-NOFP: lghi [[REGISTER]], 4096264; CHECK-NOFP: ldeb {{%f[0-7]}}, 0([[REGISTER]],%r15)265; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15)266; CHECK-NOFP: br %r14267;268; CHECK-FP-LABEL: f10:269; CHECK-FP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r11)270; CHECK-FP: lghi [[REGISTER]], 4096271; CHECK-FP: ldeb {{%f[0-7]}}, 0([[REGISTER]],%r11)272; CHECK-FP: lg [[REGISTER]], [[OFFSET]](%r11)273; CHECK-FP: br %r14274  %region1 = alloca [978 x float], align 8275  %region2 = alloca [978 x float], align 8276  call void @foo(ptr %region1, ptr %region2)277  %ptr1 = getelementptr inbounds [978 x float], ptr %region1, i64 0, i64 2278  %ptr2 = getelementptr inbounds [978 x float], ptr %region2, i64 0, i64 2279  %i0 = load volatile i32, ptr %vptr280  %i1 = load volatile i32, ptr %vptr281  %i2 = load volatile i32, ptr %vptr282  %i3 = load volatile i32, ptr %vptr283  %i4 = load volatile i32, ptr %vptr284  %i5 = load volatile i32, ptr %vptr285  %i14 = load volatile i32, ptr %vptr286  %float1 = load float, ptr %ptr1287  %float2 = load float, ptr %ptr2288  %double1 = fpext float %float1 to double289  %double2 = fpext float %float2 to double290  store volatile double %double1, ptr %dst291  store volatile double %double2, ptr %dst292  store volatile i32 %i0, ptr %vptr293  store volatile i32 %i1, ptr %vptr294  store volatile i32 %i2, ptr %vptr295  store volatile i32 %i3, ptr %vptr296  store volatile i32 %i4, ptr %vptr297  store volatile i32 %i5, ptr %vptr298  store volatile i32 %i14, ptr %vptr299  ret void300}301 302; Repeat f2 in a case where the index register is already occupied.303define void @f11(ptr %dst, i64 %index) {304; CHECK-NOFP-LABEL: f11:305; CHECK-NOFP: lgr [[REGISTER:%r[1-9][0-5]?]], %r3306; CHECK-NOFP: lay %r1, 4096(%r15)307; CHECK-NOFP: ldeb {{%f[0-7]}}, 0([[REGISTER]],%r1)308; CHECK-NOFP: br %r14309;310; CHECK-FP-LABEL: f11:311; CHECK-FP: lgr [[REGISTER:%r[1-9][0-5]?]], %r3312; CHECK-FP: lay %r1, 4096(%r11)313; CHECK-FP: ldeb {{%f[0-7]}}, 0([[REGISTER]],%r1)314; CHECK-FP: br %r14315  %region1 = alloca [978 x float], align 8316  %region2 = alloca [978 x float], align 8317  call void @foo(ptr %region1, ptr %region2)318  %elem1 = getelementptr inbounds [978 x float], ptr %region1, i64 0, i64 2319  %elem2 = getelementptr inbounds [978 x float], ptr %region2, i64 0, i64 2320  %base1 = ptrtoint ptr %elem1 to i64321  %base2 = ptrtoint ptr %elem2 to i64322  %addr1 = add i64 %base1, %index323  %addr2 = add i64 %base2, %index324  %ptr1 = inttoptr i64 %addr1 to ptr325  %ptr2 = inttoptr i64 %addr2 to ptr326  %float1 = load float, ptr %ptr1327  %float2 = load float, ptr %ptr2328  %double1 = fpext float %float1 to double329  %double2 = fpext float %float2 to double330  store volatile double %double1, ptr %dst331  store volatile double %double2, ptr %dst332  ret void333}334