From 1aba6e81fe9117d3cbec5683ba00af1f21e47cc9 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Thu, 31 Oct 2019 08:16:37 -0700 Subject: [PATCH] Fix struct assignment where types differ Commit migrated from https://github.com/dotnet/coreclr/commit/3220c89e9e5e9b4879efa941c3d04c0debcee41c --- src/coreclr/src/jit/importer.cpp | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index dea6d81..8d33f43 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -1170,7 +1170,6 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, BasicBlock* block /* = NULL */ ) { - var_types destType; GenTree* dest = nullptr; unsigned destFlags = 0; @@ -1182,23 +1181,6 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, assert(src->OperIs(GT_LCL_VAR, GT_FIELD, GT_IND, GT_OBJ, GT_CALL, GT_MKREFANY, GT_RET_EXPR, GT_COMMA) || (src->TypeGet() != TYP_STRUCT && (src->OperIsSimdOrHWintrinsic() || src->OperIs(GT_LCL_FLD)))); - if (destAddr->OperGet() == GT_ADDR) - { - GenTree* destNode = destAddr->gtGetOp1(); - // If the actual destination is a local, or already a block node, or is a node that - // will be morphed, don't insert an OBJ(ADDR). - if (destNode->gtOper == GT_INDEX || destNode->OperIsBlk() || - ((destNode->OperGet() == GT_LCL_VAR) && (destNode->TypeGet() == src->TypeGet()))) - { - dest = destNode; - } - destType = destNode->TypeGet(); - } - else - { - destType = src->TypeGet(); - } - var_types asgType = src->TypeGet(); if (src->gtOper == GT_CALL) @@ -1309,13 +1291,6 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, src->gtType = genActualType(returnType); call->gtType = src->gtType; - // If we've changed the type, and it no longer matches a local destination, - // we must use an indirection. - if ((dest != nullptr) && (dest->OperGet() == GT_LCL_VAR) && (dest->TypeGet() != asgType)) - { - dest = nullptr; - } - // !!! The destination could be on stack. !!! // This flag will let us choose the correct write barrier. destFlags = GTF_IND_TGTANYWHERE; @@ -1407,6 +1382,19 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, asgType = impNormStructType(structHnd); src->gtType = asgType; } + if ((dest == nullptr) && (destAddr->OperGet() == GT_ADDR)) + { + GenTree* destNode = destAddr->gtGetOp1(); + // If the actual destination is a local, or already a block node, or is a node that + // will be morphed, don't insert an OBJ(ADDR) if it already has the right type. + CORINFO_CLASS_HANDLE destClass = gtGetStructHandleIfPresent(destNode); + if ((destClass == structHnd) && (destNode->TypeGet() == asgType) && + ((destNode->gtOper == GT_INDEX) || destNode->OperIsBlk() || (destNode->OperGet() == GT_LCL_VAR))) + { + dest = destNode; + } + } + if (dest == nullptr) { if (asgType == TYP_STRUCT) -- 2.7.4