-
Notifications
You must be signed in to change notification settings - Fork 5.2k
JIT ARM64-SVE: Add saturating decrement/increment by element count #102315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 26 commits
51c328b
286df97
a9f6aaa
a40951f
a43e870
e700111
a6cb5e3
1e6082f
84a5d22
4a9dc8a
5025a8c
b79c21d
ef74d46
999b5e4
e82dc4e
d021f18
9780f7d
646f03c
9c4bec7
cd779d5
c9569fc
38a5614
b66bab7
4414b33
b034ea7
a536c01
1c11ce2
6a3dfea
5cbd267
e7047ae
975eb1e
f6a232e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -255,6 +255,25 @@ void Compiler::getHWIntrinsicImmOps(NamedIntrinsic intrinsic, | |
| imm2Pos = 0; | ||
| break; | ||
|
|
||
| case NI_Sve_SaturatingDecrementBy16BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy32BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy64BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy8BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy16BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy32BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy64BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy8BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy16BitElementCountScalar: | ||
| case NI_Sve_SaturatingDecrementBy32BitElementCountScalar: | ||
| case NI_Sve_SaturatingDecrementBy64BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy16BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy32BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy64BitElementCountScalar: | ||
| assert(sig->numArgs == 3); | ||
| imm1Pos = 1; | ||
| imm2Pos = 0; | ||
kunalspathak marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| break; | ||
|
|
||
| default: | ||
| assert(sig->numArgs > 0); | ||
| imm1Pos = 0; | ||
|
|
@@ -447,6 +466,33 @@ void HWIntrinsicInfo::lookupImmBounds( | |
| immUpperBound = (int)SVE_PATTERN_ALL; | ||
| break; | ||
|
|
||
| case NI_Sve_SaturatingDecrementBy16BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy32BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy64BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy8BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy16BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy32BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy64BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy8BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy16BitElementCountScalar: | ||
| case NI_Sve_SaturatingDecrementBy32BitElementCountScalar: | ||
| case NI_Sve_SaturatingDecrementBy64BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy16BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy32BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy64BitElementCountScalar: | ||
| if (immNumber == 1) | ||
| { | ||
| immLowerBound = 1; | ||
| immUpperBound = 16; | ||
| } | ||
| else | ||
| { | ||
| assert(immNumber == 2); | ||
| immLowerBound = (int)SVE_PATTERN_POW2; | ||
| immUpperBound = (int)SVE_PATTERN_ALL; | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
| unreached(); | ||
| } | ||
|
|
@@ -512,7 +558,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, | |
| return gtNewScalarHWIntrinsicNode(TYP_VOID, intrinsic); | ||
| } | ||
|
|
||
| assert(category != HW_Category_Scalar); | ||
| bool isScalar = (category == HW_Category_Scalar); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we be explicit about this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At this point we've already potentially switched to the scalar variants. So the full assert would be: Which feels excessive. Happy to switch if you still want.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed this by adding a DEBUG only bool.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are not
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for reminding me offline that they are |
||
| assert(!HWIntrinsicInfo::isScalarIsa(HWIntrinsicInfo::lookupIsa(intrinsic))); | ||
|
|
||
| assert(numArgs >= 0); | ||
|
|
@@ -526,6 +572,10 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, | |
| GenTree* op3 = nullptr; | ||
| GenTree* op4 = nullptr; | ||
|
|
||
| #ifdef DEBUG | ||
| bool isValidScalarIntrinsic = false; | ||
| #endif | ||
|
|
||
| switch (intrinsic) | ||
| { | ||
| case NI_Vector64_Abs: | ||
|
|
@@ -2436,6 +2486,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, | |
| CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2); | ||
| var_types argType = TYP_UNKNOWN; | ||
| CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE; | ||
|
|
||
| argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass))); | ||
| op3 = impPopStack().val; | ||
| unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(argClass); | ||
|
|
@@ -2507,12 +2558,68 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, | |
| break; | ||
| } | ||
|
|
||
| case NI_Sve_SaturatingDecrementBy8BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy8BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy16BitElementCountScalar: | ||
| case NI_Sve_SaturatingDecrementBy32BitElementCountScalar: | ||
| case NI_Sve_SaturatingDecrementBy64BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy16BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy32BitElementCountScalar: | ||
| case NI_Sve_SaturatingIncrementBy64BitElementCountScalar: | ||
| #ifdef DEBUG | ||
| isValidScalarIntrinsic = true; | ||
| FALLTHROUGH; | ||
| #endif | ||
| case NI_Sve_SaturatingDecrementBy16BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy32BitElementCount: | ||
| case NI_Sve_SaturatingDecrementBy64BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy16BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy32BitElementCount: | ||
| case NI_Sve_SaturatingIncrementBy64BitElementCount: | ||
|
|
||
| { | ||
| assert(sig->numArgs == 3); | ||
|
|
||
| CORINFO_ARG_LIST_HANDLE arg1 = sig->args; | ||
| CORINFO_ARG_LIST_HANDLE arg2 = info.compCompHnd->getArgNext(arg1); | ||
| CORINFO_ARG_LIST_HANDLE arg3 = info.compCompHnd->getArgNext(arg2); | ||
| var_types argType = TYP_UNKNOWN; | ||
| CORINFO_CLASS_HANDLE argClass = NO_CLASS_HANDLE; | ||
| int immLowerBound = 0; | ||
| int immUpperBound = 0; | ||
|
|
||
| argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg3, &argClass))); | ||
| op3 = getArgForHWIntrinsic(argType, argClass); | ||
| argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass))); | ||
| op2 = getArgForHWIntrinsic(argType, argClass); | ||
| argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg1, &argClass))); | ||
| op1 = impPopStack().val; | ||
|
|
||
| CorInfoType op1BaseJitType = getBaseJitTypeOfSIMDType(argClass); | ||
|
|
||
| assert(HWIntrinsicInfo::isImmOp(intrinsic, op2)); | ||
| HWIntrinsicInfo::lookupImmBounds(intrinsic, simdSize, simdBaseType, 1, &immLowerBound, &immUpperBound); | ||
| op2 = addRangeCheckIfNeeded(intrinsic, op2, (!op2->IsCnsIntOrI()), immLowerBound, immUpperBound); | ||
|
|
||
| assert(HWIntrinsicInfo::isImmOp(intrinsic, op3)); | ||
| HWIntrinsicInfo::lookupImmBounds(intrinsic, simdSize, simdBaseType, 2, &immLowerBound, &immUpperBound); | ||
| op3 = addRangeCheckIfNeeded(intrinsic, op3, (!op3->IsCnsIntOrI()), immLowerBound, immUpperBound); | ||
|
|
||
| retNode = isScalar ? gtNewScalarHWIntrinsicNode(retType, op1, op2, op3, intrinsic) | ||
| : gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize); | ||
|
|
||
| retNode->AsHWIntrinsic()->SetSimdBaseJitType(simdBaseJitType); | ||
| break; | ||
| } | ||
|
|
||
| default: | ||
| { | ||
| return nullptr; | ||
| } | ||
| } | ||
|
|
||
| assert(!isScalar || isValidScalarIntrinsic); | ||
|
|
||
| return retNode; | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.