Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 10 additions & 17 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7665,25 +7665,18 @@ void LinearScan::insertUpperVectorRestore(GenTree* tree,
if (tree != nullptr)
{
LIR::Use treeUse;
GenTree* useNode = nullptr;
bool foundUse = blockRange.TryGetUse(tree, &treeUse);
useNode = treeUse.User();
bool foundUse;
GenTree* useNode = tree;

#ifdef TARGET_ARM64
if (refPosition->needsConsecutive && useNode->OperIs(GT_FIELD_LIST))
{
// The tree node requiring consecutive registers are represented as GT_FIELD_LIST.
// When restoring the upper vector, make sure to restore it at the point where
// GT_FIELD_LIST is consumed instead where the individual field is consumed, which
// will always be at GT_FIELD_LIST creation time. That way, we will restore the
// upper vector just before the use of them in the intrinsic.
LIR::Use fieldListUse;
foundUse = blockRange.TryGetUse(useNode, &fieldListUse);
treeUse = fieldListUse;
// Get the use of the node. If the node is contained then the actual use is the containing node
// (which may be much later in the LIR). Repeatedly check until there is no contained node.
do
{
foundUse = blockRange.TryGetUse(useNode, &treeUse);
useNode = treeUse.User();
}
#endif
assert(foundUse);
assert(foundUse);
} while (useNode->isContained());

JITDUMP("before %d.%s:\n", useNode->gtTreeID, GenTree::OpName(useNode->gtOper));

// We need to insert the restore prior to the use, not (necessarily) immediately after the lclVar.
Expand Down
51 changes: 51 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// Generated by Fuzzlyn v3.3 on 2025-08-05 00:20:11
// Run on Arm64 Linux
// Seed: 7831934182807398228-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256,armsve,armsve2
// Reduced from 61.3 KiB to 1.3 KiB in 00:00:54
// Debug: Outputs <14533768479604701151, 1>
// Release: Outputs <14533768479604701151, 0>

using System;
using System.Runtime.CompilerServices;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using Xunit;

public class Runtime_118377
{
public static ulong s_4;
public static ulong F0 = 1;

[MethodImpl(MethodImplOptions.NoInlining)]
private static Vector<ulong> M4()
{
var vr3 = Sve.CreateWhileLessThanMask64Bit(0, 0);
var vr5 = Vector.Create<ulong>(s_4);
var vr1 = Sve.CreateBreakPropagateMask(vr3, vr5);
var vr7 = Vector.Create<ulong>(0);
return Sve.Add(vr1, vr7);
}

[Fact]
public static void TestEntryPoint()
{
if (Sve.IsSupported)
{
var vr4 = F0;
var vr0 = Vector.Create<ulong>(vr4);
var vr8 = Vector128.CreateScalar(14533768479604701152UL).AsVector();
var vr10 = F0;
var vr9 = Vector.Create<ulong>(vr10);
var vr6 = Sve.AbsoluteDifference(vr8, vr9);
var vr11 = M4();
Vector<ulong> var2 = Sve.ConditionalSelect(vr0, vr6, vr11);
Console.WriteLine(var2);
Assert.Equal(14533768479604701151UL, var2[0]);
Assert.Equal(1UL, var2[1]);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Needed for CLRTestEnvironmentVariable -->
<RequiresProcessIsolation>true</RequiresProcessIsolation>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<NoWarn>$(NoWarn);SYSLIB5003</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="0" />
<CLRTestEnvironmentVariable Include="DOTNET_JITMinOpts" Value="0" />
</ItemGroup>
</Project>
Loading