brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 82937cf Raw
225 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; Test high-part i64->i128 multiplications on z13.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s5 6; Check zero-extended multiplication in which only the high part is used.7define i64 @f1(i64 %dummy, i64 %a, i64 %b) {8; CHECK-LABEL: f1:9; CHECK:       # %bb.0:10; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q11; CHECK-NEXT:    mlgr %r2, %r412; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q13; CHECK-NEXT:    br %r1414  %ax = zext i64 %a to i12815  %bx = zext i64 %b to i12816  %mulx = mul i128 %ax, %bx17  %highx = lshr i128 %mulx, 6418  %high = trunc i128 %highx to i6419  ret i64 %high20}21 22; Check sign-extended multiplication in which only the high part is used.23; This needs a rather convoluted sequence.24define i64 @f2(i64 %dummy, i64 %a, i64 %b) {25; CHECK-LABEL: f2:26; CHECK:       # %bb.0:27; CHECK-NEXT:    srag %r1, %r4, 6328; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q29; CHECK-NEXT:    srag %r0, %r3, 6330; CHECK-NEXT:    ngr %r1, %r331; CHECK-NEXT:    mlgr %r2, %r432; CHECK-NEXT:    ngr %r0, %r433; CHECK-NEXT:    agr %r0, %r134; CHECK-NEXT:    sgr %r2, %r035; CHECK-NEXT:    br %r1436  %ax = sext i64 %a to i12837  %bx = sext i64 %b to i12838  %mulx = mul i128 %ax, %bx39  %highx = lshr i128 %mulx, 6440  %high = trunc i128 %highx to i6441  ret i64 %high42}43 44; Check zero-extended multiplication in which only part of the high half45; is used.46define i64 @f3(i64 %dummy, i64 %a, i64 %b) {47; CHECK-LABEL: f3:48; CHECK:       # %bb.0:49; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q50; CHECK-NEXT:    mlgr %r2, %r451; CHECK-NEXT:    srlg %r2, %r2, 352; CHECK-NEXT:    br %r1453  %ax = zext i64 %a to i12854  %bx = zext i64 %b to i12855  %mulx = mul i128 %ax, %bx56  %highx = lshr i128 %mulx, 6757  %high = trunc i128 %highx to i6458  ret i64 %high59}60 61; Check zero-extended multiplication in which the result is split into62; high and low halves.63define i64 @f4(i64 %dummy, i64 %a, i64 %b) {64; CHECK-LABEL: f4:65; CHECK:       # %bb.0:66; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q67; CHECK-NEXT:    mlgr %r2, %r468; CHECK-NEXT:    ogr %r2, %r369; CHECK-NEXT:    br %r1470  %ax = zext i64 %a to i12871  %bx = zext i64 %b to i12872  %mulx = mul i128 %ax, %bx73  %highx = lshr i128 %mulx, 6474  %high = trunc i128 %highx to i6475  %low = trunc i128 %mulx to i6476  %or = or i64 %high, %low77  ret i64 %or78}79 80; Check division by a constant, which should use multiplication instead.81define i64 @f5(i64 %dummy, i64 %a) {82; CHECK-LABEL: f5:83; CHECK:       # %bb.0:84; CHECK-NEXT:    llihf %r0, 178202857085; CHECK-NEXT:    oilf %r0, 59865022386; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q87; CHECK-NEXT:    mlgr %r2, %r088; CHECK-NEXT:    srlg %r2, %r2, 989; CHECK-NEXT:    br %r1490  %res = udiv i64 %a, 123491  ret i64 %res92}93 94; Check MLG with no displacement.95define i64 @f6(i64 %dummy, i64 %a, ptr %src) {96; CHECK-LABEL: f6:97; CHECK:       # %bb.0:98; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q99; CHECK-NEXT:    mlg %r2, 0(%r4)100; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q101; CHECK-NEXT:    br %r14102  %b = load i64, ptr %src103  %ax = zext i64 %a to i128104  %bx = zext i64 %b to i128105  %mulx = mul i128 %ax, %bx106  %highx = lshr i128 %mulx, 64107  %high = trunc i128 %highx to i64108  ret i64 %high109}110 111; Check the high end of the aligned MLG range.112define i64 @f7(i64 %dummy, i64 %a, ptr %src) {113; CHECK-LABEL: f7:114; CHECK:       # %bb.0:115; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q116; CHECK-NEXT:    mlg %r2, 524280(%r4)117; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q118; CHECK-NEXT:    br %r14119  %ptr = getelementptr i64, ptr %src, i64 65535120  %b = load i64, ptr %ptr121  %ax = zext i64 %a to i128122  %bx = zext i64 %b to i128123  %mulx = mul i128 %ax, %bx124  %highx = lshr i128 %mulx, 64125  %high = trunc i128 %highx to i64126  ret i64 %high127}128 129; Check the next doubleword up, which requires separate address logic.130; Other sequences besides this one would be OK.131define i64 @f8(i64 %dummy, i64 %a, ptr %src) {132; CHECK-LABEL: f8:133; CHECK:       # %bb.0:134; CHECK-NEXT:    agfi %r4, 524288135; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q136; CHECK-NEXT:    mlg %r2, 0(%r4)137; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q138; CHECK-NEXT:    br %r14139  %ptr = getelementptr i64, ptr %src, i64 65536140  %b = load i64, ptr %ptr141  %ax = zext i64 %a to i128142  %bx = zext i64 %b to i128143  %mulx = mul i128 %ax, %bx144  %highx = lshr i128 %mulx, 64145  %high = trunc i128 %highx to i64146  ret i64 %high147}148 149; Check the high end of the negative aligned MLG range.150define i64 @f9(i64 %dummy, i64 %a, ptr %src) {151; CHECK-LABEL: f9:152; CHECK:       # %bb.0:153; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q154; CHECK-NEXT:    mlg %r2, -8(%r4)155; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q156; CHECK-NEXT:    br %r14157  %ptr = getelementptr i64, ptr %src, i64 -1158  %b = load i64, ptr %ptr159  %ax = zext i64 %a to i128160  %bx = zext i64 %b to i128161  %mulx = mul i128 %ax, %bx162  %highx = lshr i128 %mulx, 64163  %high = trunc i128 %highx to i64164  ret i64 %high165}166 167; Check the low end of the MLG range.168define i64 @f10(i64 %dummy, i64 %a, ptr %src) {169; CHECK-LABEL: f10:170; CHECK:       # %bb.0:171; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q172; CHECK-NEXT:    mlg %r2, -524288(%r4)173; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q174; CHECK-NEXT:    br %r14175  %ptr = getelementptr i64, ptr %src, i64 -65536176  %b = load i64, ptr %ptr177  %ax = zext i64 %a to i128178  %bx = zext i64 %b to i128179  %mulx = mul i128 %ax, %bx180  %highx = lshr i128 %mulx, 64181  %high = trunc i128 %highx to i64182  ret i64 %high183}184 185; Check the next doubleword down, which needs separate address logic.186; Other sequences besides this one would be OK.187define i64 @f11(ptr %dest, i64 %a, ptr %src) {188; CHECK-LABEL: f11:189; CHECK:       # %bb.0:190; CHECK-NEXT:    agfi %r4, -524296191; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q192; CHECK-NEXT:    mlg %r2, 0(%r4)193; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q194; CHECK-NEXT:    br %r14195  %ptr = getelementptr i64, ptr %src, i64 -65537196  %b = load i64, ptr %ptr197  %ax = zext i64 %a to i128198  %bx = zext i64 %b to i128199  %mulx = mul i128 %ax, %bx200  %highx = lshr i128 %mulx, 64201  %high = trunc i128 %highx to i64202  ret i64 %high203}204 205; Check that MLG allows an index.206define i64 @f12(ptr %dest, i64 %a, i64 %src, i64 %index) {207; CHECK-LABEL: f12:208; CHECK:       # %bb.0:209; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q210; CHECK-NEXT:    mlg %r2, 524287(%r5,%r4)211; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q212; CHECK-NEXT:    br %r14213  %add1 = add i64 %src, %index214  %add2 = add i64 %add1, 524287215  %ptr = inttoptr i64 %add2 to ptr216  %b = load i64, ptr %ptr217  %ax = zext i64 %a to i128218  %bx = zext i64 %b to i128219  %mulx = mul i128 %ax, %bx220  %highx = lshr i128 %mulx, 64221  %high = trunc i128 %highx to i64222  ret i64 %high223}224 225