Skip to content

Commit 0787787

Browse files
authored
Restore registers at the head of chains of contained nodes (dotnet#118430)
Fixes dotnet#118377
1 parent 0f7b74b commit 0787787

File tree

3 files changed

+75
-17
lines changed

3 files changed

+75
-17
lines changed

src/coreclr/jit/lsra.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7665,25 +7665,18 @@ void LinearScan::insertUpperVectorRestore(GenTree* tree,
76657665
if (tree != nullptr)
76667666
{
76677667
LIR::Use treeUse;
7668-
GenTree* useNode = nullptr;
7669-
bool foundUse = blockRange.TryGetUse(tree, &treeUse);
7670-
useNode = treeUse.User();
7668+
bool foundUse;
7669+
GenTree* useNode = tree;
76717670

7672-
#ifdef TARGET_ARM64
7673-
if (refPosition->needsConsecutive && useNode->OperIs(GT_FIELD_LIST))
7674-
{
7675-
// The tree node requiring consecutive registers are represented as GT_FIELD_LIST.
7676-
// When restoring the upper vector, make sure to restore it at the point where
7677-
// GT_FIELD_LIST is consumed instead where the individual field is consumed, which
7678-
// will always be at GT_FIELD_LIST creation time. That way, we will restore the
7679-
// upper vector just before the use of them in the intrinsic.
7680-
LIR::Use fieldListUse;
7681-
foundUse = blockRange.TryGetUse(useNode, &fieldListUse);
7682-
treeUse = fieldListUse;
7671+
// Get the use of the node. If the node is contained then the actual use is the containing node
7672+
// (which may be much later in the LIR). Repeatedly check until there is no contained node.
7673+
do
7674+
{
7675+
foundUse = blockRange.TryGetUse(useNode, &treeUse);
76837676
useNode = treeUse.User();
7684-
}
7685-
#endif
7686-
assert(foundUse);
7677+
assert(foundUse);
7678+
} while (useNode->isContained());
7679+
76877680
JITDUMP("before %d.%s:\n", useNode->gtTreeID, GenTree::OpName(useNode->gtOper));
76887681

76897682
// We need to insert the restore prior to the use, not (necessarily) immediately after the lclVar.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 v3.3 on 2025-08-05 00:20:11
5+
// Run on Arm64 Linux
6+
// Seed: 7831934182807398228-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256,armsve,armsve2
7+
// Reduced from 61.3 KiB to 1.3 KiB in 00:00:54
8+
// Debug: Outputs <14533768479604701151, 1>
9+
// Release: Outputs <14533768479604701151, 0>
10+
11+
using System;
12+
using System.Runtime.CompilerServices;
13+
using System.Numerics;
14+
using System.Runtime.Intrinsics;
15+
using System.Runtime.Intrinsics.Arm;
16+
using Xunit;
17+
18+
public class Runtime_118377
19+
{
20+
public static ulong s_4;
21+
public static ulong F0 = 1;
22+
23+
[MethodImpl(MethodImplOptions.NoInlining)]
24+
private static Vector<ulong> M4()
25+
{
26+
var vr3 = Sve.CreateWhileLessThanMask64Bit(0, 0);
27+
var vr5 = Vector.Create<ulong>(s_4);
28+
var vr1 = Sve.CreateBreakPropagateMask(vr3, vr5);
29+
var vr7 = Vector.Create<ulong>(0);
30+
return Sve.Add(vr1, vr7);
31+
}
32+
33+
[Fact]
34+
public static void TestEntryPoint()
35+
{
36+
if (Sve.IsSupported)
37+
{
38+
var vr4 = F0;
39+
var vr0 = Vector.Create<ulong>(vr4);
40+
var vr8 = Vector128.CreateScalar(14533768479604701152UL).AsVector();
41+
var vr10 = F0;
42+
var vr9 = Vector.Create<ulong>(vr10);
43+
var vr6 = Sve.AbsoluteDifference(vr8, vr9);
44+
var vr11 = M4();
45+
Vector<ulong> var2 = Sve.ConditionalSelect(vr0, vr6, vr11);
46+
Console.WriteLine(var2);
47+
Assert.Equal(14533768479604701151UL, var2[0]);
48+
Assert.Equal(1UL, var2[1]);
49+
}
50+
}
51+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<!-- Needed for CLRTestEnvironmentVariable -->
4+
<RequiresProcessIsolation>true</RequiresProcessIsolation>
5+
<DebugType>None</DebugType>
6+
<Optimize>True</Optimize>
7+
<NoWarn>$(NoWarn);SYSLIB5003</NoWarn>
8+
</PropertyGroup>
9+
<ItemGroup>
10+
<Compile Include="$(MSBuildProjectName).cs" />
11+
<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="0" />
12+
<CLRTestEnvironmentVariable Include="DOTNET_JITMinOpts" Value="0" />
13+
</ItemGroup>
14+
</Project>

0 commit comments

Comments
 (0)