From: Carol Eidt Date: Thu, 22 Feb 2018 22:31:02 +0000 (-0800) Subject: Handle a restored double Interval at block boundary X-Git-Tag: accepted/tizen/unified/20190422.045933~2899^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ac62c2b083da7c60c9477fd1dab9f562eeec8e4c;p=platform%2Fupstream%2Fcoreclr.git Handle a restored double Interval at block boundary During the process of freeing registers that are no longer live at the start of a new block, we may restore a 'previousInterval'. If that is a double (and the freed interval was float), we need to skip the next float. --- diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp index 4898968..5687db9 100644 --- a/src/jit/lsra.cpp +++ b/src/jit/lsra.cpp @@ -4957,6 +4957,12 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock, bool alloc } #ifdef _TARGET_ARM_ + // unassignPhysReg, above, may have restored a 'previousInterval', in which case we need to + // get the value of 'physRegRecord->assignedInterval' rather than using 'assignedInterval'. + if (physRegRecord->assignedInterval != nullptr) + { + assignedInterval = physRegRecord->assignedInterval; + } if (assignedInterval->registerType == TYP_DOUBLE) { // Skip next float register, because we already addressed a double register diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_541653/DevDiv_541653.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_541653/DevDiv_541653.cs new file mode 100644 index 0000000..eac3182 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/DevDiv_541653/DevDiv_541653.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// + +// The bug captured by this test was a case where: +// - We have a double register pair that was previous occupied by a double lclVar. +// - That lclVar becomes dead, but has subsequent references, so it remains as the +// previousInterval on the RegRecord. +// - The first float half is then assigned to another lclVar. It is live across a +// loop backedge, so it is live at the end of the loop, but is then released before +// the next block is allocated. +// - At this time, the double lclVar is restored to that RegRecord (as inactive), but +// the loop over the lclVars sees only the second half, and asserts because it doesn't +// expect to ever encounter an interval in the second half (it should have been skipped). + +using System; +using System.Runtime.CompilerServices; + +public class DevDiv_541643 +{ + public const int Pass = 100; + public const int Fail = -1; + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static float GetFloat(int i) + { + return (float)i; + } + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static double GetDouble(int i) + { + return (double)i; + } + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static int GetInt(float f) + { + return (int)f; + } + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static int GetInt(double d) + { + return (int)d; + } + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static int test(int count) + { + double d = GetDouble(0); + // Use d; it will be dead until we redefine it below. + int result = (int)d; + + // Now define our float lclVar and use it in a loop. + float f = GetFloat(1); + for (int i = 0; i < count; i++) + { + result += GetInt(f); + } + + // Finally, redefine d and use it. + d = GetDouble(3); + for (int i = 0; i < count; i++) + { + result += GetInt(d); + } + + Console.WriteLine("Result: " + result); + return result; + } + public static int Main() + { + int result = test(10); + return Pass; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_541653/DevDiv_541653.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_541653/DevDiv_541653.csproj new file mode 100644 index 0000000..6d58ab0 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/DevDiv_541653/DevDiv_541653.csproj @@ -0,0 +1,37 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + + + False + + + + + True + + + + + + + + + + +