Skip to content

Commit f1bcbeb

Browse files
authored
Arm: Free up upper-half register that was not ready because of its association with busy lower-half register (#107714)
* make sure the upperHalf is moved to ready pool when lowerHalf holding DOUBLE interval is done * remove the logging * added test cases * fix a typo * Add missing Xunit reference * Revert "remove the logging" This reverts commit d8f2f17. * better fix to free up upperHalf if lowerHalf is getting freed up * jit format * Revert "remove the logging" This reverts commit d8f2f17. * Handle upperHalf fix similar to lowerHalf code * formatting * jit format
1 parent d58b1ca commit f1bcbeb

File tree

3 files changed

+348
-8
lines changed

3 files changed

+348
-8
lines changed

src/coreclr/jit/lsra.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9875,24 +9875,40 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
98759875
{
98769876
targetRegsReady.RemoveRegNumFromMask(fromReg);
98779877
}
9878+
9879+
// Since we want to check if we can free upperHalfReg, only do it
9880+
// if lowerHalfReg is ready.
9881+
if (targetRegsReady.IsRegNumInMask(fromReg))
9882+
{
9883+
regNumber upperHalfSrcReg = (regNumber)source[upperHalfReg];
9884+
regNumber upperHalfSrcLoc = (regNumber)location[upperHalfReg];
9885+
// Necessary conditions:
9886+
// - There is a source register for this reg (upperHalfSrcReg != REG_NA)
9887+
// - It is currently free (upperHalfSrcLoc == REG_NA)
9888+
// - The source interval isn't yet completed (sourceIntervals[upperHalfSrcReg] != nullptr)
9889+
// - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg))
9890+
if ((upperHalfSrcReg != REG_NA) && (upperHalfSrcLoc == REG_NA) &&
9891+
(sourceIntervals[upperHalfSrcReg] != nullptr) &&
9892+
!targetRegsFromStack.IsRegNumInMask(upperHalfReg))
9893+
{
9894+
targetRegsReady.AddRegNumInMask(upperHalfReg);
9895+
}
9896+
}
98789897
}
98799898
}
98809899
else if (genIsValidFloatReg(fromReg) && !genIsValidDoubleReg(fromReg))
98819900
{
98829901
// We may have freed up the other half of a double where the lower half
98839902
// was already free.
9884-
regNumber lowerHalfReg = REG_PREV(fromReg);
9885-
regNumber lowerHalfSrcReg = (regNumber)source[lowerHalfReg];
9886-
regNumber lowerHalfSrcLoc = (regNumber)location[lowerHalfReg];
9887-
regMaskTP lowerHalfRegMask = genRegMask(lowerHalfReg);
9903+
regNumber lowerHalfReg = REG_PREV(fromReg);
9904+
regNumber lowerHalfSrcReg = (regNumber)source[lowerHalfReg];
9905+
regNumber lowerHalfSrcLoc = (regNumber)location[lowerHalfReg];
98889906
// Necessary conditions:
98899907
// - There is a source register for this reg (lowerHalfSrcReg != REG_NA)
98909908
// - It is currently free (lowerHalfSrcLoc == REG_NA)
98919909
// - The source interval isn't yet completed (sourceIntervals[lowerHalfSrcReg] != nullptr)
9892-
// - It's not in the ready set ((targetRegsReady & lowerHalfRegMask) ==
9893-
// RBM_NONE)
9894-
// - It's not resolved from stack ((targetRegsFromStack & lowerHalfRegMask) !=
9895-
// lowerHalfRegMask)
9910+
// - It's not in the ready set (!targetRegsReady.IsRegNumInMask(lowerHalfReg))
9911+
// - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(lowerHalfReg))
98969912
if ((lowerHalfSrcReg != REG_NA) && (lowerHalfSrcLoc == REG_NA) &&
98979913
(sourceIntervals[lowerHalfSrcReg] != nullptr) &&
98989914
!targetRegsReady.IsRegNumInMask(lowerHalfReg) &&
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
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.4 on 2024-09-10 14:15:16
5+
// Run on Arm Linux
6+
// Seed: 9455791714420973255
7+
// Reduced from 119.7 KiB to 12.1 KiB in 00:15:49
8+
// Hits JIT assert in Release:
9+
// Assertion failed 'sourceIntervals[targetReg] != nullptr' in 'Program:M8(byref,S0):long' during 'LSRA allocate' (IL size 7341; hash 0x093e6d2a; FullOpts)
10+
//
11+
// File: /__w/1/s/src/coreclr/jit/lsra.cpp Line: 10074
12+
//
13+
using System;
14+
using Xunit;
15+
16+
namespace _107621
17+
{
18+
public struct S0
19+
{
20+
public bool F0;
21+
public long F1;
22+
public long F2;
23+
public float F3;
24+
public byte F5;
25+
public sbyte F6;
26+
public S0(long f2, float f3, double f4, sbyte f6) : this()
27+
{
28+
}
29+
}
30+
31+
public class C0
32+
{
33+
public long F0;
34+
public S0 F2;
35+
public S0 F3;
36+
public long F5;
37+
public C0(double f1, S0 f2, S0 f3, double f4, long f5)
38+
{
39+
}
40+
}
41+
42+
public struct S1
43+
{
44+
public bool F1;
45+
public S0 F2;
46+
public C0 F3;
47+
public byte F4;
48+
public uint F5;
49+
public S1(S0 f2, C0 f3) : this()
50+
{
51+
}
52+
53+
public short M10()
54+
{
55+
return default(short);
56+
}
57+
}
58+
59+
public class Program
60+
{
61+
public static IRuntime s_rt;
62+
public static ulong s_1;
63+
public static C0 s_5 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0);
64+
public static ushort[] s_7;
65+
public static C0 s_11 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0);
66+
67+
[Fact]
68+
public static void TestEntryPoint()
69+
{
70+
try
71+
{
72+
var vr12 = s_11.F2;
73+
M8(ref s_5.F3.F3, vr12);
74+
} catch {}
75+
}
76+
77+
private static long M8(ref float arg0, S0 arg1)
78+
{
79+
double var1 = default(double);
80+
bool var8 = default(bool);
81+
if (arg1.F0)
82+
{
83+
if (M9())
84+
{
85+
sbyte[,,] var0 = new sbyte[,,]
86+
{
87+
{
88+
{
89+
1
90+
}
91+
}
92+
};
93+
arg0 = (arg1.F1 * new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)).M10());
94+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, -1), 0, 0)).M10();
95+
new S1(new S0(0, 0, 0, 0), new C0(-1.7976931348623157E+308d, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)).M10();
96+
s_rt.WriteLine(var0[0, 0, 0]);
97+
s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var1));
98+
byte var3 = arg1.F5++;
99+
var vr7 = new S1[]
100+
{
101+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(-1922739055833068276L, 0, 0, 1), 0, 0)),
102+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0)),
103+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
104+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(-9223372036854775808L, 0, 0, 0), 0, 0)),
105+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
106+
new S1(new S0(9223372036854775807L, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(-9223372036854775808L, 0, 0, 0), 0, 0)),
107+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(3366051754928502355L, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0))
108+
};
109+
ref float vr16 = ref vr7[0].F3.F3.F3;
110+
vr16 = (s_1 >> s_7[0]--);
111+
var vr8 = new S1[]
112+
{
113+
new S1(new S0(-7780288970767849613L, 0, 0, 127), new C0(0, new S0(-7247354589903316995L, 0, 0, 1), new S0(3332629451991572720L, 0, 0, 0), 0, 0)),
114+
new S1(new S0(9223372036854775806L, 0, 0, 0), new C0(0, new S0(56844987229889904L, 0, 0, 0), new S0(9223372036854775806L, 3.4028235E+38f, 0, -49), 0, -2954444398035812513L)),
115+
new S1(new S0(9223372036854775807L, 0, 0, -127), new C0(0, new S0(9223372036854775807L, 0, 0, -127), new S0(-8108349655554254125L, 0, 0, -128), 0, 0))
116+
};
117+
float vr19 = vr8[0].F3.F3.F3;
118+
C0 var4 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0);
119+
s_rt.WriteLine(var3);
120+
s_rt.WriteLine(var4.F0);
121+
s_rt.WriteLine(var4.F2.F0);
122+
s_rt.WriteLine(var4.F2.F5);
123+
s_rt.WriteLine(var4.F3.F0);
124+
s_rt.WriteLine(var4.F3.F1);
125+
s_rt.WriteLine(var4.F3.F2);
126+
s_rt.WriteLine(var4.F3.F5);
127+
s_rt.WriteLine(var4.F5);
128+
}
129+
130+
for (int var5 = 0; var5 < 2; var5++)
131+
{
132+
var vr5 = new S1[]
133+
{
134+
new S1(new S0(0, 1, 1, 0), new C0(0, new S0(0, 1, -1, 0), new S0(0, 1, -2261.3113161007714d, 1), 0, 0)),
135+
new S1(new S0(0, 1, 0, 0), new C0(0, new S0(0, 3.4028235E+38f, -1.7976931348623157E+308d, 0), new S0(0, 0, 0, 0), 0, 0)),
136+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
137+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
138+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
139+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
140+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0))
141+
};
142+
}
143+
144+
S1 var6 = new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, -1), 0, 0));
145+
s_rt.WriteLine(var6.F1);
146+
s_rt.WriteLine(var6.F2.F0);
147+
s_rt.WriteLine(var6.F2.F2);
148+
s_rt.WriteLine(var6.F2.F5);
149+
s_rt.WriteLine(var6.F2.F6);
150+
s_rt.WriteLine(var6.F3.F0);
151+
s_rt.WriteLine(var6.F3.F2.F0);
152+
s_rt.WriteLine(var6.F3.F2.F2);
153+
s_rt.WriteLine(var6.F3.F2.F5);
154+
s_rt.WriteLine(var6.F3.F2.F6);
155+
s_rt.WriteLine(var6.F3.F3.F0);
156+
s_rt.WriteLine(var6.F3.F3.F5);
157+
s_rt.WriteLine(var6.F3.F3.F6);
158+
s_rt.WriteLine(var6.F3.F5);
159+
s_rt.WriteLine(var6.F4);
160+
s_rt.WriteLine(var6.F5);
161+
}
162+
else
163+
{
164+
var vr6 = new S1[]
165+
{
166+
new S1(new S0(0, -1, -1.7976931348623157E+308d, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, -1, 0, 0), 1, 0)),
167+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 3.4028235E+38f, 0, 0), 0, 0)),
168+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)),
169+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)),
170+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0))
171+
};
172+
float vr22 = vr6[0].F3.F3.F3;
173+
arg1.F5 = (byte)vr22;
174+
C0 var7 = new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0);
175+
var7.F3.F3--;
176+
s_7 = new ushort[]
177+
{
178+
1
179+
};
180+
sbyte[] var9 = new sbyte[]
181+
{
182+
1
183+
};
184+
if (s_5.F2.F0)
185+
{
186+
uint[] var10 = new uint[]
187+
{
188+
0,
189+
1,
190+
0,
191+
0,
192+
0,
193+
0,
194+
0,
195+
0
196+
};
197+
var vr1 = new S1[]
198+
{
199+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0)),
200+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
201+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
202+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, -1), 0, 0))
203+
};
204+
sbyte var11 = (sbyte)(var10[0] - M11(vr1));
205+
s_rt.WriteLine(var10[0]);
206+
s_rt.WriteLine(var11);
207+
}
208+
else
209+
{
210+
ulong[] var12 = new ulong[]
211+
{
212+
1
213+
};
214+
s_rt.WriteLine(var12[0]);
215+
}
216+
217+
if (s_5.F2.F0)
218+
{
219+
var vr3 = new S1[]
220+
{
221+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
222+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
223+
new S1(new S0(0, 0, -1, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
224+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, -1), new S0(0, 0, 0, 0), 0, 0)),
225+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
226+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 1), 0, 0)),
227+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
228+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0))
229+
};
230+
C0[] var13 = new C0[]
231+
{
232+
new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0),
233+
new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)
234+
};
235+
s_rt.WriteLine(var13[0].F0);
236+
s_rt.WriteLine(var13[0].F2.F1);
237+
s_rt.WriteLine(var13[0].F2.F2);
238+
s_rt.WriteLine(var13[0].F2.F5);
239+
s_rt.WriteLine(var13[0].F2.F6);
240+
s_rt.WriteLine(var13[0].F3.F0);
241+
s_rt.WriteLine(var13[0].F3.F1);
242+
s_rt.WriteLine(var13[0].F3.F2);
243+
s_rt.WriteLine(var13[0].F3.F5);
244+
s_rt.WriteLine(var13[0].F3.F6);
245+
s_rt.WriteLine(var13[0].F5);
246+
}
247+
else
248+
{
249+
return arg1.F2++;
250+
}
251+
252+
var7.F3.F3 = var7.F2.F3--;
253+
float var14 = arg1.F3;
254+
s_rt.WriteLine(System.BitConverter.SingleToUInt32Bits(var14));
255+
s_rt.WriteLine(var8);
256+
var vr9 = new S1[]
257+
{
258+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
259+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
260+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
261+
new S1(new S0(0, 0, 0, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
262+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)),
263+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 1), new S0(0, 0, 0, 0), 0, 0)),
264+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0))
265+
};
266+
var vr10 = new S1[]
267+
{
268+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0)),
269+
new S1(new S0(0, 0, 1, 1), new C0(0, new S0(0, 0, 0, 0), new S0(0, 0, 0, 0), 0, 0))
270+
};
271+
s_rt.WriteLine(var7.F0);
272+
s_rt.WriteLine(var7.F2.F0);
273+
s_rt.WriteLine(var7.F2.F1);
274+
s_rt.WriteLine(var7.F2.F2);
275+
s_rt.WriteLine(var7.F2.F5);
276+
s_rt.WriteLine(var7.F2.F6);
277+
s_rt.WriteLine(var7.F3.F0);
278+
s_rt.WriteLine(var7.F3.F1);
279+
s_rt.WriteLine(var7.F3.F5);
280+
s_rt.WriteLine(var7.F3.F6);
281+
s_rt.WriteLine(var7.F5);
282+
}
283+
284+
for (int var15 = 0; var15 < 1; var15++)
285+
{
286+
var vr2 = new S1[]
287+
{
288+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 0, -1.7976931348623157E+308d, 0), new S0(0, 0, 0, 0), 0, 0)),
289+
new S1(new S0(0, 0, 0, 0), new C0(0, new S0(0, 3.4028235E+38f, 0, 0), new S0(0, 0, 0, 0), 0, 0))
290+
};
291+
}
292+
293+
return 0;
294+
}
295+
296+
private static bool M9()
297+
{
298+
return default(bool);
299+
}
300+
301+
private static ref float M11(S1[] arg0)
302+
{
303+
return ref arg0[0].F3.F3.F3;
304+
}
305+
}
306+
307+
public interface IRuntime
308+
{
309+
void WriteLine<T>(T value);
310+
}
311+
312+
public class Runtime : IRuntime
313+
{
314+
public void WriteLine<T>(T value) => System.Console.WriteLine(value);
315+
}
316+
}
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)