Skip to content

Commit df0930c

Browse files
authored
JIT: don't dead store OSR exposed locals (#89867)
Backport of #89743 to 7.0. The local var ref count for OSR locals can be misleading, since some of the appearances may be in the "tier0" parts of the methods and won't be visible once we trim the OSR method down to just the part we're going to compile. Fix by giving OSR-exposed locals an implicit ref count. Fixes #89666.
1 parent 078e669 commit df0930c

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

src/coreclr/jit/lclvars.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,12 @@ void Compiler::lvaInitTypeRef()
356356
{
357357
lvaSetVarAddrExposed(lclNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
358358
}
359+
360+
// Ensure that ref counts for exposed OSR locals take into account
361+
// that some of the refs might be in the Tier0 parts of the method
362+
// that get trimmed away.
363+
//
364+
varDsc->lvImplicitlyReferenced = 1;
359365
}
360366
}
361367
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
7+
8+
public class Runtime_89666
9+
{
10+
public static int Main()
11+
{
12+
byte[] a1 = new byte[100_000];
13+
byte[] a2 = new byte[100_000];
14+
15+
Problem(a1.Length, a1);
16+
Problem(a2.Length, a2);
17+
18+
for (int i = 0; i < a1.Length; i++)
19+
{
20+
if (a1[i] != a2[i])
21+
{
22+
Console.WriteLine($"Found diff at {i}: {a1[i]} != {a2[i]}");
23+
return -1;
24+
}
25+
}
26+
return 100;
27+
}
28+
29+
[MethodImpl(MethodImplOptions.NoInlining)]
30+
static void Problem(int n, byte[] a)
31+
{
32+
Random random = new Random(1);
33+
int value = 0;
34+
Span<byte> span = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref value, 1));
35+
for (int i = 0; i < n; i++)
36+
{
37+
// This write must be kept in the OSR method
38+
value = random.Next();
39+
Write(span, i, a);
40+
}
41+
}
42+
43+
[MethodImpl(MethodImplOptions.NoInlining)]
44+
static void Write(Span<byte> s, int i, byte[] a)
45+
{
46+
a[i] = s[0];
47+
}
48+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<!-- Needed for CLRTestEnvironmentVariable -->
4+
<RequiresProcessIsolation>true</RequiresProcessIsolation>
5+
<DebugType />
6+
<Optimize>True</Optimize>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<Compile Include="$(MSBuildProjectName).cs" />
10+
<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="1" />
11+
<CLRTestEnvironmentVariable Include="DOTNET_TieredPGO" Value="0" />
12+
<CLRTestEnvironmentVariable Include="DOTNET_TC_QuickJitForLoops" Value="1" />
13+
<CLRTestEnvironmentVariable Include="DOTNET_TC_OnStackReplacement" Value="1" />
14+
</ItemGroup>
15+
</Project>

0 commit comments

Comments
 (0)