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

Commit 88527bb

Browse files
author
Sergey Andreenko
authored
Fix 14455: _opt_relrotarg_valref test failure on amd64. (#15032)
* fix the issue Do not zero-initialize temps, that were created by jit and do not have GC refs. The confusion was that `varDsc->lvIsTemp` means `short live` variable, when we wanted to ask is it IL temp or not. * add a non-stress repro.
1 parent d3297ab commit 88527bb

File tree

3 files changed

+146
-6
lines changed

3 files changed

+146
-6
lines changed

src/jit/morph.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8104,22 +8104,23 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
81048104

81058105
// If compInitMem is set, we may need to zero-initialize some locals. Normally it's done in the prolog
81068106
// but this loop can't include the prolog. Since we don't have liveness information, we insert zero-initialization
8107-
// for all non-parameter non-temp locals as well as temp structs with GC fields.
8107+
// for all non-parameter IL locals as well as temp structs with GC fields.
81088108
// Liveness phase will remove unnecessary initializations.
81098109
if (info.compInitMem)
81108110
{
81118111
unsigned varNum;
81128112
LclVarDsc* varDsc;
81138113
for (varNum = 0, varDsc = lvaTable; varNum < lvaCount; varNum++, varDsc++)
81148114
{
8115-
var_types lclType = varDsc->TypeGet();
81168115
if (!varDsc->lvIsParam)
81178116
{
8118-
if (!varDsc->lvIsTemp || ((lclType == TYP_STRUCT) && (varDsc->lvStructGcCount > 0)))
8117+
var_types lclType = varDsc->TypeGet();
8118+
bool isUserLocal = (varNum < info.compLocalsCount);
8119+
bool structWithGCFields = ((lclType == TYP_STRUCT) && (varDsc->lvStructGcCount > 0));
8120+
if (isUserLocal || structWithGCFields)
81198121
{
8120-
var_types lclType = varDsc->TypeGet();
8121-
GenTreePtr lcl = gtNewLclvNode(varNum, lclType);
8122-
GenTreePtr init = nullptr;
8122+
GenTreePtr lcl = gtNewLclvNode(varNum, lclType);
8123+
GenTreePtr init = nullptr;
81238124
if (lclType == TYP_STRUCT)
81248125
{
81258126
const bool isVolatile = false;
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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+
// It is a non-stress repro for the issue #14455.
6+
// growTree is optimized as fast tail call and converted to a loop.
7+
// `starg.s 0` forces the jit to create a temp for the modifiable this.
8+
// Before the fix the jit zero-initialized all long-live locals in the end of the loop,
9+
// on the last iteration it set `this` to `null` and the return block was trying to use
10+
// `null` to write `m_rightChild` in, that caused a runtime exception.
11+
12+
13+
.assembly extern System.Runtime {auto}
14+
.assembly GitHub_14455 {}
15+
16+
.class public auto ansi beforefieldinit Rotate.Node
17+
extends [System.Runtime]System.Object
18+
{
19+
.field public class Rotate.Node m_leftChild
20+
.field public class Rotate.Node m_rightChild
21+
.method public hidebysig specialname rtspecialname
22+
instance void .ctor() cil managed
23+
{
24+
// Code size 7 (0x7)
25+
.maxstack 8
26+
IL_0000: ldarg.0
27+
IL_0001: call instance void [System.Runtime]System.Object::.ctor()
28+
IL_0006: ret
29+
} // end of method Node::.ctor
30+
31+
.method family hidebysig virtual instance void
32+
Finalize() cil managed
33+
{
34+
.override [System.Runtime]System.Object::Finalize
35+
// Code size 10 (0xa)
36+
.maxstack 1
37+
.try
38+
{
39+
IL_0000: leave.s IL_0009
40+
41+
} // end .try
42+
finally
43+
{
44+
IL_0002: ldarg.0
45+
IL_0003: call instance void [System.Runtime]System.Object::Finalize()
46+
IL_0008: endfinally
47+
} // end handler
48+
IL_0009: ret
49+
} // end of method Node::Finalize
50+
51+
.method public hidebysig instance void
52+
growTree(int32 maxHeight) cil managed
53+
{
54+
// Code size 72 (0x48)
55+
.maxstack 4
56+
.locals init (class Rotate.Node V_0)
57+
IL_0000: ldarg.1
58+
IL_0001: ldc.i4.0
59+
IL_0002: ble.s IL_0037
60+
61+
IL_0004: ldarg.0
62+
IL_0005: newobj instance void Rotate.Node::.ctor()
63+
IL_000a: stfld class Rotate.Node Rotate.Node::m_leftChild
64+
IL_000f: ldarg.0
65+
IL_0010: ldfld class Rotate.Node Rotate.Node::m_leftChild
66+
IL_0015: ldarg.1
67+
IL_0016: ldc.i4.1
68+
IL_0017: sub
69+
IL_0018: callvirt instance void Rotate.Node::growTree(int32)
70+
IL_001d: ldarg.0
71+
IL_001e: newobj instance void Rotate.Node::.ctor()
72+
IL_0023: stfld class Rotate.Node Rotate.Node::m_rightChild
73+
IL_0028: ldarg.0
74+
IL_0029: ldfld class Rotate.Node Rotate.Node::m_rightChild
75+
IL_002e: ldarg.1
76+
IL_002f: ldc.i4.1
77+
IL_0030: sub
78+
IL_0031: callvirt instance void Rotate.Node::growTree(int32)
79+
IL_0036: ret
80+
ldarg.0
81+
starg.s 0 // Force to create a temp for the modifiable this.
82+
IL_0037: ldarg.0
83+
IL_0038: ldarg.0
84+
IL_0039: ldnull
85+
IL_003a: dup
86+
IL_003b: stloc.0
87+
IL_003c: stfld class Rotate.Node Rotate.Node::m_rightChild
88+
IL_0041: ldloc.0
89+
IL_0042: stfld class Rotate.Node Rotate.Node::m_leftChild
90+
IL_0047: ret
91+
} // end of method Node::growTree
92+
93+
.method public hidebysig static int32 Main() cil managed
94+
{
95+
.entrypoint
96+
// Code size 14 (0xe)
97+
.maxstack 8
98+
IL_0000: newobj instance void Rotate.Node::.ctor()
99+
IL_0005: ldc.i4.4
100+
IL_0006: callvirt instance void Rotate.Node::growTree(int32)
101+
IL_000b: ldc.i4.s 100
102+
IL_000d: ret
103+
} // end of method Node::Main
104+
105+
} // end of class Rotate.Node
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
8+
<SchemaVersion>2.0</SchemaVersion>
9+
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
10+
<OutputType>Exe</OutputType>
11+
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
12+
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
13+
</PropertyGroup>
14+
<!-- Default configurations to help VS understand the configurations -->
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
17+
<ItemGroup>
18+
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
19+
<Visible>False</Visible>
20+
</CodeAnalysisDependentAssemblyPaths>
21+
</ItemGroup>
22+
<PropertyGroup>
23+
<DebugType>None</DebugType>
24+
<Optimize>True</Optimize>
25+
</PropertyGroup>
26+
<ItemGroup>
27+
<Compile Include="GitHub_14455.il" />
28+
</ItemGroup>
29+
<ItemGroup>
30+
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
31+
</ItemGroup>
32+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
33+
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
34+
</Project>

0 commit comments

Comments
 (0)