brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.5 KiB · b243765 Raw
549 lines · plain
1; Test spilling using MVC.  The tests here assume z10 register pressure,2; without the high words being available.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -verify-machineinstrs | FileCheck %s5 6declare void @foo()7 8@g0 = dso_local global i32 09@g1 = dso_local global i32 110@g2 = dso_local global i32 211@g3 = dso_local global i32 312@g4 = dso_local global i32 413@g5 = dso_local global i32 514@g6 = dso_local global i32 615@g7 = dso_local global i32 716@g8 = dso_local global i32 817@g9 = dso_local global i32 918 19@h0 = dso_local global i64 020@h1 = dso_local global i64 121@h2 = dso_local global i64 222@h3 = dso_local global i64 323@h4 = dso_local global i64 424@h5 = dso_local global i64 525@h6 = dso_local global i64 626@h7 = dso_local global i64 727@h8 = dso_local global i64 828@h9 = dso_local global i64 929 30; This function shouldn't spill anything31define dso_local void @f1(ptr %ptr0) {32; CHECK-LABEL: f1:33; CHECK: stmg34; CHECK: aghi %r15, -16035; CHECK-NOT: %r1536; CHECK: brasl %r14, foo@PLT37; CHECK-NOT: %r1538; CHECK: lmg39; CHECK: br %r1440  %ptr1 = getelementptr i32, ptr %ptr0, i32 241  %ptr2 = getelementptr i32, ptr %ptr0, i32 442  %ptr3 = getelementptr i32, ptr %ptr0, i32 643  %ptr4 = getelementptr i32, ptr %ptr0, i32 844  %ptr5 = getelementptr i32, ptr %ptr0, i32 1045  %ptr6 = getelementptr i32, ptr %ptr0, i32 1246 47  %val0 = load i32, ptr %ptr048  %val1 = load i32, ptr %ptr149  %val2 = load i32, ptr %ptr250  %val3 = load i32, ptr %ptr351  %val4 = load i32, ptr %ptr452  %val5 = load i32, ptr %ptr553  %val6 = load i32, ptr %ptr654 55  call void @foo()56 57  store i32 %val0, ptr %ptr058  store i32 %val1, ptr %ptr159  store i32 %val2, ptr %ptr260  store i32 %val3, ptr %ptr361  store i32 %val4, ptr %ptr462  store i32 %val5, ptr %ptr563  store i32 %val6, ptr %ptr664 65  ret void66}67 68; Test a case where at least one i32 load and at least one i32 store69; need spills.70define dso_local void @f2(ptr %ptr0) {71; CHECK-LABEL: f2:72; CHECK: mvc [[OFFSET1:16[04]]](4,%r15), [[OFFSET2:[0-9]+]]({{%r[0-9]+}})73; CHECK: brasl %r14, foo@PLT74; CHECK: mvc [[OFFSET2]](4,{{%r[0-9]+}}), [[OFFSET1]](%r15)75; CHECK: br %r1476  %ptr1 = getelementptr i32, ptr %ptr0, i64 277  %ptr2 = getelementptr i32, ptr %ptr0, i64 478  %ptr3 = getelementptr i32, ptr %ptr0, i64 679  %ptr4 = getelementptr i32, ptr %ptr0, i64 880  %ptr5 = getelementptr i32, ptr %ptr0, i64 1081  %ptr6 = getelementptr i32, ptr %ptr0, i64 1282  %ptr7 = getelementptr i32, ptr %ptr0, i64 1483  %ptr8 = getelementptr i32, ptr %ptr0, i64 1684 85  %val0 = load i32, ptr %ptr086  %val1 = load i32, ptr %ptr187  %val2 = load i32, ptr %ptr288  %val3 = load i32, ptr %ptr389  %val4 = load i32, ptr %ptr490  %val5 = load i32, ptr %ptr591  %val6 = load i32, ptr %ptr692  %val7 = load i32, ptr %ptr793  %val8 = load i32, ptr %ptr894 95  call void @foo()96 97  store i32 %val0, ptr %ptr098  store i32 %val1, ptr %ptr199  store i32 %val2, ptr %ptr2100  store i32 %val3, ptr %ptr3101  store i32 %val4, ptr %ptr4102  store i32 %val5, ptr %ptr5103  store i32 %val6, ptr %ptr6104  store i32 %val7, ptr %ptr7105  store i32 %val8, ptr %ptr8106 107  ret void108}109 110; Test a case where at least one i64 load and at least one i64 store111; need spills.112define dso_local void @f3(ptr %ptr0) {113; CHECK-LABEL: f3:114; CHECK: mvc 160(8,%r15), [[OFFSET:[0-9]+]]({{%r[0-9]+}})115; CHECK: brasl %r14, foo@PLT116; CHECK: mvc [[OFFSET]](8,{{%r[0-9]+}}), 160(%r15)117; CHECK: br %r14118  %ptr1 = getelementptr i64, ptr %ptr0, i64 2119  %ptr2 = getelementptr i64, ptr %ptr0, i64 4120  %ptr3 = getelementptr i64, ptr %ptr0, i64 6121  %ptr4 = getelementptr i64, ptr %ptr0, i64 8122  %ptr5 = getelementptr i64, ptr %ptr0, i64 10123  %ptr6 = getelementptr i64, ptr %ptr0, i64 12124  %ptr7 = getelementptr i64, ptr %ptr0, i64 14125  %ptr8 = getelementptr i64, ptr %ptr0, i64 16126 127  %val0 = load i64, ptr %ptr0128  %val1 = load i64, ptr %ptr1129  %val2 = load i64, ptr %ptr2130  %val3 = load i64, ptr %ptr3131  %val4 = load i64, ptr %ptr4132  %val5 = load i64, ptr %ptr5133  %val6 = load i64, ptr %ptr6134  %val7 = load i64, ptr %ptr7135  %val8 = load i64, ptr %ptr8136 137  call void @foo()138 139  store i64 %val0, ptr %ptr0140  store i64 %val1, ptr %ptr1141  store i64 %val2, ptr %ptr2142  store i64 %val3, ptr %ptr3143  store i64 %val4, ptr %ptr4144  store i64 %val5, ptr %ptr5145  store i64 %val6, ptr %ptr6146  store i64 %val7, ptr %ptr7147  store i64 %val8, ptr %ptr8148 149  ret void150}151 152 153; Test a case where at least at least one f32 load and at least one f32 store154; need spills.  The 8 call-saved FPRs could be used for 8 of the %vals155; (and are at the time of writing), but it would really be better to use156; MVC for all 10.157define dso_local void @f4(ptr %ptr0) {158; CHECK-LABEL: f4:159; CHECK: mvc [[OFFSET1:16[04]]](4,%r15), [[OFFSET2:[0-9]+]]({{%r[0-9]+}})160; CHECK: brasl %r14, foo@PLT161; CHECK: mvc [[OFFSET2]](4,{{%r[0-9]+}}), [[OFFSET1]](%r15)162; CHECK: br %r14163  %ptr1 = getelementptr float, ptr %ptr0, i64 2164  %ptr2 = getelementptr float, ptr %ptr0, i64 4165  %ptr3 = getelementptr float, ptr %ptr0, i64 6166  %ptr4 = getelementptr float, ptr %ptr0, i64 8167  %ptr5 = getelementptr float, ptr %ptr0, i64 10168  %ptr6 = getelementptr float, ptr %ptr0, i64 12169  %ptr7 = getelementptr float, ptr %ptr0, i64 14170  %ptr8 = getelementptr float, ptr %ptr0, i64 16171  %ptr9 = getelementptr float, ptr %ptr0, i64 18172 173  %val0 = load float, ptr %ptr0174  %val1 = load float, ptr %ptr1175  %val2 = load float, ptr %ptr2176  %val3 = load float, ptr %ptr3177  %val4 = load float, ptr %ptr4178  %val5 = load float, ptr %ptr5179  %val6 = load float, ptr %ptr6180  %val7 = load float, ptr %ptr7181  %val8 = load float, ptr %ptr8182  %val9 = load float, ptr %ptr9183 184  call void @foo()185 186  store float %val0, ptr %ptr0187  store float %val1, ptr %ptr1188  store float %val2, ptr %ptr2189  store float %val3, ptr %ptr3190  store float %val4, ptr %ptr4191  store float %val5, ptr %ptr5192  store float %val6, ptr %ptr6193  store float %val7, ptr %ptr7194  store float %val8, ptr %ptr8195  store float %val9, ptr %ptr9196 197  ret void198}199 200; Similarly for f64.201define dso_local void @f5(ptr %ptr0) {202; CHECK-LABEL: f5:203; CHECK: mvc 160(8,%r15), [[OFFSET:[0-9]+]]({{%r[0-9]+}})204; CHECK: brasl %r14, foo@PLT205; CHECK: mvc [[OFFSET]](8,{{%r[0-9]+}}), 160(%r15)206; CHECK: br %r14207  %ptr1 = getelementptr double, ptr %ptr0, i64 2208  %ptr2 = getelementptr double, ptr %ptr0, i64 4209  %ptr3 = getelementptr double, ptr %ptr0, i64 6210  %ptr4 = getelementptr double, ptr %ptr0, i64 8211  %ptr5 = getelementptr double, ptr %ptr0, i64 10212  %ptr6 = getelementptr double, ptr %ptr0, i64 12213  %ptr7 = getelementptr double, ptr %ptr0, i64 14214  %ptr8 = getelementptr double, ptr %ptr0, i64 16215  %ptr9 = getelementptr double, ptr %ptr0, i64 18216 217  %val0 = load double, ptr %ptr0218  %val1 = load double, ptr %ptr1219  %val2 = load double, ptr %ptr2220  %val3 = load double, ptr %ptr3221  %val4 = load double, ptr %ptr4222  %val5 = load double, ptr %ptr5223  %val6 = load double, ptr %ptr6224  %val7 = load double, ptr %ptr7225  %val8 = load double, ptr %ptr8226  %val9 = load double, ptr %ptr9227 228  call void @foo()229 230  store double %val0, ptr %ptr0231  store double %val1, ptr %ptr1232  store double %val2, ptr %ptr2233  store double %val3, ptr %ptr3234  store double %val4, ptr %ptr4235  store double %val5, ptr %ptr5236  store double %val6, ptr %ptr6237  store double %val7, ptr %ptr7238  store double %val8, ptr %ptr8239  store double %val9, ptr %ptr9240 241  ret void242}243 244; Repeat f2 with atomic accesses.  We shouldn't use MVC here.245define dso_local void @f6(ptr %ptr0) {246; CHECK-LABEL: f6:247; CHECK-NOT: mvc248; CHECK: br %r14249  %ptr1 = getelementptr i32, ptr %ptr0, i64 2250  %ptr2 = getelementptr i32, ptr %ptr0, i64 4251  %ptr3 = getelementptr i32, ptr %ptr0, i64 6252  %ptr4 = getelementptr i32, ptr %ptr0, i64 8253  %ptr5 = getelementptr i32, ptr %ptr0, i64 10254  %ptr6 = getelementptr i32, ptr %ptr0, i64 12255  %ptr7 = getelementptr i32, ptr %ptr0, i64 14256  %ptr8 = getelementptr i32, ptr %ptr0, i64 16257 258  %val0 = load atomic i32, ptr %ptr0 unordered, align 4259  %val1 = load atomic i32, ptr %ptr1 unordered, align 4260  %val2 = load atomic i32, ptr %ptr2 unordered, align 4261  %val3 = load atomic i32, ptr %ptr3 unordered, align 4262  %val4 = load atomic i32, ptr %ptr4 unordered, align 4263  %val5 = load atomic i32, ptr %ptr5 unordered, align 4264  %val6 = load atomic i32, ptr %ptr6 unordered, align 4265  %val7 = load atomic i32, ptr %ptr7 unordered, align 4266  %val8 = load atomic i32, ptr %ptr8 unordered, align 4267 268  call void @foo()269 270  store atomic i32 %val0, ptr %ptr0 unordered, align 4271  store atomic i32 %val1, ptr %ptr1 unordered, align 4272  store atomic i32 %val2, ptr %ptr2 unordered, align 4273  store atomic i32 %val3, ptr %ptr3 unordered, align 4274  store atomic i32 %val4, ptr %ptr4 unordered, align 4275  store atomic i32 %val5, ptr %ptr5 unordered, align 4276  store atomic i32 %val6, ptr %ptr6 unordered, align 4277  store atomic i32 %val7, ptr %ptr7 unordered, align 4278  store atomic i32 %val8, ptr %ptr8 unordered, align 4279 280  ret void281}282 283; ...likewise volatile accesses.284define dso_local void @f7(ptr %ptr0) {285; CHECK-LABEL: f7:286; CHECK-NOT: mvc287; CHECK: br %r14288  %ptr1 = getelementptr i32, ptr %ptr0, i64 2289  %ptr2 = getelementptr i32, ptr %ptr0, i64 4290  %ptr3 = getelementptr i32, ptr %ptr0, i64 6291  %ptr4 = getelementptr i32, ptr %ptr0, i64 8292  %ptr5 = getelementptr i32, ptr %ptr0, i64 10293  %ptr6 = getelementptr i32, ptr %ptr0, i64 12294  %ptr7 = getelementptr i32, ptr %ptr0, i64 14295  %ptr8 = getelementptr i32, ptr %ptr0, i64 16296 297  %val0 = load volatile i32, ptr %ptr0298  %val1 = load volatile i32, ptr %ptr1299  %val2 = load volatile i32, ptr %ptr2300  %val3 = load volatile i32, ptr %ptr3301  %val4 = load volatile i32, ptr %ptr4302  %val5 = load volatile i32, ptr %ptr5303  %val6 = load volatile i32, ptr %ptr6304  %val7 = load volatile i32, ptr %ptr7305  %val8 = load volatile i32, ptr %ptr8306 307  call void @foo()308 309  store volatile i32 %val0, ptr %ptr0310  store volatile i32 %val1, ptr %ptr1311  store volatile i32 %val2, ptr %ptr2312  store volatile i32 %val3, ptr %ptr3313  store volatile i32 %val4, ptr %ptr4314  store volatile i32 %val5, ptr %ptr5315  store volatile i32 %val6, ptr %ptr6316  store volatile i32 %val7, ptr %ptr7317  store volatile i32 %val8, ptr %ptr8318 319  ret void320}321 322; Check that LRL and STRL are not converted.323define dso_local void @f8() {324; CHECK-LABEL: f8:325; CHECK-NOT: mvc326; CHECK: br %r14327  %val0 = load i32, ptr@g0328  %val1 = load i32, ptr@g1329  %val2 = load i32, ptr@g2330  %val3 = load i32, ptr@g3331  %val4 = load i32, ptr@g4332  %val5 = load i32, ptr@g5333  %val6 = load i32, ptr@g6334  %val7 = load i32, ptr@g7335  %val8 = load i32, ptr@g8336  %val9 = load i32, ptr@g9337 338  call void @foo()339 340  store i32 %val0, ptr@g0341  store i32 %val1, ptr@g1342  store i32 %val2, ptr@g2343  store i32 %val3, ptr@g3344  store i32 %val4, ptr@g4345  store i32 %val5, ptr@g5346  store i32 %val6, ptr@g6347  store i32 %val7, ptr@g7348  store i32 %val8, ptr@g8349  store i32 %val9, ptr@g9350 351  ret void352}353 354; Likewise LGRL and STGRL.355define dso_local void @f9() {356; CHECK-LABEL: f9:357; CHECK-NOT: mvc358; CHECK: br %r14359  %val0 = load i64, ptr@h0360  %val1 = load i64, ptr@h1361  %val2 = load i64, ptr@h2362  %val3 = load i64, ptr@h3363  %val4 = load i64, ptr@h4364  %val5 = load i64, ptr@h5365  %val6 = load i64, ptr@h6366  %val7 = load i64, ptr@h7367  %val8 = load i64, ptr@h8368  %val9 = load i64, ptr@h9369 370  call void @foo()371 372  store i64 %val0, ptr@h0373  store i64 %val1, ptr@h1374  store i64 %val2, ptr@h2375  store i64 %val3, ptr@h3376  store i64 %val4, ptr@h4377  store i64 %val5, ptr@h5378  store i64 %val6, ptr@h6379  store i64 %val7, ptr@h7380  store i64 %val8, ptr@h8381  store i64 %val9, ptr@h9382 383  ret void384}385 386; This showed a problem with the way stack coloring updated instructions.387; The copy from %val9 to %newval8 can be done using an MVC, which then388; has two frame index operands.  Stack coloring chose a valid renumbering389; [FI0, FI1] -> [FI1, FI2], but applied it in the form FI0 -> FI1 -> FI2,390; so that both operands ended up being the same.391define dso_local void @f10() {392; CHECK-LABEL: f10:393; CHECK: lgrl [[REG:%r[0-9]+]], h9394; CHECK: stg [[REG]], [[VAL9:[0-9]+]](%r15)395; CHECK: brasl %r14, foo@PLT396; CHECK: brasl %r14, foo@PLT397; CHECK: mvc [[NEWVAL8:[0-9]+]](8,%r15), [[VAL9]](%r15)398; CHECK: brasl %r14, foo@PLT399; CHECK: lg [[REG:%r[0-9]+]], [[NEWVAL8]](%r15)400; CHECK: stgrl [[REG]], h8401; CHECK: br %r14402entry:403  %val8 = load volatile i64, ptr@h8404  %val0 = load volatile i64, ptr@h0405  %val1 = load volatile i64, ptr@h1406  %val2 = load volatile i64, ptr@h2407  %val3 = load volatile i64, ptr@h3408  %val4 = load volatile i64, ptr@h4409  %val5 = load volatile i64, ptr@h5410  %val6 = load volatile i64, ptr@h6411  %val7 = load volatile i64, ptr@h7412  %val9 = load volatile i64, ptr@h9413 414  call void @foo()415 416  store volatile i64 %val0, ptr@h0417  store volatile i64 %val1, ptr@h1418  store volatile i64 %val2, ptr@h2419  store volatile i64 %val3, ptr@h3420  store volatile i64 %val4, ptr@h4421  store volatile i64 %val5, ptr@h5422  store volatile i64 %val6, ptr@h6423  store volatile i64 %val7, ptr@h7424 425  %check = load volatile i64, ptr@h0426  %cond = icmp eq i64 %check, 0427  br i1 %cond, label %skip, label %fallthru428 429fallthru:430  call void @foo()431 432  store volatile i64 %val0, ptr@h0433  store volatile i64 %val1, ptr@h1434  store volatile i64 %val2, ptr@h2435  store volatile i64 %val3, ptr@h3436  store volatile i64 %val4, ptr@h4437  store volatile i64 %val5, ptr@h5438  store volatile i64 %val6, ptr@h6439  store volatile i64 %val7, ptr@h7440  store volatile i64 %val8, ptr@h8441  br label %skip442 443skip:444  %newval8 = phi i64 [ %val8, %entry ], [ %val9, %fallthru ]445  call void @foo()446 447  store volatile i64 %val0, ptr@h0448  store volatile i64 %val1, ptr@h1449  store volatile i64 %val2, ptr@h2450  store volatile i64 %val3, ptr@h3451  store volatile i64 %val4, ptr@h4452  store volatile i64 %val5, ptr@h5453  store volatile i64 %val6, ptr@h6454  store volatile i64 %val7, ptr@h7455  store volatile i64 %newval8, ptr@h8456  store volatile i64 %val9, ptr@h9457 458  ret void459}460 461; This used to generate a no-op MVC.  It is very sensitive to spill heuristics.462define dso_local void @f11() {463; CHECK-LABEL: f11:464; CHECK-NOT: mvc [[OFFSET:[0-9]+]](8,%r15), [[OFFSET]](%r15)465; CHECK: br %r14466entry:467  %val0 = load volatile i64, ptr@h0468  %val1 = load volatile i64, ptr@h1469  %val2 = load volatile i64, ptr@h2470  %val3 = load volatile i64, ptr@h3471  %val4 = load volatile i64, ptr@h4472  %val5 = load volatile i64, ptr@h5473  %val6 = load volatile i64, ptr@h6474  %val7 = load volatile i64, ptr@h7475 476  %altval0 = load volatile i64, ptr@h0477  %altval1 = load volatile i64, ptr@h1478 479  call void @foo()480 481  store volatile i64 %val0, ptr@h0482  store volatile i64 %val1, ptr@h1483  store volatile i64 %val2, ptr@h2484  store volatile i64 %val3, ptr@h3485  store volatile i64 %val4, ptr@h4486  store volatile i64 %val5, ptr@h5487  store volatile i64 %val6, ptr@h6488  store volatile i64 %val7, ptr@h7489 490  %check = load volatile i64, ptr@h0491  %cond = icmp eq i64 %check, 0492  br i1 %cond, label %a1, label %b1493 494a1:495  call void @foo()496  br label %join1497 498b1:499  call void @foo()500  br label %join1501 502join1:503  %newval0 = phi i64 [ %val0, %a1 ], [ %altval0, %b1 ]504 505  call void @foo()506 507  store volatile i64 %val1, ptr@h1508  store volatile i64 %val2, ptr@h2509  store volatile i64 %val3, ptr@h3510  store volatile i64 %val4, ptr@h4511  store volatile i64 %val5, ptr@h5512  store volatile i64 %val6, ptr@h6513  store volatile i64 %val7, ptr@h7514  br i1 %cond, label %a2, label %b2515 516a2:517  call void @foo()518  br label %join2519 520b2:521  call void @foo()522  br label %join2523 524join2:525  %newval1 = phi i64 [ %val1, %a2 ], [ %altval1, %b2 ]526 527  call void @foo()528 529  store volatile i64 %val2, ptr@h2530  store volatile i64 %val3, ptr@h3531  store volatile i64 %val4, ptr@h4532  store volatile i64 %val5, ptr@h5533  store volatile i64 %val6, ptr@h6534  store volatile i64 %val7, ptr@h7535 536  call void @foo()537 538  store volatile i64 %newval0, ptr@h0539  store volatile i64 %newval1, ptr@h1540  store volatile i64 %val2, ptr@h2541  store volatile i64 %val3, ptr@h3542  store volatile i64 %val4, ptr@h4543  store volatile i64 %val5, ptr@h5544  store volatile i64 %val6, ptr@h6545  store volatile i64 %val7, ptr@h7546 547  ret void548}549