summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPat Gavlin <pagavlin@microsoft.com>2016-09-22 10:12:59 -0700
committerPat Gavlin <pagavlin@microsoft.com>2016-09-22 10:12:59 -0700
commitea7fd8631c858638b346204e3a4b6f8a8ac9110c (patch)
tree91b36ba7f9fd273a3cbeb4d0f93e566d41ede2d6
parentf5d7e048cf7d66c6dc8473d428bf2d82dddd07d5 (diff)
downloadcoreclr-ea7fd8631c858638b346204e3a4b6f8a8ac9110c.tar.gz
coreclr-ea7fd8631c858638b346204e3a4b6f8a8ac9110c.tar.bz2
coreclr-ea7fd8631c858638b346204e3a4b6f8a8ac9110c.zip
Decompose GT_FIELD_LIST nodes that use a GT_LONG.
These nodes are decomposed by splitting the appropriate field list element into two elements: one each for the low and high halves of the GT_LONG.
-rw-r--r--src/jit/decomposelongs.cpp33
-rw-r--r--src/jit/lowerxarch.cpp5
2 files changed, 34 insertions, 4 deletions
diff --git a/src/jit/decomposelongs.cpp b/src/jit/decomposelongs.cpp
index 017fa62c3e..04f48aa6fb 100644
--- a/src/jit/decomposelongs.cpp
+++ b/src/jit/decomposelongs.cpp
@@ -260,6 +260,39 @@ GenTree* DecomposeLongs::DecomposeNode(GenTree* tree)
}
}
+ // If we replaced the argument to a GT_FIELD_LIST element with a GT_LONG node, split that field list
+ // element into two elements: one for each half of the GT_LONG.
+ if ((use.Def()->OperGet() == GT_LONG) && !use.IsDummyUse() && (use.User()->OperGet() == GT_FIELD_LIST))
+ {
+ GenTreeOp* value = use.Def()->AsOp();
+ Range().Remove(value);
+
+ // The node returned by `use.User()` is the head of the field list. We need to find the actual node that uses
+ // the `GT_LONG` so that we can split it.
+ GenTreeFieldList* listNode = use.User()->AsFieldList();
+ for ( ; listNode != nullptr; listNode = listNode->Rest())
+ {
+ if (listNode->Current() == value)
+ {
+ break;
+ }
+ }
+
+ assert(listNode != nullptr);
+ GenTree* rest = listNode->gtOp2;
+
+ GenTreeFieldList* loNode = listNode;
+ loNode->gtOp1 = value->gtOp1;
+ loNode->gtFieldType = TYP_INT;
+
+ GenTreeFieldList* hiNode = new (m_compiler, GT_FIELD_LIST) GenTreeFieldList(value->gtOp2,
+ loNode->gtFieldOffset + 4,
+ TYP_INT,
+ loNode);
+
+ hiNode->gtOp2 = rest;
+ }
+
#ifdef DEBUG
if (m_compiler->verbose)
{
diff --git a/src/jit/lowerxarch.cpp b/src/jit/lowerxarch.cpp
index 3a745bb3bc..235d7bed6e 100644
--- a/src/jit/lowerxarch.cpp
+++ b/src/jit/lowerxarch.cpp
@@ -1915,10 +1915,7 @@ void Lowering::TreeNodeInfoInitPutArgStk(GenTree* tree)
for (; fieldListPtr; fieldListPtr = fieldListPtr->Rest())
{
GenTree* fieldNode = fieldListPtr->Current();
- if (fieldNode->OperGet() == GT_LONG)
- {
- NYI_X86("Promoted long field of TYP_STRUCT");
- }
+ assert(fieldNode->TypeGet() != TYP_LONG);
if (varTypeIsByte(fieldNode))
{
fieldNode->gtLsraInfo.setSrcCandidates(l, l->allRegs(TYP_INT) & ~RBM_NON_BYTE_REGS);