diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 787a93c5721256..9370e2f6501679 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -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. diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.cs b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.cs new file mode 100644 index 00000000000000..c49e208881cd20 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.cs @@ -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 M4() + { + var vr3 = Sve.CreateWhileLessThanMask64Bit(0, 0); + var vr5 = Vector.Create(s_4); + var vr1 = Sve.CreateBreakPropagateMask(vr3, vr5); + var vr7 = Vector.Create(0); + return Sve.Add(vr1, vr7); + } + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + var vr4 = F0; + var vr0 = Vector.Create(vr4); + var vr8 = Vector128.CreateScalar(14533768479604701152UL).AsVector(); + var vr10 = F0; + var vr9 = Vector.Create(vr10); + var vr6 = Sve.AbsoluteDifference(vr8, vr9); + var vr11 = M4(); + Vector var2 = Sve.ConditionalSelect(vr0, vr6, vr11); + Console.WriteLine(var2); + Assert.Equal(14533768479604701151UL, var2[0]); + Assert.Equal(1UL, var2[1]); + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.csproj new file mode 100644 index 00000000000000..532bf97e96111e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_118377/Runtime_118377.csproj @@ -0,0 +1,14 @@ + + + + true + None + True + $(NoWarn);SYSLIB5003 + + + + + + +