summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarol Eidt <carol.eidt@microsoft.com>2020-02-13 14:27:34 -0800
committerGitHub <noreply@github.com>2020-02-13 14:27:34 -0800
commita86e825a641cf637d641e35f9ca88b65fe7ae801 (patch)
tree4d4ee4731f321963280a3720426475ebb4e25f6b
parent3800df91364fac77a85a512a9988c71302726e65 (diff)
downloadcoreclr-a86e825a641cf637d641e35f9ca88b65fe7ae801.tar.gz
coreclr-a86e825a641cf637d641e35f9ca88b65fe7ae801.tar.bz2
coreclr-a86e825a641cf637d641e35f9ca88b65fe7ae801.zip
Port fix for #1241 to 3.1 (#27983)
-rw-r--r--src/jit/morph.cpp27
-rw-r--r--tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.cs95
-rw-r--r--tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.csproj13
3 files changed, 123 insertions, 12 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index dfea9e7832..5d5d471eb7 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -10199,6 +10199,7 @@ GenTree* Compiler::fgMorphCopyBlock(GenTree* tree)
GenTreeLclVarCommon* lclVarTree = nullptr;
GenTreeLclVarCommon* srcLclVarTree = nullptr;
unsigned destLclNum = BAD_VAR_NUM;
+ unsigned modifiedLclNum = BAD_VAR_NUM;
LclVarDsc* destLclVar = nullptr;
FieldSeqNode* destFldSeq = nullptr;
bool destDoFldAsg = false;
@@ -10214,10 +10215,11 @@ GenTree* Compiler::fgMorphCopyBlock(GenTree* tree)
{
blockWidthIsConst = true;
destOnStack = true;
+ modifiedLclNum = dest->AsLclVarCommon()->GetLclNum();
if (dest->gtOper == GT_LCL_VAR)
{
lclVarTree = dest->AsLclVarCommon();
- destLclNum = lclVarTree->gtLclNum;
+ destLclNum = modifiedLclNum;
destLclVar = &lvaTable[destLclNum];
if (destLclVar->lvType == TYP_STRUCT)
{
@@ -10272,26 +10274,27 @@ GenTree* Compiler::fgMorphCopyBlock(GenTree* tree)
noway_assert(destAddr->TypeGet() == TYP_BYREF || destAddr->TypeGet() == TYP_I_IMPL);
if (destAddr->IsLocalAddrExpr(this, &lclVarTree, &destFldSeq))
{
- destOnStack = true;
- destLclNum = lclVarTree->gtLclNum;
- destLclVar = &lvaTable[destLclNum];
+ destOnStack = true;
+ destLclNum = lclVarTree->GetLclNum();
+ modifiedLclNum = destLclNum;
+ destLclVar = &lvaTable[destLclNum];
}
}
}
- if (destLclVar != nullptr)
- {
#if LOCAL_ASSERTION_PROP
- // Kill everything about destLclNum (and its field locals)
- if (optLocalAssertionProp)
+ // Kill everything about modifiedLclNum (and its field locals)
+ if ((modifiedLclNum != BAD_VAR_NUM) && optLocalAssertionProp)
+ {
+ if (optAssertionCount > 0)
{
- if (optAssertionCount > 0)
- {
- fgKillDependentAssertions(destLclNum DEBUGARG(tree));
- }
+ fgKillDependentAssertions(modifiedLclNum DEBUGARG(tree));
}
+ }
#endif // LOCAL_ASSERTION_PROP
+ if (destLclVar != nullptr)
+ {
if (destLclVar->lvPromoted && blockWidthIsConst)
{
noway_assert(varTypeIsStruct(destLclVar));
diff --git a/tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.cs b/tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.cs
new file mode 100644
index 0000000000..02c21ce5eb
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.cs
@@ -0,0 +1,95 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Linq;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+
+namespace Runtime_1241
+{
+
+ public struct Vertex
+ {
+ public Vector3 Position;
+ public Vector2 TexCoords;
+
+ public Vertex(Vector3 pos, Vector2 tex)
+ {
+ Position = pos;
+ TexCoords = tex;
+ }
+ }
+
+ class Program
+ {
+ static int Main()
+ {
+ int returnVal = 100;
+
+ // This prints all zeros in the failure case.
+ Console.WriteLine("Replacing array element with new struct directly");
+ {
+ var bug = Bug.Create();
+ bug.MutateBroken();
+
+ Console.WriteLine(bug.Vertices[0].Position);
+ if ((bug.Vertices[0].Position.X != 1) || (bug.Vertices[0].Position.Y != 1) || (bug.Vertices[0].Position.Z != 1))
+ {
+ returnVal = -1;
+ }
+ }
+
+ // Works
+ Console.WriteLine("Replacing array element with new struct, stored in a local variable first");
+ {
+ var bug = Bug.Create();
+ bug.MutateWorks();
+
+ Console.WriteLine(bug.Vertices[0].Position);
+ if ((bug.Vertices[0].Position.X != 1) || (bug.Vertices[0].Position.Y != 1) || (bug.Vertices[0].Position.Z != 1))
+ {
+ returnVal = -1;
+ }
+ }
+
+ return returnVal;
+ }
+ }
+
+ public class Bug
+ {
+ public static Bug Create()
+ {
+ return new Bug
+ {
+ Vertices = Enumerable.Range(1, 100).Select(i => new Vertex(new Vector3(i), Vector2.One)).ToArray()
+ };
+ }
+
+ public Vertex[] Vertices { get; set; }
+
+ public void MutateBroken()
+ {
+ for (var i = 0; i < Vertices.Length; i++)
+ {
+ var vert = Vertices[i];
+
+ Vertices[i] = new Vertex(vert.Position, vert.TexCoords);
+ }
+ }
+
+ public void MutateWorks()
+ {
+ for (var i = 0; i < Vertices.Length; i++)
+ {
+ var vert = Vertices[i];
+
+ var newVert = new Vertex(vert.Position, vert.TexCoords);
+
+ Vertices[i] = newVert;
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.csproj b/tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.csproj
new file mode 100644
index 0000000000..656bedde10
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <CLRTestPriority>1</CLRTestPriority>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DebugType />
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+</Project>