JIT: make sure to set compLongUsed during struct promotion (#32702)
authorAndy Ayers <andya@microsoft.com>
Mon, 24 Feb 2020 19:31:15 +0000 (11:31 -0800)
committerGitHub <noreply@github.com>
Mon, 24 Feb 2020 19:31:15 +0000 (11:31 -0800)
If we're promoting a long field, make sure `compLongUsed` gets set.
Otherwise we may fail to properly decompose a long later on.

Fixes #32059.

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

index 9c83a26..d0d00b7 100644 (file)
@@ -2103,7 +2103,7 @@ bool Compiler::StructPromotionHelper::TryPromoteStructField(lvaStructFieldInfo&
 //
 void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum)
 {
-    LclVarDsc* varDsc = &compiler->lvaTable[lclNum];
+    LclVarDsc* varDsc = compiler->lvaGetDesc(lclNum);
 
     // We should never see a reg-sized non-field-addressed struct here.
     assert(!varDsc->lvRegStruct);
@@ -2167,11 +2167,13 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum)
 #endif
 
         // Lifetime of field locals might span multiple BBs, so they must be long lifetime temps.
-        unsigned varNum = compiler->lvaGrabTemp(false DEBUGARG(bufp));
+        const unsigned varNum = compiler->lvaGrabTemp(false DEBUGARG(bufp));
 
-        varDsc = &compiler->lvaTable[lclNum]; // lvaGrabTemp can reallocate the lvaTable
+        // lvaGrabTemp can reallocate the lvaTable, so
+        // refresh the cached varDsc for lclNum.
+        varDsc = compiler->lvaGetDesc(lclNum);
 
-        LclVarDsc* fieldVarDsc       = &compiler->lvaTable[varNum];
+        LclVarDsc* fieldVarDsc       = compiler->lvaGetDesc(varNum);
         fieldVarDsc->lvType          = pFieldInfo->fldType;
         fieldVarDsc->lvExactSize     = pFieldInfo->fldSize;
         fieldVarDsc->lvIsStructField = true;
@@ -2180,6 +2182,13 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum)
         fieldVarDsc->lvFldOrdinal    = pFieldInfo->fldOrdinal;
         fieldVarDsc->lvParentLcl     = lclNum;
         fieldVarDsc->lvIsParam       = varDsc->lvIsParam;
+
+        // This new local may be the first time we've seen a long typed local.
+        if (fieldVarDsc->lvType == TYP_LONG)
+        {
+            compiler->compLongUsed = true;
+        }
+
 #if defined(TARGET_AMD64) || defined(TARGET_ARM64)
 
         // Reset the implicitByRef flag.
diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_32059/Runtime_32059.il b/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_32059/Runtime_32059.il
new file mode 100644 (file)
index 0000000..b72b585
--- /dev/null
@@ -0,0 +1,71 @@
+// 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.
+//
+
+.assembly extern System.Runtime {}
+.assembly Runtime_32059 {}
+
+.class private auto ansi beforefieldinit Runtime_32059 extends [System.Runtime]System.Object
+{
+
+.method public hidebysig static int32 Main(string[] args) cil managed
+{
+  .entrypoint
+  .locals init (valuetype [System.Runtime]System.DateTime V_0)
+  .maxstack 12
+  ldarg.0
+  ldnull
+  ldnull
+  ldnull
+  ldnull
+  ldnull
+  ldnull
+  ldnull
+  ldloc.0
+  ldc.i4.0
+  ldnull
+  newobj     instance void Runtime_32059::.ctor(string[],
+                                           string,
+                                           string,
+                                           string,
+                                           string,
+                                           string,
+                                           string,
+                                           string,
+                                           valuetype [System.Runtime]System.DateTime,
+                                           int32,
+                                           string)
+  tail.
+  call       instance int32 Runtime_32059::F()
+  ret
+}
+
+.method public specialname rtspecialname instance void .ctor(string[] o,
+                             string h,
+                             string g,
+                             string f,
+                             string e,
+                             string d,
+                             string c,
+                             string b,
+                             valuetype [System.Runtime]System.DateTime a,
+                             int32 pc,
+                             string current) cil managed  noinlining
+{
+  ldarg.0
+  call instance void [System.Runtime]System.Object::.ctor()
+  ret
+} 
+
+.method public hidebysig instance int32 F() cil managed noinlining
+{
+  ldc.i4 100
+  ret
+}
+}
+
+
+
+
+
diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_32059/Runtime_32059.ilproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/Runtime_32059/Runtime_32059.ilproj
new file mode 100644 (file)
index 0000000..e7c67cc
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk.IL">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <PropertyGroup>
+    <DebugType>None</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).il" />
+  </ItemGroup>
+</Project>