Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Handle a restored double Interval at block boundary
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
CarolEidt committed Feb 22, 2018
1 parent a231c3a commit ac62c2b
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
74 changes: 74 additions & 0 deletions tests/src/JIT/Regression/JitBlue/DevDiv_541653/DevDiv_541653.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
<OutputType>Exe</OutputType>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
<Visible>False</Visible>
</CodeAnalysisDependentAssemblyPaths>
</ItemGroup>
<PropertyGroup>
<DebugType></DebugType>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
</PropertyGroup>
</Project>

0 comments on commit ac62c2b

Please sign in to comment.