varNode = addrNode->AsLclVarCommon();
addrNode = nullptr;
}
+ else // addrNode is used
+ {
+ // Generate code to load the address that we need into a register
+ genConsumeAddress(addrNode);
+ addrReg = addrNode->gtRegNum;
+
+#ifdef _TARGET_ARM64_
+ // If addrReg equal to loReg, swap(loReg, hiReg)
+ // This reduces code complexity by only supporting one addrReg overwrite case
+ if (loReg == addrReg)
+ {
+ loReg = hiReg;
+ hiReg = addrReg;
+ }
+#endif // _TARGET_ARM64_
+ }
}
// Either varNode or addrNOde must have been setup above,
gcPtrCount = treeNode->gtNumberReferenceSlots;
#endif
// Setup the structSize, isHFa, and gcPtrCount
- if (varNode != nullptr)
+ if (source->OperGet() == GT_LCL_VAR)
{
+ assert(varNode != nullptr);
varNumInp = varNode->gtLclNum;
assert(varNumInp < compiler->lvaCount);
LclVarDsc* varDsc = &compiler->lvaTable[varNumInp];
gcPtrs[i] = varDsc->lvGcLayout[i];
#endif // _TARGET_ARM_
}
- else // addrNode is used
+ else // we must have a GT_OBJ
{
- assert(addrNode != nullptr);
-
- // Generate code to load the address that we need into a register
- genConsumeAddress(addrNode);
- addrReg = addrNode->gtRegNum;
-
-#ifdef _TARGET_ARM64_
- // If addrReg equal to loReg, swap(loReg, hiReg)
- // This reduces code complexity by only supporting one addrReg overwrite case
- if (loReg == addrReg)
- {
- loReg = hiReg;
- hiReg = addrReg;
- }
-#endif // _TARGET_ARM64_
- }
+ assert(source->OperGet() == GT_OBJ);
- if (source->OperIs(GT_OBJ))
- {
// If the source is an OBJ node then we need to use the type information
// it provides (size and GC layout) even if the node wraps a lclvar. Due
// to struct reinterpretation (e.g. Unsafe.As<X, Y>) it is possible that