brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · b7d4141 Raw
230 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 z17.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z17 | 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.23define i64 @f2(i64 %dummy, i64 %a, i64 %b) {24; CHECK-LABEL: f2:25; CHECK:       # %bb.0:26; CHECK-NEXT:    mgrk %r2, %r3, %r427; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q28; CHECK-NEXT:    br %r1429  %ax = sext i64 %a to i12830  %bx = sext i64 %b to i12831  %mulx = mul i128 %ax, %bx32  %highx = lshr i128 %mulx, 6433  %high = trunc i128 %highx to i6434  ret i64 %high35}36 37; Check zero-extended multiplication in which only part of the high half38; is used.   FIXME: Should use MLGR as well.39define i64 @f3(i64 %dummy, i64 %a, i64 %b) {40; CHECK-LABEL: f3:41; CHECK:       # %bb.0:42; CHECK-NEXT:    vgbm %v0, 043; CHECK-NEXT:    vgbm %v1, 044; CHECK-NEXT:    vlvgg %v1, %r3, 145; CHECK-NEXT:    vlvgg %v0, %r4, 146; CHECK-NEXT:    vmlq %v0, %v1, %v047; CHECK-NEXT:    vrepib %v1, 6748; CHECK-NEXT:    vsrlb %v0, %v0, %v149; CHECK-NEXT:    vsrl %v0, %v0, %v150; CHECK-NEXT:    vlgvg %r2, %v0, 151; CHECK-NEXT:    br %r1452  %ax = zext i64 %a to i12853  %bx = zext i64 %b to i12854  %mulx = mul i128 %ax, %bx55  %highx = lshr i128 %mulx, 6756  %high = trunc i128 %highx to i6457  ret i64 %high58}59 60; Check zero-extended multiplication in which the result is split into61; high and low halves.   FIXME: Should use MLGR as well.62define i64 @f4(i64 %dummy, i64 %a, i64 %b) {63; CHECK-LABEL: f4:64; CHECK:       # %bb.0:65; CHECK-NEXT:    vgbm %v0, 066; CHECK-NEXT:    vgbm %v1, 067; CHECK-NEXT:    vlvgg %v1, %r3, 168; CHECK-NEXT:    vlvgg %v0, %r4, 169; CHECK-NEXT:    vmlq %v0, %v1, %v070; CHECK-NEXT:    vrepib %v1, 6471; CHECK-NEXT:    vsrlb %v1, %v0, %v172; CHECK-NEXT:    vo %v0, %v1, %v073; CHECK-NEXT:    vlgvg %r2, %v0, 174; CHECK-NEXT:    br %r1475  %ax = zext i64 %a to i12876  %bx = zext i64 %b to i12877  %mulx = mul i128 %ax, %bx78  %highx = lshr i128 %mulx, 6479  %high = trunc i128 %highx to i6480  %low = trunc i128 %mulx to i6481  %or = or i64 %high, %low82  ret i64 %or83}84 85; Check division by a constant, which should use multiplication instead.86define i64 @f5(i64 %dummy, i64 %a) {87; CHECK-LABEL: f5:88; CHECK:       # %bb.0:89; CHECK-NEXT:    llihf %r0, 178202857090; CHECK-NEXT:    oilf %r0, 59865022391; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q92; CHECK-NEXT:    mlgr %r2, %r093; CHECK-NEXT:    srlg %r2, %r2, 994; CHECK-NEXT:    br %r1495  %res = udiv i64 %a, 123496  ret i64 %res97}98 99; Check MLG with no displacement.100define i64 @f6(i64 %dummy, i64 %a, ptr %src) {101; CHECK-LABEL: f6:102; CHECK:       # %bb.0:103; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q104; CHECK-NEXT:    mlg %r2, 0(%r4)105; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q106; CHECK-NEXT:    br %r14107  %b = load i64, ptr %src108  %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 high end of the aligned MLG range.117define i64 @f7(i64 %dummy, i64 %a, ptr %src) {118; CHECK-LABEL: f7:119; CHECK:       # %bb.0:120; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q121; CHECK-NEXT:    mlg %r2, 524280(%r4)122; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q123; CHECK-NEXT:    br %r14124  %ptr = getelementptr i64, ptr %src, i64 65535125  %b = load i64, ptr %ptr126  %ax = zext i64 %a to i128127  %bx = zext i64 %b to i128128  %mulx = mul i128 %ax, %bx129  %highx = lshr i128 %mulx, 64130  %high = trunc i128 %highx to i64131  ret i64 %high132}133 134; Check the next doubleword up, which requires separate address logic.135; Other sequences besides this one would be OK.136define i64 @f8(i64 %dummy, i64 %a, ptr %src) {137; CHECK-LABEL: f8:138; CHECK:       # %bb.0:139; CHECK-NEXT:    agfi %r4, 524288140; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q141; CHECK-NEXT:    mlg %r2, 0(%r4)142; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q143; CHECK-NEXT:    br %r14144  %ptr = getelementptr i64, ptr %src, i64 65536145  %b = load i64, ptr %ptr146  %ax = zext i64 %a to i128147  %bx = zext i64 %b to i128148  %mulx = mul i128 %ax, %bx149  %highx = lshr i128 %mulx, 64150  %high = trunc i128 %highx to i64151  ret i64 %high152}153 154; Check the high end of the negative aligned MLG range.155define i64 @f9(i64 %dummy, i64 %a, ptr %src) {156; CHECK-LABEL: f9:157; CHECK:       # %bb.0:158; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q159; CHECK-NEXT:    mlg %r2, -8(%r4)160; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q161; CHECK-NEXT:    br %r14162  %ptr = getelementptr i64, ptr %src, i64 -1163  %b = load i64, ptr %ptr164  %ax = zext i64 %a to i128165  %bx = zext i64 %b to i128166  %mulx = mul i128 %ax, %bx167  %highx = lshr i128 %mulx, 64168  %high = trunc i128 %highx to i64169  ret i64 %high170}171 172; Check the low end of the MLG range.173define i64 @f10(i64 %dummy, i64 %a, ptr %src) {174; CHECK-LABEL: f10:175; CHECK:       # %bb.0:176; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q177; CHECK-NEXT:    mlg %r2, -524288(%r4)178; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q179; CHECK-NEXT:    br %r14180  %ptr = getelementptr i64, ptr %src, i64 -65536181  %b = load i64, ptr %ptr182  %ax = zext i64 %a to i128183  %bx = zext i64 %b to i128184  %mulx = mul i128 %ax, %bx185  %highx = lshr i128 %mulx, 64186  %high = trunc i128 %highx to i64187  ret i64 %high188}189 190; Check the next doubleword down, which needs separate address logic.191; Other sequences besides this one would be OK.192define i64 @f11(ptr %dest, i64 %a, ptr %src) {193; CHECK-LABEL: f11:194; CHECK:       # %bb.0:195; CHECK-NEXT:    agfi %r4, -524296196; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q197; CHECK-NEXT:    mlg %r2, 0(%r4)198; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q199; CHECK-NEXT:    br %r14200  %ptr = getelementptr i64, ptr %src, i64 -65537201  %b = load i64, ptr %ptr202  %ax = zext i64 %a to i128203  %bx = zext i64 %b to i128204  %mulx = mul i128 %ax, %bx205  %highx = lshr i128 %mulx, 64206  %high = trunc i128 %highx to i64207  ret i64 %high208}209 210; Check that MLG allows an index.211define i64 @f12(ptr %dest, i64 %a, i64 %src, i64 %index) {212; CHECK-LABEL: f12:213; CHECK:       # %bb.0:214; CHECK-NEXT:    # kill: def $r3d killed $r3d def $r2q215; CHECK-NEXT:    mlg %r2, 524287(%r5,%r4)216; CHECK-NEXT:    # kill: def $r2d killed $r2d killed $r2q217; CHECK-NEXT:    br %r14218  %add1 = add i64 %src, %index219  %add2 = add i64 %add1, 524287220  %ptr = inttoptr i64 %add2 to ptr221  %b = load i64, ptr %ptr222  %ax = zext i64 %a to i128223  %bx = zext i64 %b to i128224  %mulx = mul i128 %ax, %bx225  %highx = lshr i128 %mulx, 64226  %high = trunc i128 %highx to i64227  ret i64 %high228}229 230