Skip to content

Commit b79583c

Browse files
authored
JIT: Properly handle param reg targets with multiple register assignments (#113499)
LSRA can assign different registers to the same local over its lifetime. When this happens for a parameter, there is special logic to ensure that the parameter gets its right initial register assignment. This handling was missing for mapped parameter register targets.
1 parent 599996a commit b79583c

File tree

4 files changed

+91
-13
lines changed

4 files changed

+91
-13
lines changed

src/coreclr/jit/lclvars.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4771,7 +4771,7 @@ bool Compiler::lvaIsPreSpilled(unsigned lclNum, regMaskTP preSpillMask)
47714771
//
47724772
void Compiler::lvaUpdateArgWithInitialReg(LclVarDsc* varDsc)
47734773
{
4774-
noway_assert(varDsc->lvIsParam);
4774+
assert(varDsc->lvIsParam || varDsc->lvIsParamRegTarget);
47754775

47764776
if (varDsc->lvIsRegCandidate())
47774777
{
@@ -4790,20 +4790,11 @@ void Compiler::lvaUpdateArgsWithInitialReg()
47904790
return;
47914791
}
47924792

4793-
for (unsigned lclNum = 0; lclNum < info.compArgsCount; lclNum++)
4793+
for (unsigned lclNum = 0; lclNum < lvaCount; lclNum++)
47944794
{
47954795
LclVarDsc* varDsc = lvaGetDesc(lclNum);
47964796

4797-
if (varDsc->lvPromoted)
4798-
{
4799-
for (unsigned fieldVarNum = varDsc->lvFieldLclStart;
4800-
fieldVarNum < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++fieldVarNum)
4801-
{
4802-
LclVarDsc* fieldVarDsc = lvaGetDesc(fieldVarNum);
4803-
lvaUpdateArgWithInitialReg(fieldVarDsc);
4804-
}
4805-
}
4806-
else
4797+
if (varDsc->lvIsParam || varDsc->lvIsParamRegTarget)
48074798
{
48084799
lvaUpdateArgWithInitialReg(varDsc);
48094800
}

src/coreclr/jit/lsra.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8218,7 +8218,7 @@ void LinearScan::resolveRegisters()
82188218

82198219
// Determine initial position for parameters
82208220

8221-
if (varDsc->lvIsParam)
8221+
if (varDsc->lvIsParam || varDsc->lvIsParamRegTarget)
82228222
{
82238223
SingleTypeRegSet initialRegMask = interval->firstRefPosition->registerAssignment;
82248224
regNumber initialReg = (initialRegMask == RBM_NONE || interval->firstRefPosition->spillAfter)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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+
// Generated by Fuzzlyn v2.5 on 2025-03-13 04:40:20
5+
// Run on Arm Linux
6+
// Seed: 13401882525903110030
7+
// Reduced from 421.9 KiB to 1.1 KiB in 00:03:35
8+
// Hits JIT assert in Release:
9+
// Assertion failed '!"Detected conflicting incoming edges when homing parameter registers"' in 'Program:M42(S0,byte,byte):S0' during 'Generate code' (IL size 83; hash 0x8f48ed9b; FullOpts)
10+
//
11+
// File: /__w/1/s/src/coreclr/jit/codegencommon.cpp Line: 3225
12+
//
13+
using System;
14+
using Xunit;
15+
16+
public class Runtime_113486
17+
{
18+
static IRuntime s_rt;
19+
static S0[,, ] s_14;
20+
static sbyte[][] s_44 = new sbyte[][]
21+
{
22+
new sbyte[]
23+
{
24+
0
25+
}
26+
};
27+
28+
[Fact]
29+
public static void TestEntryPoint()
30+
{
31+
try
32+
{
33+
var vr5 = new S0();
34+
var vr6 = s_44[0][0];
35+
M42(vr5, vr6, 0);
36+
}
37+
catch
38+
{
39+
}
40+
}
41+
42+
static S0 M42(S0 arg0, sbyte arg2, sbyte arg3)
43+
{
44+
for (int var0 = 0; var0 < 1; var0++)
45+
{
46+
ushort var1 = (ushort)(-M44());
47+
arg0.F0 = var1++;
48+
s_rt.WriteLine("c_223", var1);
49+
}
50+
51+
arg3 = arg2;
52+
arg0.F1 = arg0.F0;
53+
s_rt.WriteLine("c_231", arg3);
54+
return arg0;
55+
}
56+
57+
static ushort M44()
58+
{
59+
return s_14[0, 0, 0].F1--;
60+
}
61+
62+
struct S0
63+
{
64+
public ushort F0;
65+
public ushort F1;
66+
}
67+
68+
interface IRuntime
69+
{
70+
void WriteLine<T>(string site, T value);
71+
}
72+
73+
class Runtime : IRuntime
74+
{
75+
public void WriteLine<T>(string site, T value) => System.Console.WriteLine(value);
76+
}
77+
}
78+
79+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Optimize>True</Optimize>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<Compile Include="$(MSBuildProjectName).cs" />
7+
</ItemGroup>
8+
</Project>

0 commit comments

Comments
 (0)