From: Sergey Andreenko Date: Thu, 16 Nov 2017 18:38:46 +0000 (-0800) Subject: Fix 14455: _opt_relrotarg_valref test failure on amd64. (#15032) X-Git-Tag: accepted/tizen/base/20180629.140029~552 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=88527bb6bdec8662a5cef5efcadb22c7fcabae50;p=platform%2Fupstream%2Fcoreclr.git Fix 14455: _opt_relrotarg_valref test failure on amd64. (#15032) * fix the issue Do not zero-initialize temps, that were created by jit and do not have GC refs. The confusion was that `varDsc->lvIsTemp` means `short live` variable, when we wanted to ask is it IL temp or not. * add a non-stress repro. --- diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index c8e4322..f6a05de 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -8104,7 +8104,7 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa // If compInitMem is set, we may need to zero-initialize some locals. Normally it's done in the prolog // but this loop can't include the prolog. Since we don't have liveness information, we insert zero-initialization - // for all non-parameter non-temp locals as well as temp structs with GC fields. + // for all non-parameter IL locals as well as temp structs with GC fields. // Liveness phase will remove unnecessary initializations. if (info.compInitMem) { @@ -8112,14 +8112,15 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa LclVarDsc* varDsc; for (varNum = 0, varDsc = lvaTable; varNum < lvaCount; varNum++, varDsc++) { - var_types lclType = varDsc->TypeGet(); if (!varDsc->lvIsParam) { - if (!varDsc->lvIsTemp || ((lclType == TYP_STRUCT) && (varDsc->lvStructGcCount > 0))) + var_types lclType = varDsc->TypeGet(); + bool isUserLocal = (varNum < info.compLocalsCount); + bool structWithGCFields = ((lclType == TYP_STRUCT) && (varDsc->lvStructGcCount > 0)); + if (isUserLocal || structWithGCFields) { - var_types lclType = varDsc->TypeGet(); - GenTreePtr lcl = gtNewLclvNode(varNum, lclType); - GenTreePtr init = nullptr; + GenTreePtr lcl = gtNewLclvNode(varNum, lclType); + GenTreePtr init = nullptr; if (lclType == TYP_STRUCT) { const bool isVolatile = false; diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_14455/GitHub_14455.il b/tests/src/JIT/Regression/JitBlue/GitHub_14455/GitHub_14455.il new file mode 100644 index 0000000..5573099 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_14455/GitHub_14455.il @@ -0,0 +1,105 @@ +// 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. + +// It is a non-stress repro for the issue #14455. +// growTree is optimized as fast tail call and converted to a loop. +// `starg.s 0` forces the jit to create a temp for the modifiable this. +// Before the fix the jit zero-initialized all long-live locals in the end of the loop, +// on the last iteration it set `this` to `null` and the return block was trying to use +// `null` to write `m_rightChild` in, that caused a runtime exception. + + +.assembly extern System.Runtime {auto} +.assembly GitHub_14455 {} + +.class public auto ansi beforefieldinit Rotate.Node + extends [System.Runtime]System.Object +{ + .field public class Rotate.Node m_leftChild + .field public class Rotate.Node m_rightChild + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [System.Runtime]System.Object::.ctor() + IL_0006: ret + } // end of method Node::.ctor + + .method family hidebysig virtual instance void + Finalize() cil managed + { + .override [System.Runtime]System.Object::Finalize + // Code size 10 (0xa) + .maxstack 1 + .try + { + IL_0000: leave.s IL_0009 + + } // end .try + finally + { + IL_0002: ldarg.0 + IL_0003: call instance void [System.Runtime]System.Object::Finalize() + IL_0008: endfinally + } // end handler + IL_0009: ret + } // end of method Node::Finalize + + .method public hidebysig instance void + growTree(int32 maxHeight) cil managed + { + // Code size 72 (0x48) + .maxstack 4 + .locals init (class Rotate.Node V_0) + IL_0000: ldarg.1 + IL_0001: ldc.i4.0 + IL_0002: ble.s IL_0037 + + IL_0004: ldarg.0 + IL_0005: newobj instance void Rotate.Node::.ctor() + IL_000a: stfld class Rotate.Node Rotate.Node::m_leftChild + IL_000f: ldarg.0 + IL_0010: ldfld class Rotate.Node Rotate.Node::m_leftChild + IL_0015: ldarg.1 + IL_0016: ldc.i4.1 + IL_0017: sub + IL_0018: callvirt instance void Rotate.Node::growTree(int32) + IL_001d: ldarg.0 + IL_001e: newobj instance void Rotate.Node::.ctor() + IL_0023: stfld class Rotate.Node Rotate.Node::m_rightChild + IL_0028: ldarg.0 + IL_0029: ldfld class Rotate.Node Rotate.Node::m_rightChild + IL_002e: ldarg.1 + IL_002f: ldc.i4.1 + IL_0030: sub + IL_0031: callvirt instance void Rotate.Node::growTree(int32) + IL_0036: ret + ldarg.0 + starg.s 0 // Force to create a temp for the modifiable this. + IL_0037: ldarg.0 + IL_0038: ldarg.0 + IL_0039: ldnull + IL_003a: dup + IL_003b: stloc.0 + IL_003c: stfld class Rotate.Node Rotate.Node::m_rightChild + IL_0041: ldloc.0 + IL_0042: stfld class Rotate.Node Rotate.Node::m_leftChild + IL_0047: ret + } // end of method Node::growTree + + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 14 (0xe) + .maxstack 8 + IL_0000: newobj instance void Rotate.Node::.ctor() + IL_0005: ldc.i4.4 + IL_0006: callvirt instance void Rotate.Node::growTree(int32) + IL_000b: ldc.i4.s 100 + IL_000d: ret + } // end of method Node::Main + +} // end of class Rotate.Node diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_14455/GitHub_14455.ilproj b/tests/src/JIT/Regression/JitBlue/GitHub_14455/GitHub_14455.ilproj new file mode 100644 index 0000000..c832348 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_14455/GitHub_14455.ilproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + False + + + + None + True + + + + + + + + + +