Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -1112,8 +1112,11 @@ class LinearScan : public LinearScanInterface

static Compiler::fgWalkResult markAddrModeOperandsHelperMD(GenTree* tree, void* p);

// Helper for getKillSetForNode().
// Helpers for getKillSetForNode().
regMaskTP getKillSetForStoreInd(GenTreeStoreInd* tree);
#ifdef FEATURE_HW_INTRINSICS
regMaskTP getKillSetForHWIntrinsic(GenTreeHWIntrinsic* node);
#endif // FEATURE_HW_INTRINSICS

// Return the registers killed by the given tree node.
regMaskTP getKillSetForNode(GenTree* tree);
Expand Down
44 changes: 44 additions & 0 deletions src/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,44 @@ regMaskTP LinearScan::getKillSetForStoreInd(GenTreeStoreInd* tree)
return killMask;
}

#ifdef FEATURE_HW_INTRINSICS
//------------------------------------------------------------------------
// getKillSetForHWIntrinsic: Determine the liveness kill set for a GT_STOREIND node.
// If the GT_STOREIND will generate a write barrier, determine the specific kill
// set required by the case-specific, platform-specific write barrier. If no
// write barrier is required, the kill set will be RBM_NONE.
//
// Arguments:
// tree - the GT_STOREIND node
//
// Return Value: a register mask of the registers killed
//
regMaskTP LinearScan::getKillSetForHWIntrinsic(GenTreeHWIntrinsic* node)
{
regMaskTP killMask = RBM_NONE;
#ifdef _TARGET_XARCH_
switch (node->gtHWIntrinsicId)
{
case NI_SSE2_MaskMove:
// maskmovdqu uses edi as the implicit address register.
// Although it is set as the srcCandidate on the address, if there is also a fixed
// assignment for the definition of the address, resolveConflictingDefAndUse() may
// change the register assignment on the def or use of a tree temp (SDSU) when there
// is a conflict, and the FixedRef on edi won't be sufficient to ensure that another
// Interval will not be allocated there.
// Issue #17674 tracks this.
killMask = RBM_EDI;
break;

default:
// Leave killMask as RBM_NONE
break;
}
#endif // _TARGET_XARCH_
return killMask;
}
#endif // FEATURE_HW_INTRINSICS

//------------------------------------------------------------------------
// getKillSetForNode: Return the registers killed by the given tree node.
//
Expand Down Expand Up @@ -853,6 +891,12 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
break;
#endif // PROFILING_SUPPORTED

#ifdef FEATURE_HW_INTRINSICS
case GT_HWIntrinsic:
killMask = getKillSetForHWIntrinsic(tree->AsHWIntrinsic());
break;
#endif // FEATURE_HW_INTRINSICS

default:
// for all other 'tree->OperGet()' kinds, leave 'killMask' = RBM_NONE
break;
Expand Down