Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a86e825

Browse files
authored
Port fix for #1241 to 3.1 (#27983)
1 parent 3800df9 commit a86e825

File tree

3 files changed

+123
-12
lines changed

3 files changed

+123
-12
lines changed

src/jit/morph.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10199,6 +10199,7 @@ GenTree* Compiler::fgMorphCopyBlock(GenTree* tree)
1019910199
GenTreeLclVarCommon* lclVarTree = nullptr;
1020010200
GenTreeLclVarCommon* srcLclVarTree = nullptr;
1020110201
unsigned destLclNum = BAD_VAR_NUM;
10202+
unsigned modifiedLclNum = BAD_VAR_NUM;
1020210203
LclVarDsc* destLclVar = nullptr;
1020310204
FieldSeqNode* destFldSeq = nullptr;
1020410205
bool destDoFldAsg = false;
@@ -10214,10 +10215,11 @@ GenTree* Compiler::fgMorphCopyBlock(GenTree* tree)
1021410215
{
1021510216
blockWidthIsConst = true;
1021610217
destOnStack = true;
10218+
modifiedLclNum = dest->AsLclVarCommon()->GetLclNum();
1021710219
if (dest->gtOper == GT_LCL_VAR)
1021810220
{
1021910221
lclVarTree = dest->AsLclVarCommon();
10220-
destLclNum = lclVarTree->gtLclNum;
10222+
destLclNum = modifiedLclNum;
1022110223
destLclVar = &lvaTable[destLclNum];
1022210224
if (destLclVar->lvType == TYP_STRUCT)
1022310225
{
@@ -10272,26 +10274,27 @@ GenTree* Compiler::fgMorphCopyBlock(GenTree* tree)
1027210274
noway_assert(destAddr->TypeGet() == TYP_BYREF || destAddr->TypeGet() == TYP_I_IMPL);
1027310275
if (destAddr->IsLocalAddrExpr(this, &lclVarTree, &destFldSeq))
1027410276
{
10275-
destOnStack = true;
10276-
destLclNum = lclVarTree->gtLclNum;
10277-
destLclVar = &lvaTable[destLclNum];
10277+
destOnStack = true;
10278+
destLclNum = lclVarTree->GetLclNum();
10279+
modifiedLclNum = destLclNum;
10280+
destLclVar = &lvaTable[destLclNum];
1027810281
}
1027910282
}
1028010283
}
1028110284

10282-
if (destLclVar != nullptr)
10283-
{
1028410285
#if LOCAL_ASSERTION_PROP
10285-
// Kill everything about destLclNum (and its field locals)
10286-
if (optLocalAssertionProp)
10286+
// Kill everything about modifiedLclNum (and its field locals)
10287+
if ((modifiedLclNum != BAD_VAR_NUM) && optLocalAssertionProp)
10288+
{
10289+
if (optAssertionCount > 0)
1028710290
{
10288-
if (optAssertionCount > 0)
10289-
{
10290-
fgKillDependentAssertions(destLclNum DEBUGARG(tree));
10291-
}
10291+
fgKillDependentAssertions(modifiedLclNum DEBUGARG(tree));
1029210292
}
10293+
}
1029310294
#endif // LOCAL_ASSERTION_PROP
1029410295

10296+
if (destLclVar != nullptr)
10297+
{
1029510298
if (destLclVar->lvPromoted && blockWidthIsConst)
1029610299
{
1029710300
noway_assert(varTypeIsStruct(destLclVar));
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Linq;
7+
using System.Numerics;
8+
using System.Runtime.CompilerServices;
9+
10+
namespace Runtime_1241
11+
{
12+
13+
public struct Vertex
14+
{
15+
public Vector3 Position;
16+
public Vector2 TexCoords;
17+
18+
public Vertex(Vector3 pos, Vector2 tex)
19+
{
20+
Position = pos;
21+
TexCoords = tex;
22+
}
23+
}
24+
25+
class Program
26+
{
27+
static int Main()
28+
{
29+
int returnVal = 100;
30+
31+
// This prints all zeros in the failure case.
32+
Console.WriteLine("Replacing array element with new struct directly");
33+
{
34+
var bug = Bug.Create();
35+
bug.MutateBroken();
36+
37+
Console.WriteLine(bug.Vertices[0].Position);
38+
if ((bug.Vertices[0].Position.X != 1) || (bug.Vertices[0].Position.Y != 1) || (bug.Vertices[0].Position.Z != 1))
39+
{
40+
returnVal = -1;
41+
}
42+
}
43+
44+
// Works
45+
Console.WriteLine("Replacing array element with new struct, stored in a local variable first");
46+
{
47+
var bug = Bug.Create();
48+
bug.MutateWorks();
49+
50+
Console.WriteLine(bug.Vertices[0].Position);
51+
if ((bug.Vertices[0].Position.X != 1) || (bug.Vertices[0].Position.Y != 1) || (bug.Vertices[0].Position.Z != 1))
52+
{
53+
returnVal = -1;
54+
}
55+
}
56+
57+
return returnVal;
58+
}
59+
}
60+
61+
public class Bug
62+
{
63+
public static Bug Create()
64+
{
65+
return new Bug
66+
{
67+
Vertices = Enumerable.Range(1, 100).Select(i => new Vertex(new Vector3(i), Vector2.One)).ToArray()
68+
};
69+
}
70+
71+
public Vertex[] Vertices { get; set; }
72+
73+
public void MutateBroken()
74+
{
75+
for (var i = 0; i < Vertices.Length; i++)
76+
{
77+
var vert = Vertices[i];
78+
79+
Vertices[i] = new Vertex(vert.Position, vert.TexCoords);
80+
}
81+
}
82+
83+
public void MutateWorks()
84+
{
85+
for (var i = 0; i < Vertices.Length; i++)
86+
{
87+
var vert = Vertices[i];
88+
89+
var newVert = new Vertex(vert.Position, vert.TexCoords);
90+
91+
Vertices[i] = newVert;
92+
}
93+
}
94+
}
95+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<CLRTestPriority>1</CLRTestPriority>
5+
</PropertyGroup>
6+
<PropertyGroup>
7+
<DebugType />
8+
<Optimize>True</Optimize>
9+
</PropertyGroup>
10+
<ItemGroup>
11+
<Compile Include="$(MSBuildProjectName).cs" />
12+
</ItemGroup>
13+
</Project>

0 commit comments

Comments
 (0)