summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarol Eidt <carol.eidt@microsoft.com>2015-07-26 20:14:03 -0700
committerJan Kotas <jkotas@microsoft.com>2015-07-26 21:23:55 -0700
commit25aa636ff812ba8432f65a0b9078eaa886b4f6d2 (patch)
treecd96fb8084e658d096c88d9593ed3f27fe79a8f4
parentd0e28de45b690c8e51809265244ed02d7ed3c855 (diff)
downloadcoreclr-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.cpp21
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;