From 2b04d12bdc62abd3c656931886bc7628ddee87fa Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Fri, 29 Jul 2022 17:57:07 +0300 Subject: [PATCH 1/3] Spilling fixes --- src/coreclr/jit/codegenlinear.cpp | 55 +++---------------- src/coreclr/jit/gentree.h | 51 +++++++++++++++++ src/coreclr/jit/lsra.cpp | 19 +------ src/coreclr/jit/regset.cpp | 91 +++++-------------------------- 4 files changed, 75 insertions(+), 141 deletions(-) diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index e3ac21ba504a2..6161834342719 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -2148,64 +2148,23 @@ void CodeGen::genProduceReg(GenTree* tree) } else { - // In case of multi-reg call node, spill flag on call node - // indicates that one or more of its allocated regs need to - // be spilled. Call node needs to be further queried to - // know which of its result regs needs to be spilled. - if (tree->IsMultiRegCall()) + if (tree->IsMultiRegNode()) { - GenTreeCall* call = tree->AsCall(); - const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - const unsigned regCount = retTypeDesc->GetReturnRegCount(); + // In case of multi-reg node, spill flag on it indicates that one or more of its allocated regs need to + // be spilled, and it needs to be further queried to know which of its result regs needs to be spilled. + const unsigned regCount = tree->GetMultiRegCount(compiler); for (unsigned i = 0; i < regCount; ++i) { - GenTreeFlags flags = call->GetRegSpillFlagByIdx(i); + GenTreeFlags flags = tree->GetRegSpillFlagByIdx(i); if ((flags & GTF_SPILL) != 0) { - regNumber reg = call->GetRegNumByIdx(i); - regSet.rsSpillTree(reg, call, i); + regNumber reg = tree->GetRegByIndex(i); + regSet.rsSpillTree(reg, tree, i); gcInfo.gcMarkRegSetNpt(genRegMask(reg)); } } } -#if FEATURE_ARG_SPLIT - else if (tree->OperIsPutArgSplit()) - { - assert(compFeatureArgSplit()); - GenTreePutArgSplit* argSplit = tree->AsPutArgSplit(); - unsigned regCount = argSplit->gtNumRegs; - - for (unsigned i = 0; i < regCount; ++i) - { - GenTreeFlags flags = argSplit->GetRegSpillFlagByIdx(i); - if ((flags & GTF_SPILL) != 0) - { - regNumber reg = argSplit->GetRegNumByIdx(i); - regSet.rsSpillTree(reg, argSplit, i); - gcInfo.gcMarkRegSetNpt(genRegMask(reg)); - } - } - } -#ifdef TARGET_ARM - else if (compFeatureArgSplit() && tree->OperIsMultiRegOp()) - { - GenTreeMultiRegOp* multiReg = tree->AsMultiRegOp(); - unsigned regCount = multiReg->GetRegCount(); - - for (unsigned i = 0; i < regCount; ++i) - { - GenTreeFlags flags = multiReg->GetRegSpillFlagByIdx(i); - if ((flags & GTF_SPILL) != 0) - { - regNumber reg = multiReg->GetRegNumByIdx(i); - regSet.rsSpillTree(reg, multiReg, i); - gcInfo.gcMarkRegSetNpt(genRegMask(reg)); - } - } - } -#endif // TARGET_ARM -#endif // FEATURE_ARG_SPLIT else { regSet.rsSpillTree(tree->GetRegNum(), tree); diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 81c0c181bfa3e..a4e62320f44e4 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1860,6 +1860,9 @@ struct GenTree // Returns the GTF flag equivalent for the regIndex'th register of a multi-reg node. GenTreeFlags GetRegSpillFlagByIdx(int regIndex) const; + // Sets the GTF flag equivalent for the regIndex'th register of a multi-reg node. + void SetRegSpillFlagByIdx(GenTreeFlags flags, int regIndex); + // Last-use information for either GenTreeLclVar or GenTreeCopyOrReload nodes. private: GenTreeFlags GetLastUseBit(int regIndex) const; @@ -9076,6 +9079,54 @@ inline GenTreeFlags GenTree::GetRegSpillFlagByIdx(int regIndex) const return GTF_EMPTY; } +//----------------------------------------------------------------------------------- +// SetRegSpillFlagByIdx: Set a specific register's spill flags, based on regIndex, +// for this multi-reg node. +// +// Arguments: +// flags - the flags to set +// regIndex - which register's spill flags to set +// +// Notes: +// This must be a multireg node and 'regIndex' must be a valid index for this node. +// This method takes the GTF "equivalent" flags and sets the packed flags on the +// multireg node. +// +inline void GenTree::SetRegSpillFlagByIdx(GenTreeFlags flags, int regIndex) +{ +#if FEATURE_MULTIREG_RET + if (IsMultiRegCall()) + { + AsCall()->SetRegSpillFlagByIdx(flags, regIndex); + return; + } + +#if FEATURE_ARG_SPLIT + if (OperIsPutArgSplit()) + { + AsPutArgSplit()->SetRegSpillFlagByIdx(flags, regIndex); + return; + } +#endif // FEATURE_ARG_SPLIT + +#if !defined(TARGET_64BIT) + if (OperIsMultiRegOp()) + { + AsMultiRegOp()->SetRegSpillFlagByIdx(flags, regIndex); + return; + } +#endif // !defined(TARGET_64BIT) + +#endif // FEATURE_MULTIREG_RET + if (OperIsScalarLocal()) + { + AsLclVar()->SetRegSpillFlagByIdx(flags, regIndex); + return; + } + + assert(!"Invalid node type for SetRegSpillFlagByIdx"); +} + //----------------------------------------------------------------------------------- // GetLastUseBit: Get the last use bit for regIndex // diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 4417858838d54..89762aeb3710d 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -6950,25 +6950,10 @@ void LinearScan::resolveRegisters() // register specified by multi-reg index of current RefPosition. // Note that the spill flag on treeNode indicates that one or // more its allocated registers are in that state. - if (treeNode->IsMultiRegCall()) + if (treeNode->IsMultiRegNode()) { - GenTreeCall* call = treeNode->AsCall(); - call->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); + treeNode->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); } -#if FEATURE_ARG_SPLIT - else if (treeNode->OperIsPutArgSplit()) - { - GenTreePutArgSplit* splitArg = treeNode->AsPutArgSplit(); - splitArg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); - } -#ifdef TARGET_ARM - else if (compFeatureArgSplit() && treeNode->OperIsMultiRegOp()) - { - GenTreeMultiRegOp* multiReg = treeNode->AsMultiRegOp(); - multiReg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); - } -#endif // TARGET_ARM -#endif // FEATURE_ARG_SPLIT } // If the value is reloaded or moved to a different register, we need to insert diff --git a/src/coreclr/jit/regset.cpp b/src/coreclr/jit/regset.cpp index d28a90ec36f5d..90dab5e3af1ef 100644 --- a/src/coreclr/jit/regset.cpp +++ b/src/coreclr/jit/regset.cpp @@ -292,36 +292,19 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) { assert(tree != nullptr); - GenTreeCall* call = nullptr; - GenTreeLclVar* lcl = nullptr; - var_types treeType; -#if defined(TARGET_ARM) - GenTreePutArgSplit* splitArg = nullptr; - GenTreeMultiRegOp* multiReg = nullptr; -#endif + var_types treeType = TYP_UNDEF; + bool isMultiRegTree = false; - if (tree->IsMultiRegCall()) - { - call = tree->AsCall(); - const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); - treeType = retTypeDesc->GetReturnRegType(regIdx); - } -#ifdef TARGET_ARM - else if (tree->OperIsPutArgSplit()) - { - splitArg = tree->AsPutArgSplit(); - treeType = splitArg->GetRegType(regIdx); - } - else if (tree->OperIsMultiRegOp()) - { - multiReg = tree->AsMultiRegOp(); - treeType = multiReg->GetRegType(regIdx); - } -#endif // TARGET_ARM - else if (tree->IsMultiRegLclVar()) + if (tree->IsMultiRegLclVar()) { LclVarDsc* varDsc = m_rsCompiler->lvaGetDesc(tree->AsLclVar()); treeType = varDsc->TypeGet(); + isMultiRegTree = true; + } + else if (tree->IsMultiRegNode()) + { + treeType = tree->GetRegTypeByIndex(regIdx); + isMultiRegTree = true; } else { @@ -353,29 +336,9 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) assert((tree->gtFlags & GTF_SPILL) != 0); GenTreeFlags regFlags = GTF_EMPTY; - if (call != nullptr) + if (isMultiRegTree) { - regFlags = call->GetRegSpillFlagByIdx(regIdx); - assert((regFlags & GTF_SPILL) != 0); - regFlags &= ~GTF_SPILL; - } -#ifdef TARGET_ARM - else if (splitArg != nullptr) - { - regFlags = splitArg->GetRegSpillFlagByIdx(regIdx); - assert((regFlags & GTF_SPILL) != 0); - regFlags &= ~GTF_SPILL; - } - else if (multiReg != nullptr) - { - regFlags = multiReg->GetRegSpillFlagByIdx(regIdx); - assert((regFlags & GTF_SPILL) != 0); - regFlags &= ~GTF_SPILL; - } -#endif // TARGET_ARM - else if (lcl != nullptr) - { - regFlags = lcl->GetRegSpillFlagByIdx(regIdx); + regFlags = tree->GetRegSpillFlagByIdx(regIdx); assert((regFlags & GTF_SPILL) != 0); regFlags &= ~GTF_SPILL; } @@ -385,13 +348,7 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) tree->gtFlags &= ~GTF_SPILL; } -#if defined(TARGET_ARM) - assert(tree->GetRegNum() == reg || (call != nullptr && call->GetRegNumByIdx(regIdx) == reg) || - (splitArg != nullptr && splitArg->GetRegNumByIdx(regIdx) == reg) || - (multiReg != nullptr && multiReg->GetRegNumByIdx(regIdx) == reg)); -#else - assert(tree->GetRegNum() == reg || (call != nullptr && call->GetRegNumByIdx(regIdx) == reg)); -#endif // !TARGET_ARM + assert(tree->GetRegByIndex(regIdx) == reg); // Are any registers free for spillage? SpillDsc* spill = SpillDsc::alloc(m_rsCompiler, this, tempType); @@ -435,29 +392,11 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) // Mark the tree node as having been spilled rsMarkSpill(tree, reg); - // In case of multi-reg call node also mark the specific - // result reg as spilled. - if (call != nullptr) - { - regFlags |= GTF_SPILLED; - call->SetRegSpillFlagByIdx(regFlags, regIdx); - } -#ifdef TARGET_ARM - else if (splitArg != nullptr) - { - regFlags |= GTF_SPILLED; - splitArg->SetRegSpillFlagByIdx(regFlags, regIdx); - } - else if (multiReg != nullptr) - { - regFlags |= GTF_SPILLED; - multiReg->SetRegSpillFlagByIdx(regFlags, regIdx); - } -#endif // TARGET_ARM - else if (lcl != nullptr) + // In case of multi-reg call node also mark the specific result reg as spilled. + if (isMultiRegTree) { regFlags |= GTF_SPILLED; - lcl->SetRegSpillFlagByIdx(regFlags, regIdx); + tree->SetRegSpillFlagByIdx(regFlags, regIdx); } } From 1ce6169b875aafd7b3eb7432f5dbb953646facee Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Fri, 29 Jul 2022 19:11:50 +0300 Subject: [PATCH 2/3] Unspilling fixes --- src/coreclr/jit/lsra.cpp | 4 +++ src/coreclr/jit/regset.cpp | 56 +++++++++++++------------------------- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 89762aeb3710d..bc476b466151c 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -4665,7 +4665,11 @@ void LinearScan::allocateRegisters() { assert(lastAllocatedRefPosition->registerAssignment != RBM_NONE); RegRecord* regRecord = lastAllocatedRefPosition->getInterval()->assignedReg; + + INDEBUG(activeRefPosition = lastAllocatedRefPosition); unassignPhysReg(regRecord, lastAllocatedRefPosition); + INDEBUG(activeRefPosition = nullptr); + // Now set lastAllocatedRefPosition to null, so that we don't try to spill it again lastAllocatedRefPosition = nullptr; } diff --git a/src/coreclr/jit/regset.cpp b/src/coreclr/jit/regset.cpp index 90dab5e3af1ef..3020198acadd2 100644 --- a/src/coreclr/jit/regset.cpp +++ b/src/coreclr/jit/regset.cpp @@ -364,8 +364,12 @@ void RegSet::rsSpillTree(regNumber reg, GenTree* tree, unsigned regIdx /* =0 */) #ifdef DEBUG if (m_rsCompiler->verbose) { - printf("\t\t\t\t\t\t\tThe register %s spilled with ", m_rsCompiler->compRegVarName(reg)); + printf("\t\t\t\t\t\t\tThe register %s spilled with ", m_rsCompiler->compRegVarName(reg)); Compiler::printTreeID(spill->spillTree); + if (isMultiRegTree) + { + printf("[%u]", regIdx); + } } #endif @@ -473,15 +477,13 @@ TempDsc* RegSet::rsGetSpillTempWord(regNumber reg, SpillDsc* dsc, SpillDsc* prev // oldReg - reg of tree that was spilled. // // Return Value: -// None. +// TempDsc the caller is expected to release. // // Assumptions: -// 1. It is the responsibility of the caller to free the spill temp. -// 2. RyuJIT backend specific: In case of multi-reg call node -// GTF_SPILLED flag associated with reg is cleared. It is the -// responsibility of caller to clear GTF_SPILLED flag on call node -// itself after ensuring there are no outstanding regs in GTF_SPILLED -// state. +// In case of multi-reg node GTF_SPILLED flag associated with reg is +// cleared. It is the responsibility of caller to clear GTF_SPILLED +// flag on call node itself after ensuring there are no outstanding +// regs in GTF_SPILLED state. // TempDsc* RegSet::rsUnspillInPlace(GenTree* tree, regNumber oldReg, unsigned regIdx /* =0 */) { @@ -493,36 +495,12 @@ TempDsc* RegSet::rsUnspillInPlace(GenTree* tree, regNumber oldReg, unsigned regI // Get the temp TempDsc* temp = rsGetSpillTempWord(oldReg, spillDsc, prevDsc); - // The value is now unspilled - if (tree->IsMultiRegCall()) - { - GenTreeCall* call = tree->AsCall(); - GenTreeFlags flags = call->GetRegSpillFlagByIdx(regIdx); - flags &= ~GTF_SPILLED; - call->SetRegSpillFlagByIdx(flags, regIdx); - } -#if defined(TARGET_ARM) - else if (tree->OperIsPutArgSplit()) - { - GenTreePutArgSplit* splitArg = tree->AsPutArgSplit(); - GenTreeFlags flags = splitArg->GetRegSpillFlagByIdx(regIdx); - flags &= ~GTF_SPILLED; - splitArg->SetRegSpillFlagByIdx(flags, regIdx); - } - else if (tree->OperIsMultiRegOp()) + // The value is now unspilled. + if (tree->IsMultiRegNode()) { - GenTreeMultiRegOp* multiReg = tree->AsMultiRegOp(); - GenTreeFlags flags = multiReg->GetRegSpillFlagByIdx(regIdx); + GenTreeFlags flags = tree->GetRegSpillFlagByIdx(regIdx); flags &= ~GTF_SPILLED; - multiReg->SetRegSpillFlagByIdx(flags, regIdx); - } -#endif // TARGET_ARM - else if (tree->IsMultiRegLclVar()) - { - GenTreeLclVar* lcl = tree->AsLclVar(); - GenTreeFlags flags = lcl->GetRegSpillFlagByIdx(regIdx); - flags &= ~GTF_SPILLED; - lcl->SetRegSpillFlagByIdx(flags, regIdx); + tree->SetRegSpillFlagByIdx(flags, regIdx); } else { @@ -532,8 +510,12 @@ TempDsc* RegSet::rsUnspillInPlace(GenTree* tree, regNumber oldReg, unsigned regI #ifdef DEBUG if (m_rsCompiler->verbose) { - printf("\t\t\t\t\t\t\tTree-Node marked unspilled from "); + printf("\t\t\t\t\t\t\tTree-Node marked unspilled from "); Compiler::printTreeID(tree); + if (tree->IsMultiRegNode()) + { + printf("[%u]", regIdx); + } printf("\n"); } #endif From 43c4cea2284d3ef8a835f14f209e8a4e52e49856 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Fri, 29 Jul 2022 21:44:42 +0300 Subject: [PATCH 3/3] Fix multi-reg HWIs --- src/coreclr/jit/gentree.cpp | 2 -- src/coreclr/jit/gentree.h | 55 +++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 3b7c12f25ccb1..e9f81c9948350 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -18616,7 +18616,6 @@ bool GenTreeSIMD::OperIsMemoryLoad() const return GetSIMDIntrinsicId() == SIMDIntrinsicInitArray; } -// TODO-Review: why are layouts not compared here? /* static */ bool GenTreeSIMD::Equals(GenTreeSIMD* op1, GenTreeSIMD* op2) { return (op1->TypeGet() == op2->TypeGet()) && (op1->GetSIMDIntrinsicId() == op2->GetSIMDIntrinsicId()) && @@ -22837,7 +22836,6 @@ void GenTreeHWIntrinsic::SetHWIntrinsicId(NamedIntrinsic intrinsicId) gtHWIntrinsicId = intrinsicId; } -// TODO-Review: why are layouts not compared here? /* static */ bool GenTreeHWIntrinsic::Equals(GenTreeHWIntrinsic* op1, GenTreeHWIntrinsic* op2) { return (op1->TypeGet() == op2->TypeGet()) && (op1->GetHWIntrinsicId() == op2->GetHWIntrinsicId()) && diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index a4e62320f44e4..a35da7c871252 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -5976,12 +5976,12 @@ class IntrinsicNodeBuilder final struct GenTreeJitIntrinsic : public GenTreeMultiOp { protected: - GenTree* gtInlineOperands[2]; - uint16_t gtLayoutNum; - unsigned char gtAuxiliaryJitType; // For intrinsics than need another type (e.g. Avx2.Gather* or SIMD (by element)) - regNumberSmall gtOtherReg; // For intrinsics that return 2 registers - unsigned char gtSimdBaseJitType; // SIMD vector base JIT type - unsigned char gtSimdSize; // SIMD vector size in bytes, use 0 for scalar intrinsics + GenTree* gtInlineOperands[2]; + regNumberSmall gtOtherReg; // The second register for multi-reg intrinsics. + MultiRegSpillFlags gtSpillFlags; // Spill flags for multi-reg intrinsics. + unsigned char gtAuxiliaryJitType; // For intrinsics than need another type (e.g. Avx2.Gather* or SIMD (by element)) + unsigned char gtSimdBaseJitType; // SIMD vector base JIT type + unsigned char gtSimdSize; // SIMD vector size in bytes, use 0 for scalar intrinsics #if defined(FEATURE_SIMD) union { @@ -5993,26 +5993,25 @@ struct GenTreeJitIntrinsic : public GenTreeMultiOp #endif public: - unsigned GetLayoutNum() const + regNumber GetOtherReg() const { - return gtLayoutNum; + return (regNumber)gtOtherReg; } - void SetLayoutNum(unsigned layoutNum) + void SetOtherReg(regNumber reg) { - assert(FitsIn(layoutNum)); - gtLayoutNum = static_cast(layoutNum); + gtOtherReg = (regNumberSmall)reg; + assert(gtOtherReg == reg); } - regNumber GetOtherReg() const + GenTreeFlags GetRegSpillFlagByIdx(unsigned idx) const { - return (regNumber)gtOtherReg; + return GetMultiRegSpillFlagsByIdx(gtSpillFlags, idx); } - void SetOtherReg(regNumber reg) + void SetRegSpillFlagByIdx(GenTreeFlags flags, unsigned idx) { - gtOtherReg = (regNumberSmall)reg; - assert(gtOtherReg == reg); + gtSpillFlags = SetMultiRegSpillFlagsByIdx(gtSpillFlags, flags, idx); } CorInfoType GetAuxiliaryJitType() const @@ -6088,9 +6087,9 @@ struct GenTreeJitIntrinsic : public GenTreeMultiOp unsigned simdSize, Operands... operands) : GenTreeMultiOp(oper, type, allocator, gtInlineOperands DEBUGARG(false), operands...) - , gtLayoutNum(0) - , gtAuxiliaryJitType(CORINFO_TYPE_UNDEF) , gtOtherReg(REG_NA) + , gtSpillFlags(0) + , gtAuxiliaryJitType(CORINFO_TYPE_UNDEF) , gtSimdBaseJitType((unsigned char)simdBaseJitType) , gtSimdSize((unsigned char)simdSize) , gtHWIntrinsicId(NI_Illegal) @@ -6116,9 +6115,9 @@ struct GenTreeJitIntrinsic : public GenTreeMultiOp nodeBuilder.GetBuiltOperands(), nodeBuilder.GetOperandCount(), gtInlineOperands DEBUGARG(false)) - , gtLayoutNum(0) - , gtAuxiliaryJitType(CORINFO_TYPE_UNDEF) , gtOtherReg(REG_NA) + , gtSpillFlags(0) + , gtAuxiliaryJitType(CORINFO_TYPE_UNDEF) , gtSimdBaseJitType((unsigned char)simdBaseJitType) , gtSimdSize((unsigned char)simdSize) , gtHWIntrinsicId(NI_Illegal) @@ -9070,6 +9069,13 @@ inline GenTreeFlags GenTree::GetRegSpillFlagByIdx(int regIndex) const #endif // !defined(TARGET_64BIT) #endif // FEATURE_MULTIREG_RET +#ifdef FEATURE_HW_INTRINSICS + if (OperIsHWIntrinsic()) + { + return AsHWIntrinsic()->GetRegSpillFlagByIdx(regIndex); + } +#endif // FEATURE_HW_INTRINSICS + if (OperIsScalarLocal()) { return AsLclVar()->GetRegSpillFlagByIdx(regIndex); @@ -9118,6 +9124,15 @@ inline void GenTree::SetRegSpillFlagByIdx(GenTreeFlags flags, int regIndex) #endif // !defined(TARGET_64BIT) #endif // FEATURE_MULTIREG_RET + +#ifdef FEATURE_HW_INTRINSICS + if (OperIsHWIntrinsic()) + { + AsHWIntrinsic()->SetRegSpillFlagByIdx(flags, regIndex); + return; + } +#endif // FEATURE_HW_INTRINSICS + if (OperIsScalarLocal()) { AsLclVar()->SetRegSpillFlagByIdx(flags, regIndex);