diff options
author | sivarv <sivarv@microsoft.com> | 2016-12-20 17:25:29 -0800 |
---|---|---|
committer | sivarv <sivarv@microsoft.com> | 2016-12-20 17:36:59 -0800 |
commit | 41817d2f9d5a8abcc345d2b0bc5c9be315c4a37b (patch) | |
tree | 9aa5bb670fe9c41631f9425275b7d58b484fa93d | |
parent | 0ba60efbaa64e83c22956b524572907345748b1c (diff) | |
download | coreclr-41817d2f9d5a8abcc345d2b0bc5c9be315c4a37b.tar.gz coreclr-41817d2f9d5a8abcc345d2b0bc5c9be315c4a37b.tar.bz2 coreclr-41817d2f9d5a8abcc345d2b0bc5c9be315c4a37b.zip |
Fix GT_LOCKADD register specification.
-rw-r--r-- | src/jit/lowerxarch.cpp | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/jit/lowerxarch.cpp b/src/jit/lowerxarch.cpp index 589cef482e..9792e0ed2e 100644 --- a/src/jit/lowerxarch.cpp +++ b/src/jit/lowerxarch.cpp @@ -623,7 +623,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree) case GT_LOCKADD: info->srcCount = 2; - info->dstCount = 0; + info->dstCount = (tree->TypeGet() == TYP_VOID) ? 0 : 1; CheckImmedAndMakeContained(tree, tree->gtOp.gtOp2); break; @@ -883,6 +883,31 @@ void Lowering::TreeNodeInfoInit(GenTree* tree) // to special case them. if (tree->OperGet() == GT_XADD || tree->OperGet() == GT_XCHG || tree->OperGet() == GT_LOCKADD) { + // These tree nodes will have their op1 marked as isDelayFree=true. + // Hence these tree nodes should have a Def position so that op1's reg + // gets freed at DefLoc+1. + if (tree->TypeGet() == TYP_VOID) + { + // Right now a GT_XADD node could be morphed into a + // GT_LOCKADD of TYP_VOID. See gtExtractSideEffList(). + // Note that it is advantageous to use GT_LOCKADD + // instead of of GT_XADD as the former uses lock.add, + // which allows its second operand to be a contained + // immediate wheres xadd instruction requires its + // second operand to be in a register. + assert(tree->gtLsraInfo.dstCount == 0); + + // Give it an artificial type and mark it isLocalDefUse = true. + // This would result in a Def position created but not considered + // consumed by its parent node. + tree->gtType = TYP_INT; + tree->gtLsraInfo.isLocalDefUse = true; + } + else + { + assert(tree->gtLsraInfo.dstCount != 0); + } + delayUseSrc = op1; } else if ((op2 != nullptr) && |