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

Commit 1c28080

Browse files
authored
Re-morph lclVar nodes after simplifying (ind (addr (lclVar))). (#11531)
Morph simplifies (ind (addr (lclVar))) if the type of the load matches the type of the lclVar node. This simplification is not valid, however, if the lclVar must be normalized upon load: in that case, the lclVar node must be normalized appropriately as part of the transformation. This change fixes the simplification to perform this normalization if necessary by calling `fgMorphLclVar` on the result if the result is a lclVar node. Fixes issue #11508.
1 parent 6fb6d4f commit 1c28080

File tree

4 files changed

+117
-4
lines changed

4 files changed

+117
-4
lines changed

src/jit/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4719,7 +4719,7 @@ class Compiler
47194719
const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structDescPtr));
47204720

47214721
void fgFixupStructReturn(GenTreePtr call);
4722-
GenTreePtr fgMorphLocalVar(GenTreePtr tree);
4722+
GenTreePtr fgMorphLocalVar(GenTreePtr tree, bool forceRemorph);
47234723
bool fgAddrCouldBeNull(GenTreePtr addr);
47244724
GenTreePtr fgMorphField(GenTreePtr tree, MorphAddrContext* mac);
47254725
bool fgCanFastTailCall(GenTreeCall* call);

src/jit/morph.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6099,7 +6099,7 @@ GenTreePtr Compiler::fgMorphStackArgForVarArgs(unsigned lclNum, var_types varTyp
60996099
* Transform the given GT_LCL_VAR tree for code generation.
61006100
*/
61016101

6102-
GenTreePtr Compiler::fgMorphLocalVar(GenTreePtr tree)
6102+
GenTreePtr Compiler::fgMorphLocalVar(GenTreePtr tree, bool forceRemorph)
61036103
{
61046104
noway_assert(tree->gtOper == GT_LCL_VAR);
61056105

@@ -6129,7 +6129,7 @@ GenTreePtr Compiler::fgMorphLocalVar(GenTreePtr tree)
61296129

61306130
/* If not during the global morphing phase bail */
61316131

6132-
if (!fgGlobalMorph)
6132+
if (!fgGlobalMorph && !forceRemorph)
61336133
{
61346134
return tree;
61356135
}
@@ -8523,7 +8523,8 @@ GenTreePtr Compiler::fgMorphLeaf(GenTreePtr tree)
85238523

85248524
if (tree->gtOper == GT_LCL_VAR)
85258525
{
8526-
return fgMorphLocalVar(tree);
8526+
const bool forceRemorph = false;
8527+
return fgMorphLocalVar(tree, forceRemorph);
85278528
}
85288529
#ifdef _TARGET_X86_
85298530
else if (tree->gtOper == GT_LCL_FLD)
@@ -13196,6 +13197,25 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
1319613197
DEBUG_DESTROY_NODE(op1); // GT_ADD or GT_ADDR
1319713198
DEBUG_DESTROY_NODE(tree); // GT_IND
1319813199

13200+
// If the result of the fold is a local var, we may need to perform further adjustments e.g. for
13201+
// normalization.
13202+
if (temp->OperIs(GT_LCL_VAR))
13203+
{
13204+
#ifdef DEBUG
13205+
// We clear this flag on `temp` because `fgMorphLocalVar` may assert that this bit is clear
13206+
// and the node in question must have this bit set (as it has already been morphed).
13207+
temp->gtDebugFlags &= ~GTF_DEBUG_NODE_MORPHED;
13208+
#endif // DEBUG
13209+
const bool forceRemorph = true;
13210+
temp = fgMorphLocalVar(temp, forceRemorph);
13211+
#ifdef DEBUG
13212+
// We then set this flag on `temp` because `fgMorhpLocalVar` may not set it itself, and the
13213+
// caller of `fgMorphSmpOp` may assert that this flag is set on `temp` once this function
13214+
// returns.
13215+
temp->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
13216+
#endif // DEBUG
13217+
}
13218+
1319913219
return temp;
1320013220
}
1320113221

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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.Collections.Generic;
7+
using System.Runtime.CompilerServices;
8+
9+
namespace TestApp
10+
{
11+
public struct StructWithValue : IEquatable<StructWithValue>
12+
{
13+
private ushort value;
14+
15+
public StructWithValue(ushort v)
16+
{
17+
value = v;
18+
}
19+
20+
21+
public bool Equals(StructWithValue other)
22+
{
23+
if (value.Equals (other.value))
24+
return true;
25+
else
26+
return false;
27+
}
28+
}
29+
30+
class Program
31+
{
32+
[MethodImpl(MethodImplOptions.NoOptimization)]
33+
static int Main(string[] args)
34+
{
35+
var comparer = EqualityComparer<StructWithValue>.Default;
36+
37+
for (ushort i = 0; ; i++)
38+
{
39+
var a = new StructWithValue(i);
40+
var b = new StructWithValue(i);
41+
42+
if (!comparer.Equals(a, b))
43+
{
44+
return 0;
45+
}
46+
47+
if (i == ushort.MaxValue)
48+
{
49+
break;
50+
}
51+
}
52+
53+
return 100;
54+
}
55+
}
56+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<SchemaVersion>2.0</SchemaVersion>
8+
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
9+
<OutputType>Exe</OutputType>
10+
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
11+
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
12+
</PropertyGroup>
13+
<!-- Default configurations to help VS understand the configurations -->
14+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
16+
<ItemGroup>
17+
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
18+
<Visible>False</Visible>
19+
</CodeAnalysisDependentAssemblyPaths>
20+
</ItemGroup>
21+
<PropertyGroup>
22+
<DebugType>None</DebugType>
23+
<Optimize>True</Optimize>
24+
</PropertyGroup>
25+
<ItemGroup>
26+
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
27+
</ItemGroup>
28+
<ItemGroup>
29+
<Compile Include="GitHub_11508.cs" />
30+
</ItemGroup>
31+
<!-- <PropertyGroup>
32+
<ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
33+
<ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
34+
</PropertyGroup>-->
35+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
36+
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
37+
</Project>

0 commit comments

Comments
 (0)