diff options
author | Tanner Gooding <tagoo@outlook.com> | 2021-05-18 13:33:52 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-18 13:33:52 +0300 |
commit | a2b7648d3b23fa00442ebc24a12d255895a0945e (patch) | |
tree | e08a820c93e71977e3fb89b32f0b19e442d2a257 /src/coreclr/jit/lsraarm64.cpp | |
parent | 68ebecbc84197d76f2ab9863e39341dacf99c48f (diff) |
Port SIMDIntrinsicGetItem and SIMDIntrinsicSetItem to be implemented via HWIntrinsics (#52288)
* Port SIMDIntrinsicGetItem and SIMDIntrinsicSetItem to be implemented using SimdAsHWIntrinsic
* Apply suggestions from code review
Co-authored-by: Egor Chesakov <Egor.Chesakov@microsoft.com>
* Resolving mismerge
* Added a comment explaining why we sometimes return and sometimes do containment checks
* Update src/coreclr/jit/lsraarm64.cpp
Co-authored-by: Egor Chesakov <Egor.Chesakov@microsoft.com>
Co-authored-by: Egor Chesakov <Egor.Chesakov@microsoft.com>
Diffstat (limited to 'src/coreclr/jit/lsraarm64.cpp')
-rw-r--r-- | src/coreclr/jit/lsraarm64.cpp | 69 |
1 files changed, 23 insertions, 46 deletions
diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index d7b51ff42bb..223dc906bad 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -809,44 +809,6 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) // No special handling required. break; - case SIMDIntrinsicGetItem: - { - op1 = simdTree->gtGetOp1(); - op2 = simdTree->gtGetOp2(); - - // We have an object and an index, either of which may be contained. - bool setOp2DelayFree = false; - if (!op2->IsCnsIntOrI() && (!op1->isContained() || op1->OperIsLocal())) - { - // If the index is not a constant and the object is not contained or is a local - // we will need a general purpose register to calculate the address - // internal register must not clobber input index - // TODO-Cleanup: An internal register will never clobber a source; this code actually - // ensures that the index (op2) doesn't interfere with the target. - buildInternalIntRegisterDefForNode(simdTree); - setOp2DelayFree = true; - } - srcCount += BuildOperandUses(op1); - if (!op2->isContained()) - { - RefPosition* op2Use = BuildUse(op2); - if (setOp2DelayFree) - { - setDelayFree(op2Use); - } - srcCount++; - } - - if (!op2->IsCnsIntOrI() && (!op1->isContained())) - { - // If vector is not already in memory (contained) and the index is not a constant, - // we will use the SIMD temp location to store the vector. - compiler->getSIMDInitTempVarNum(); - } - buildUses = false; - } - break; - case SIMDIntrinsicSub: case SIMDIntrinsicBitwiseAnd: case SIMDIntrinsicBitwiseOr: @@ -854,10 +816,6 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) // No special handling required. break; - case SIMDIntrinsicSetX: - case SIMDIntrinsicSetY: - case SIMDIntrinsicSetZ: - case SIMDIntrinsicSetW: case SIMDIntrinsicNarrow: { // Op1 will write to dst before Op2 is free @@ -904,10 +862,6 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree) case SIMDIntrinsicCopyToArray: case SIMDIntrinsicCopyToArrayX: case SIMDIntrinsicNone: - case SIMDIntrinsicGetX: - case SIMDIntrinsicGetY: - case SIMDIntrinsicGetZ: - case SIMDIntrinsicGetW: case SIMDIntrinsicHWAccel: case SIMDIntrinsicWiden: case SIMDIntrinsicInvalid: @@ -1202,6 +1156,29 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) } } + if ((intrin.id == NI_Vector64_GetElement) || (intrin.id == NI_Vector128_GetElement)) + { + assert(!op2DelayFree); + + if (!intrin.op2->IsCnsIntOrI() && (!intrin.op1->isContained() || intrin.op1->OperIsLocal())) + { + // If the index is not a constant and the object is not contained or is a local + // we will need a general purpose register to calculate the address + // internal register must not clobber input index + // TODO-Cleanup: An internal register will never clobber a source; this code actually + // ensures that the index (op2) doesn't interfere with the target. + buildInternalIntRegisterDefForNode(intrinsicTree); + op2DelayFree = true; + } + + if (!intrin.op2->IsCnsIntOrI() && !intrin.op1->isContained()) + { + // If the index is not a constant or op1 is in register, + // we will use the SIMD temp location to store the vector. + compiler->getSIMDInitTempVarNum(); + } + } + srcCount += op2DelayFree ? BuildDelayFreeUses(intrin.op2) : BuildOperandUses(intrin.op2); if (intrin.op3 != nullptr) |