Skip to content

Commit 0e17421

Browse files
Fix numbering of exposed LCL_VARs (#79772)
* Fix numbering of exposed LCL_VARs The conservative VN must be unique for different uses lest we risk running into memory safety issues, by, e. g. removing range checks based on "racy" data. * Add a test Without the fix, 4 out of 5 runs fail on my machine. * Succeed the test on platforms without threads No threading => no races. * Disable on Mono interp
1 parent d4feb5b commit 0e17421

File tree

4 files changed

+110
-1
lines changed

4 files changed

+110
-1
lines changed

src/coreclr/jit/valuenum.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8827,7 +8827,8 @@ void Compiler::fgValueNumberTree(GenTree* tree)
88278827
vnStore->VNForIntPtrCon(lcl->GetLclOffs()));
88288828
ValueNum loadVN = fgValueNumberByrefExposedLoad(lcl->TypeGet(), addrVN);
88298829

8830-
lcl->gtVNPair.SetBoth(loadVN);
8830+
lcl->gtVNPair.SetLiberal(loadVN);
8831+
lcl->gtVNPair.SetConservative(vnStore->VNForExpr(compCurBB, lcl->TypeGet()));
88318832
}
88328833
else
88338834
{
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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.Threading;
6+
using System.Runtime.InteropServices;
7+
using System.Runtime.CompilerServices;
8+
9+
unsafe class ExposedLocalsNumbering
10+
{
11+
private static volatile bool s_mutateIndex;
12+
private static volatile bool s_finished;
13+
private static int* s_pIndex = (int*)NativeMemory.Alloc(4);
14+
15+
public static int Main()
16+
{
17+
const int RetryCount = 100;
18+
const int UnsafeIndex = 1;
19+
20+
try
21+
{
22+
new Thread(_ =>
23+
{
24+
while (!s_finished)
25+
{
26+
if (s_mutateIndex)
27+
{
28+
*s_pIndex = UnsafeIndex;
29+
}
30+
}
31+
}).Start();
32+
}
33+
catch (PlatformNotSupportedException)
34+
{
35+
return 100;
36+
}
37+
38+
int[] array = new int[UnsafeIndex + 1];
39+
array[UnsafeIndex] = 1;
40+
41+
int safeIndex = 0;
42+
for (int i = 0; i < RetryCount; i++)
43+
{
44+
try
45+
{
46+
if (RunBoundsChecks(array.AsSpan(0, UnsafeIndex), &safeIndex) != 0)
47+
{
48+
s_finished = true;
49+
return 101;
50+
}
51+
}
52+
catch (IndexOutOfRangeException) { }
53+
}
54+
55+
s_finished = true;
56+
return 100;
57+
}
58+
59+
[MethodImpl(MethodImplOptions.NoInlining)]
60+
private static int RunBoundsChecks(Span<int> span, int* pSafeIndex)
61+
{
62+
int result = 0;
63+
int index = 0;
64+
CaptureIndex(&index);
65+
66+
result += span[index];
67+
result += span[index];
68+
result += span[index];
69+
result += span[index];
70+
71+
result += span[index];
72+
result += span[index];
73+
result += span[index];
74+
result += span[index];
75+
76+
result += span[index];
77+
result += span[index];
78+
result += span[index];
79+
result += span[index];
80+
81+
s_pIndex = pSafeIndex;
82+
s_mutateIndex = false;
83+
84+
return result;
85+
}
86+
87+
[MethodImpl(MethodImplOptions.NoInlining)]
88+
private static void CaptureIndex(int* pIndex)
89+
{
90+
s_pIndex = pIndex;
91+
s_mutateIndex = true;
92+
}
93+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<DebugType>None</DebugType>
5+
<Optimize>True</Optimize>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<Compile Include="$(MSBuildProjectName).cs" />
10+
<CLRTestEnvironmentVariable Include="DOTNET_JitNoCSE" Value="1" />
11+
</ItemGroup>
12+
</Project>

src/tests/issues.targets

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,9 @@
26032603
<ExcludeList Include = "$(XunitTestBinBase)/JIT/Regression/JitBlue/Runtime_74635/Runtime_74635/**">
26042604
<Issue>https://github.com/dotnet/runtime/issues/74687</Issue>
26052605
</ExcludeList>
2606+
<ExcludeList Include = "$(XunitTestBinBase)/JIT/opt/ValueNumbering/ExposedLocalsNumbering/ExposedLocalsNumbering/**">
2607+
<Issue>https://github.com/dotnet/runtime/issues/80184</Issue>
2608+
</ExcludeList>
26062609
<!-- End interpreter issues -->
26072610
</ItemGroup>
26082611

0 commit comments

Comments
 (0)