Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6e039a8

Browse files
authored
Optimize Vector128<long> multiplication for arm64 (#104177)
1 parent 51e2597 commit 6e039a8

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

src/coreclr/jit/gentree.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21909,7 +21909,6 @@ GenTree* Compiler::gtNewSimdBinOpNode(
2190921909

2191021910
case GT_MUL:
2191121911
{
21912-
assert(!varTypeIsLong(simdBaseType));
2191321912
GenTree** scalarOp = nullptr;
2191421913

2191521914
if (varTypeIsArithmetic(op1))
@@ -21973,6 +21972,42 @@ GenTree* Compiler::gtNewSimdBinOpNode(
2197321972
break;
2197421973
}
2197521974

21975+
case TYP_LONG:
21976+
case TYP_ULONG:
21977+
{
21978+
if (simdSize == 8)
21979+
{
21980+
// Vector64<long> vec = Vector64.CreateScalar(op1.ToScalar() * op2.ToScalar())
21981+
op1 = gtNewBitCastNode(TYP_LONG, op1);
21982+
op2 = gtNewBitCastNode(TYP_LONG, op2);
21983+
GenTreeOp* mul = gtNewOperNode(GT_MUL, TYP_LONG, op1, op2);
21984+
return gtNewSimdCreateScalarNode(TYP_SIMD8, mul, simdBaseJitType, 8);
21985+
}
21986+
21987+
// Make op1 and op2 multi-use:
21988+
GenTree* op1Dup = fgMakeMultiUse(&op1);
21989+
GenTree* op2Dup = fgMakeMultiUse(&op2);
21990+
21991+
// long left0 = op1.GetElement(0)
21992+
// long right0 = op2.GetElement(0)
21993+
GenTree* left0 = gtNewSimdToScalarNode(TYP_LONG, op1, simdBaseJitType, 16);
21994+
GenTree* right0 =
21995+
scalarOp != nullptr ? op2 : gtNewSimdToScalarNode(TYP_LONG, op2, simdBaseJitType, 16);
21996+
21997+
// long left1 = op1.GetElement(1)
21998+
// long right1 = op2.GetElement(1)
21999+
GenTree* left1 = gtNewSimdGetElementNode(TYP_LONG, op1Dup, gtNewIconNode(1), simdBaseJitType, 16);
22000+
GenTree* right1 = scalarOp != nullptr ? op2Dup
22001+
: gtNewSimdGetElementNode(TYP_LONG, op2Dup, gtNewIconNode(1),
22002+
simdBaseJitType, 16);
22003+
22004+
// Vector128<long> vec = Vector128.Create(left0 * right0, left1 * right1)
22005+
op1 = gtNewOperNode(GT_MUL, TYP_LONG, left0, right0);
22006+
op2 = gtNewOperNode(GT_MUL, TYP_LONG, left1, right1);
22007+
GenTree* vec = gtNewSimdCreateScalarUnsafeNode(type, op1, simdBaseJitType, 16);
22008+
return gtNewSimdWithElementNode(type, vec, gtNewIconNode(1), op2, simdBaseJitType, 16);
22009+
}
22010+
2197622011
default:
2197722012
{
2197822013
unreached();

src/coreclr/jit/hwintrinsicarm64.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,12 +1773,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
17731773
{
17741774
assert(sig->numArgs == 2);
17751775

1776-
if (varTypeIsLong(simdBaseType))
1777-
{
1778-
// TODO-ARM64-CQ: We should support long/ulong multiplication.
1779-
break;
1780-
}
1781-
17821776
CORINFO_ARG_LIST_HANDLE arg1 = sig->args;
17831777
CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1);
17841778
var_types argType = TYP_UNKNOWN;

0 commit comments

Comments
 (0)