RyuJIT/x86: handle must-init multi-reg vars
authorCarol Eidt <carol.eidt@microsoft.com>
Wed, 19 Oct 2016 18:28:22 +0000 (11:28 -0700)
committerCarol Eidt <carol.eidt@microsoft.com>
Wed, 19 Oct 2016 18:28:22 +0000 (11:28 -0700)
In the RyuJIT backend, lclVars can occupy multiple registers, and not have a stack location. These should be handled for must-init as for lvRegister. The existing code was doing this oinly for _TARGET_64_BIT_ when it should be !LEGACY_BACKEND.
This fixes DevDiv VSO bug 278372

Commit migrated from https://github.com/dotnet/coreclr/commit/9ed511b7d60853fb32938d9cab252fbfeafce85e

src/coreclr/src/jit/codegencommon.cpp
src/coreclr/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.il [new file with mode: 0644]
src/coreclr/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.ilproj [new file with mode: 0644]

index 91977e9..b0a8f68 100755 (executable)
@@ -7027,12 +7027,12 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
             noway_assert(varTypeIsGC(varDsc->TypeGet()) || (varDsc->TypeGet() == TYP_STRUCT) ||
                          compiler->info.compInitMem || compiler->opts.compDbgCode);
 
-#ifdef _TARGET_64BIT_
+#ifndef LEGACY_BACKEND
             if (!varDsc->lvOnFrame)
             {
                 continue;
             }
-#else  // !_TARGET_64BIT_
+#else  // LEGACY_BACKEND
             if (varDsc->lvRegister)
             {
                 if (varDsc->lvOnFrame)
@@ -7048,7 +7048,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
                 }
                 continue;
             }
-#endif // !_TARGET_64BIT_
+#endif // LEGACY_BACKEND
 
             if ((varDsc->TypeGet() == TYP_STRUCT) && !compiler->info.compInitMem &&
                 (varDsc->lvExactSize >= TARGET_POINTER_SIZE))
diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.il b/src/coreclr/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.il
new file mode 100644 (file)
index 0000000..1081877
--- /dev/null
@@ -0,0 +1,156 @@
+// 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.
+
+// This test is a reduced repro case for DevDiv VSO bug 278372.
+// The failure mode is that the RyuJIT/x86 backend was not correctly
+// handling the case of a variable involving a variable V such that:
+//  - V is lvMustInit (therefore it must be undefined on some path)
+//  - V lives in multiple registers, but never on the stack
+//  - there is at least one other variable that is also lvMustInit, but that
+//    has a stack location.
+//
+// In this case, genFnProlog was attempting to zero-init V on the stack.
+//
+// It was difficult to construct a repro; this repro requires that the test
+// be run with COMPlus_JitStressRegs=0x200 (which changes the location of
+// variables at block boundaries).
+
+
+// Metadata version: v4.0.30319
+.assembly extern System.Runtime
+{
+  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:
+  .ver 4:1:0:0
+}
+.assembly extern System.Console
+{
+  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:
+  .ver 4:0:0:0
+}
+.assembly DevDiv_278372
+{
+}
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class private auto ansi beforefieldinit DevDiv_278372
+       extends [System.Runtime]System.Object
+{
+  .method public hidebysig static bool  check(int32& dummy) cil managed noinlining
+  {
+            ldc.i4.1
+            ret
+  } // end of method DevDiv_278372::check
+
+  .method public hidebysig static int32  getX() cil managed noinlining
+  {
+            ldc.i4.s   25
+            ret
+  } // end of method DevDiv_278372::getX
+
+  .method public hidebysig static int32  getY() cil managed noinlining
+  {
+            ldc.i4.5
+            ret
+  } // end of method DevDiv_278372::getY
+
+  .method public hidebysig static int32  Test(int32 x,
+                                              int32 y,
+                                              int32 x2,
+                                              int32 y2,
+                                              int32 x3,
+                                              int32 y3) cil managed noinlining
+  {
+    .maxstack  2
+    .locals init ([0] int32 z,
+             [1] int32 returnVal,
+             [2] int32 dummy,
+             [3] int32 z2)
+
+            // Initialize returnVal to 100
+            ldc.i4.s   100
+            stloc.1
+
+            // Here we pass the address of "dummy" to ensure that we have a must-init on-stack variable.
+            ldloca.s   dummy
+            call       bool DevDiv_278372::check(int32&)
+            brfalse.s  L1
+
+            // Here we are conditionally defining "z", so that it will be must-init
+            ldarg.0
+            ldarg.1
+            rem
+            stloc.0
+    L1:     ldloc.0
+            brfalse.s  L2
+
+            ldc.i4.m1
+            stloc.1
+    L2:     ldarg.2
+            ldarg.3
+            rem
+            stloc.3
+            ldarg.0
+            ldarg.1
+            add
+            stloc.0
+            ldloc.0
+            ldc.i4.s   30
+            beq.s      L3
+
+            ldc.i4.m1
+            stloc.1
+    L3:     ldloc.3
+            brfalse.s  L4
+
+            ldc.i4.m1
+            stloc.1
+    L4:     ldloc.1
+            ldc.i4.s   100
+            bne.un.s   L5
+
+            ldstr      "Pass"
+            call       void [System.Console]System.Console::WriteLine(string)
+            br.s       L6
+
+    L5:     ldstr      "Fail"
+            call       void [System.Console]System.Console::WriteLine(string)
+    L6:     ldloc.1
+            ret
+  } // end of method DevDiv_278372::Test
+
+  .method public hidebysig static int32  Main() cil managed
+  {
+    .entrypoint
+    // Code size       16 (0x10)
+    .maxstack  8
+            ldc.i4.s   25
+            ldc.i4.5
+            ldc.i4.s   25
+            ldc.i4.5
+            ldc.i4.s   25
+            ldc.i4.5
+            call       int32 DevDiv_278372::Test(int32,
+                                                int32,
+                                                int32,
+                                                int32,
+                                                int32,
+                                                int32)
+            ret
+  } // end of method DevDiv_278372::Main
+
+  .method public hidebysig specialname rtspecialname 
+          instance void  .ctor() cil managed
+  {
+    // Code size       7 (0x7)
+    .maxstack  8
+            ldarg.0
+            call       instance void [System.Runtime]System.Object::.ctor()
+            ret
+  } // end of method DevDiv_278372::.ctor
+
+} // end of class DevDiv_278372
+
+
+// =============================================================
diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.ilproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.ilproj
new file mode 100644 (file)
index 0000000..f3da12d
--- /dev/null
@@ -0,0 +1,51 @@
+<?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>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+  </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>None</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="DevDiv_278372.il" />
+  </ItemGroup>
+  <PropertyGroup>
+    <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+set COMPlus_JitStressRegs=0x200
+]]></CLRTestBatchPreCommands>
+  <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+export COMPlus_JitStressRegs=0x200
+]]></BashCLRTestPreCommands>
+  </PropertyGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup> 
+</Project>