diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2015-07-26 20:14:03 -0700 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2015-07-26 21:23:55 -0700 |
commit | 25aa636ff812ba8432f65a0b9078eaa886b4f6d2 (patch) | |
tree | cd96fb8084e658d096c88d9593ed3f27fe79a8f4 | |
parent | d0e28de45b690c8e51809265244ed02d7ed3c855 (diff) | |
download | coreclr-25aa636ff812ba8432f65a0b9078eaa886b4f6d2.tar.gz coreclr-25aa636ff812ba8432f65a0b9078eaa886b4f6d2.tar.bz2 coreclr-25aa636ff812ba8432f65a0b9078eaa886b4f6d2.zip |
Fix 1203471: Incorrect rationalization of unused SIMD localVar
The Rationalizer was not correctly handling a case of an unused SIMD expression involving a localVar or temporary value, where the SIMD expression is returning a non-SIMD value, and the expression is sufficiently complex (e.g. a call to vector * scalar which is inlined but not an intrinsic).
The ldobj of the localVar is not eliminated, because it involves an indirection, and therefore appears potentially unsafe to eliminate. However, when we transform the ldobj into a plain localVar during the Rationalizer, we need to correctly handle the case where it has no parent.
[tfs-changeset: 1505976]
-rw-r--r-- | src/jit/rationalize.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/jit/rationalize.cpp b/src/jit/rationalize.cpp index aaa50550b8..c2828ec0c8 100644 --- a/src/jit/rationalize.cpp +++ b/src/jit/rationalize.cpp @@ -1546,8 +1546,27 @@ void Rationalizer::RewriteLdObj(GenTreePtr* ppTree, Compiler::fgWalkData* data) if (srcAddr->OperGet() == GT_ADDR && comp->isSIMDTypeLocal(srcAddr->gtGetOp1())) { GenTree* src = srcAddr->gtGetOp1(); - comp->fgSnipInnerNode(ldObj); comp->fgSnipInnerNode(srcAddr); + // It is possible for the ldobj to be the last node in the tree, if its result is + // not actually stored anywhere and is not eliminated. + // This can happen with an unused SIMD expression involving a localVar or temporary value, + // where the SIMD expression is returning a non-SIMD value, and the expression is sufficiently + // complex (e.g. a call to vector * scalar which is inlined but not an intrinsic). + // The ldobj of the localVar is not eliminated, because it involves an indirection, + // and therefore appears potentially unsafe to eliminate. However, when we transform the ldobj into + // a plain localVar during the Rationalizer, we need to correctly handle the case where it has + // no parent. + // This happens, for example, with this source code: + // Vector4.Dot(default(Vector4) * 2f, Vector4.One); + if (ldObj->gtNext == nullptr) + { + SplitData *tmpState = (SplitData *) data->pCallbackData; + comp->fgSnipNode(tmpState->root->AsStmt(), ldObj); + } + else + { + comp->fgSnipInnerNode(ldObj); + } src->gtType = simdType; *ppTree = src; |