brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · ca100f2 Raw
270 lines · plain
1; Test high-part i64->i128 multiplications.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -asm-verbose=0 | FileCheck %s4 5declare i64 @foo()6 7; Check zero-extended multiplication in which only the high part is used.8define i64 @f1(i64 %dummy, i64 %a, i64 %b) {9; CHECK-LABEL: f1:10; CHECK-NOT: {{%r[234]}}11; CHECK: mlgr %r2, %r412; CHECK: br %r1413  %ax = zext i64 %a to i12814  %bx = zext i64 %b to i12815  %mulx = mul i128 %ax, %bx16  %highx = lshr i128 %mulx, 6417  %high = trunc i128 %highx to i6418  ret i64 %high19}20 21; Check sign-extended multiplication in which only the high part is used.22; This needs a rather convoluted sequence.23define i64 @f2(i64 %dummy, i64 %a, i64 %b) {24; CHECK-LABEL: f2:25; CHECK-DAG: srag [[RES1:%r[0-5]]], %r3, 6326; CHECK-DAG: srag [[RES2:%r[0-5]]], %r4, 6327; CHECK-DAG: ngr [[RES1]], %r428; CHECK-DAG: ngr [[RES2]], %r329; CHECK-DAG: agr [[RES2]], [[RES1]]30; CHECK-DAG: mlgr %r2, %r431; CHECK: sgr %r2, [[RES2]]32; CHECK: br %r1433  %ax = sext i64 %a to i12834  %bx = sext i64 %b to i12835  %mulx = mul i128 %ax, %bx36  %highx = lshr i128 %mulx, 6437  %high = trunc i128 %highx to i6438  ret i64 %high39}40 41; Check zero-extended multiplication in which only part of the high half42; is used.43define i64 @f3(i64 %dummy, i64 %a, i64 %b) {44; CHECK-LABEL: f3:45; CHECK-NOT: {{%r[234]}}46; CHECK: mlgr %r2, %r447; CHECK: srlg %r2, %r2, 348; CHECK: br %r1449  %ax = zext i64 %a to i12850  %bx = zext i64 %b to i12851  %mulx = mul i128 %ax, %bx52  %highx = lshr i128 %mulx, 6753  %high = trunc i128 %highx to i6454  ret i64 %high55}56 57; Check zero-extended multiplication in which the result is split into58; high and low halves.59define i64 @f4(i64 %dummy, i64 %a, i64 %b) {60; CHECK-LABEL: f4:61; CHECK-NOT: {{%r[234]}}62; CHECK: mlgr %r2, %r463; CHECK: ogr %r3, %r264; CHECK: lgr %r2, %r365; CHECK: br %r1466  %ax = zext i64 %a to i12867  %bx = zext i64 %b to i12868  %mulx = mul i128 %ax, %bx69  %highx = lshr i128 %mulx, 6470  %high = trunc i128 %highx to i6471  %low = trunc i128 %mulx to i6472  %or = or i64 %high, %low73  ret i64 %or74}75 76; Check division by a constant, which should use multiplication instead.77define i64 @f5(i64 %dummy, i64 %a) {78; CHECK-LABEL: f5:79; CHECK: mlgr %r2,80; CHECK: srlg %r2, %r2,81; CHECK: br %r1482  %res = udiv i64 %a, 123483  ret i64 %res84}85 86; Check MLG with no displacement.87define i64 @f6(i64 %dummy, i64 %a, ptr %src) {88; CHECK-LABEL: f6:89; CHECK-NOT: {{%r[234]}}90; CHECK: mlg %r2, 0(%r4)91; CHECK: br %r1492  %b = load i64, ptr %src93  %ax = zext i64 %a to i12894  %bx = zext i64 %b to i12895  %mulx = mul i128 %ax, %bx96  %highx = lshr i128 %mulx, 6497  %high = trunc i128 %highx to i6498  ret i64 %high99}100 101; Check the high end of the aligned MLG range.102define i64 @f7(i64 %dummy, i64 %a, ptr %src) {103; CHECK-LABEL: f7:104; CHECK: mlg %r2, 524280(%r4)105; CHECK: br %r14106  %ptr = getelementptr i64, ptr %src, i64 65535107  %b = load i64, ptr %ptr108  %ax = zext i64 %a to i128109  %bx = zext i64 %b to i128110  %mulx = mul i128 %ax, %bx111  %highx = lshr i128 %mulx, 64112  %high = trunc i128 %highx to i64113  ret i64 %high114}115 116; Check the next doubleword up, which requires separate address logic.117; Other sequences besides this one would be OK.118define i64 @f8(i64 %dummy, i64 %a, ptr %src) {119; CHECK-LABEL: f8:120; CHECK: agfi %r4, 524288121; CHECK: mlg %r2, 0(%r4)122; CHECK: br %r14123  %ptr = getelementptr i64, ptr %src, i64 65536124  %b = load i64, ptr %ptr125  %ax = zext i64 %a to i128126  %bx = zext i64 %b to i128127  %mulx = mul i128 %ax, %bx128  %highx = lshr i128 %mulx, 64129  %high = trunc i128 %highx to i64130  ret i64 %high131}132 133; Check the high end of the negative aligned MLG range.134define i64 @f9(i64 %dummy, i64 %a, ptr %src) {135; CHECK-LABEL: f9:136; CHECK: mlg %r2, -8(%r4)137; CHECK: br %r14138  %ptr = getelementptr i64, ptr %src, i64 -1139  %b = load i64, ptr %ptr140  %ax = zext i64 %a to i128141  %bx = zext i64 %b to i128142  %mulx = mul i128 %ax, %bx143  %highx = lshr i128 %mulx, 64144  %high = trunc i128 %highx to i64145  ret i64 %high146}147 148; Check the low end of the MLG range.149define i64 @f10(i64 %dummy, i64 %a, ptr %src) {150; CHECK-LABEL: f10:151; CHECK: mlg %r2, -524288(%r4)152; CHECK: br %r14153  %ptr = getelementptr i64, ptr %src, i64 -65536154  %b = load i64, ptr %ptr155  %ax = zext i64 %a to i128156  %bx = zext i64 %b to i128157  %mulx = mul i128 %ax, %bx158  %highx = lshr i128 %mulx, 64159  %high = trunc i128 %highx to i64160  ret i64 %high161}162 163; Check the next doubleword down, which needs separate address logic.164; Other sequences besides this one would be OK.165define i64 @f11(ptr %dest, i64 %a, ptr %src) {166; CHECK-LABEL: f11:167; CHECK: agfi %r4, -524296168; CHECK: mlg %r2, 0(%r4)169; CHECK: br %r14170  %ptr = getelementptr i64, ptr %src, i64 -65537171  %b = load i64, ptr %ptr172  %ax = zext i64 %a to i128173  %bx = zext i64 %b to i128174  %mulx = mul i128 %ax, %bx175  %highx = lshr i128 %mulx, 64176  %high = trunc i128 %highx to i64177  ret i64 %high178}179 180; Check that MLG allows an index.181define i64 @f12(ptr %dest, i64 %a, i64 %src, i64 %index) {182; CHECK-LABEL: f12:183; CHECK: mlg %r2, 524287(%r5,%r4)184; CHECK: br %r14185  %add1 = add i64 %src, %index186  %add2 = add i64 %add1, 524287187  %ptr = inttoptr i64 %add2 to ptr188  %b = load i64, ptr %ptr189  %ax = zext i64 %a to i128190  %bx = zext i64 %b to i128191  %mulx = mul i128 %ax, %bx192  %highx = lshr i128 %mulx, 64193  %high = trunc i128 %highx to i64194  ret i64 %high195}196 197; Check that multiplications of spilled values can use MLG rather than MLGR.198define i64 @f13(ptr %ptr0) {199; CHECK-LABEL: f13:200; CHECK: brasl %r14, foo@PLT201; CHECK: mlg {{%r[0-9]+}}, 160(%r15)202; CHECK: br %r14203  %ptr1 = getelementptr i64, ptr %ptr0, i64 2204  %ptr2 = getelementptr i64, ptr %ptr0, i64 4205  %ptr3 = getelementptr i64, ptr %ptr0, i64 6206  %ptr4 = getelementptr i64, ptr %ptr0, i64 8207  %ptr5 = getelementptr i64, ptr %ptr0, i64 10208  %ptr6 = getelementptr i64, ptr %ptr0, i64 12209  %ptr7 = getelementptr i64, ptr %ptr0, i64 14210  %ptr8 = getelementptr i64, ptr %ptr0, i64 16211  %ptr9 = getelementptr i64, ptr %ptr0, i64 18212 213  %val0 = load i64, ptr %ptr0214  %val1 = load i64, ptr %ptr1215  %val2 = load i64, ptr %ptr2216  %val3 = load i64, ptr %ptr3217  %val4 = load i64, ptr %ptr4218  %val5 = load i64, ptr %ptr5219  %val6 = load i64, ptr %ptr6220  %val7 = load i64, ptr %ptr7221  %val8 = load i64, ptr %ptr8222  %val9 = load i64, ptr %ptr9223 224  %ret = call i64 @foo()225 226  %retx = zext i64 %ret to i128227  %val0x = zext i64 %val0 to i128228  %mul0d = mul i128 %retx, %val0x229  %mul0x = lshr i128 %mul0d, 64230 231  %val1x = zext i64 %val1 to i128232  %mul1d = mul i128 %mul0x, %val1x233  %mul1x = lshr i128 %mul1d, 64234 235  %val2x = zext i64 %val2 to i128236  %mul2d = mul i128 %mul1x, %val2x237  %mul2x = lshr i128 %mul2d, 64238 239  %val3x = zext i64 %val3 to i128240  %mul3d = mul i128 %mul2x, %val3x241  %mul3x = lshr i128 %mul3d, 64242 243  %val4x = zext i64 %val4 to i128244  %mul4d = mul i128 %mul3x, %val4x245  %mul4x = lshr i128 %mul4d, 64246 247  %val5x = zext i64 %val5 to i128248  %mul5d = mul i128 %mul4x, %val5x249  %mul5x = lshr i128 %mul5d, 64250 251  %val6x = zext i64 %val6 to i128252  %mul6d = mul i128 %mul5x, %val6x253  %mul6x = lshr i128 %mul6d, 64254 255  %val7x = zext i64 %val7 to i128256  %mul7d = mul i128 %mul6x, %val7x257  %mul7x = lshr i128 %mul7d, 64258 259  %val8x = zext i64 %val8 to i128260  %mul8d = mul i128 %mul7x, %val8x261  %mul8x = lshr i128 %mul8d, 64262 263  %val9x = zext i64 %val9 to i128264  %mul9d = mul i128 %mul8x, %val9x265  %mul9x = lshr i128 %mul9d, 64266 267  %mul9 = trunc i128 %mul9x to i64268  ret i64 %mul9269}270