diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2020-02-13 14:27:34 -0800 |
---|---|---|
committer | Hyungju Lee <leee.lee@samsung.com> | 2020-10-30 18:21:40 +0900 |
commit | b21691713af4721fdde0aba7e9848b901605f029 (patch) | |
tree | b6c4949ef2835493f5b0ae70cec9fd1eabc8ec1c | |
parent | efafc277debebbeaa444b8d5d32b2b77420fa889 (diff) | |
download | coreclr-b21691713af4721fdde0aba7e9848b901605f029.tar.gz coreclr-b21691713af4721fdde0aba7e9848b901605f029.tar.bz2 coreclr-b21691713af4721fdde0aba7e9848b901605f029.zip |
Port fix for #1241 to 3.1 (#27983)
-rw-r--r-- | src/jit/morph.cpp | 27 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.cs | 95 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/Runtime_1241/Runtime_1241.csproj | 13 |
3 files changed, 123 insertions, 12 deletions
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 5450b4396c..ef5f5fcaaf 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -10190,6 +10190,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; @@ -10205,10 +10206,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) { @@ -10263,26 +10265,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> |