Skip to content

Commit 6627183

Browse files
authored
JIT: block some struct promotion for OSR (#67131)
This undoes part of #65903. OSR methods can't rely solely on their own analysis for struct promotion as they only see parts of methods.
1 parent 938f2e3 commit 6627183

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

src/coreclr/jit/lclvars.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,14 @@ bool Compiler::StructPromotionHelper::CanPromoteStructVar(unsigned lclNum)
18511851
return false;
18521852
}
18531853

1854+
// If the local was exposed at Tier0, we currently have to assume it's aliased for OSR.
1855+
//
1856+
if (compiler->lvaIsOSRLocal(lclNum) && compiler->info.compPatchpointInfo->IsExposed(lclNum))
1857+
{
1858+
JITDUMP(" struct promotion of V%02u is disabled because it is an exposed OSR local\n", lclNum);
1859+
return false;
1860+
}
1861+
18541862
CORINFO_CLASS_HANDLE typeHnd = varDsc->GetStructHnd();
18551863
assert(typeHnd != NO_CLASS_HANDLE);
18561864

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
interface IFoo
9+
{
10+
public Span<object> AsSpan();
11+
}
12+
13+
public struct ObjectSequence1 : IFoo
14+
{
15+
public object Value1;
16+
17+
public Span<object> AsSpan()
18+
{
19+
return MemoryMarshal.CreateSpan(ref Value1, 1);
20+
}
21+
}
22+
23+
public struct ObjectSequenceMany : IFoo
24+
{
25+
public object[] _values;
26+
27+
public Span<object> AsSpan()
28+
{
29+
return _values.AsSpan();
30+
}
31+
32+
public ObjectSequenceMany(object[] x)
33+
{
34+
_values = x;
35+
}
36+
}
37+
38+
public class InvalidPromotion
39+
{
40+
[MethodImpl(MethodImplOptions.NoInlining)]
41+
static bool G<T>(int n) where T : IFoo
42+
{
43+
// OSR cannot safely promote values
44+
T values = default;
45+
46+
if (values is ObjectSequenceMany)
47+
{
48+
values = (T)(object)new ObjectSequenceMany(new object[5]);
49+
}
50+
51+
Span<object> indexedValues = values.AsSpan();
52+
53+
// For a patchpoint here.
54+
for (int i = 0; i < n; i++)
55+
{
56+
indexedValues[i] = "foo";
57+
}
58+
59+
if (values is ObjectSequence1)
60+
{
61+
return (indexedValues[0] == ((ObjectSequence1)(object)values).Value1);
62+
}
63+
64+
return false;
65+
}
66+
67+
public static int Main()
68+
{
69+
return G<ObjectSequence1>(1) ? 100 : -1;
70+
}
71+
}
72+
73+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<DebugType />
5+
<Optimize>True</Optimize>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<Compile Include="$(MSBuildProjectName).cs" />
9+
</ItemGroup>
10+
<PropertyGroup>
11+
<CLRTestBatchPreCommands><![CDATA[
12+
$(CLRTestBatchPreCommands)
13+
set COMPlus_TieredCompilation=1
14+
set COMPlus_TC_QuickJitForLoops=1
15+
set COMPlus_TC_OnStackReplacement=1
16+
set COMPlus_OSR_HitLimit=1
17+
set COMPlus_TC_OnStackReplacement=1
18+
set COMPlus_TC_OnStackReplacement_InitialCounter=1
19+
]]></CLRTestBatchPreCommands>
20+
<BashCLRTestPreCommands><![CDATA[
21+
$(BashCLRTestPreCommands)
22+
export COMPlus_TieredCompilation=1
23+
export COMPlus_TC_QuickJitForLoops=1
24+
export COMPlus_TC_OnStackReplacement=1
25+
export COMPlus_OSR_HitLimit=1
26+
export COMPlus_TC_OnStackReplacement=1
27+
export COMPlus_TC_OnStackReplacement_InitialCounter=1
28+
]]></BashCLRTestPreCommands>
29+
</PropertyGroup>
30+
</Project>

0 commit comments

Comments
 (0)