Jit: fix a few issues with single def local tracking (dotnet/coreclr#10633)
authorAndy Ayers <andya@microsoft.com>
Sat, 1 Apr 2017 07:56:33 +0000 (00:56 -0700)
committerGitHub <noreply@github.com>
Sat, 1 Apr 2017 07:56:33 +0000 (00:56 -0700)
Fixes for three issues that came up in desktop testing.

1. Don't track class types for locals when in import only mode,
since the jit may be looking at an uninstantiated generic method.
In these cases the jit's use of TYP_REF to represent CORINFO_TYPE_VAR
confuses the tracking code. In import only mode the jit is not going
to use the information, so there is no need to track it at all.

    Import only mode is tied to verification and CoreCLR runs in full
trust mode, so no test was added.

2. Allow `lvaUpdateClass` to be called more than once but assert
that the second and subsequent calls provide the exact same update
as the first call.

    This can happen for single def ref class locals whose definition
block is reimported. Reimportation is triggered by some tolerable
non-ref type mismatches at block joins and so ref type information
should be consistent for each importation attempt.

    Add a couple of IL test cases translated from destkop MC++ tests
that will trigger this kind of reimportation.

3. Bail out of devirtualization (for desktop only) if the base class
has precise initialization semantics, since desktop seems to trigger
class initialization for ref type callvirts (contrary to ECMA355 I.8.9.5).
See dotnet/coreclr#4853 for some discussion. Since this is desktop only behavior
no test was added.

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

src/coreclr/src/jit/gentree.cpp
src/coreclr/src/jit/importer.cpp
src/coreclr/src/jit/lclvars.cpp
src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.il [new file with mode: 0644]
src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj [new file with mode: 0644]
src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il [new file with mode: 0644]
src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj [new file with mode: 0644]

index 4e42f4f..3628ff7 100644 (file)
@@ -16379,6 +16379,14 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTreePtr tree, bool* isExact,
     *isExact                      = false;
     CORINFO_CLASS_HANDLE objClass = nullptr;
 
+    // Bail out if we're just importing and not generating code, since
+    // the jit uses TYP_REF for CORINFO_TYPE_VAR locals and args, but
+    // these may not be ref types.
+    if (compIsForImportOnly())
+    {
+        return objClass;
+    }
+
     // Bail out if the tree is not a ref type.
     var_types treeType = tree->TypeGet();
     if (treeType != TYP_REF)
index 969f2df..e4c740e 100644 (file)
@@ -18488,6 +18488,18 @@ void Compiler::impDevirtualizeCall(GenTreeCall*            call,
     CORINFO_CLASS_HANDLE baseClass        = info.compCompHnd->getMethodClass(baseMethod);
     const DWORD          baseClassAttribs = info.compCompHnd->getClassAttribs(baseClass);
 
+#if !defined(FEATURE_CORECLR)
+    // If base class is not beforefieldinit then devirtualizing may
+    // cause us to miss a base class init trigger. Spec says we don't
+    // need a trigger for ref class callvirts but desktop seems to
+    // have one anyways. So defer.
+    if ((baseClassAttribs & CORINFO_FLG_BEFOREFIELDINIT) == 0)
+    {
+        JITDUMP("\nimpDevirtualizeCall: base class has precise initialization, sorry\n");
+        return;
+    }
+#endif // FEATURE_CORECLR
+
     // Is the call an interface call?
     const bool isInterface = (baseClassAttribs & CORINFO_FLG_INTERFACE) != 0;
 
index 2206236..ab7c15d 100644 (file)
@@ -2306,6 +2306,15 @@ void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool
 void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
 {
     noway_assert(varNum < lvaCount);
+
+    // If we are just importing, we cannot reliably track local ref types,
+    // since the jit maps CORINFO_TYPE_VAR to TYP_REF.
+    if (compIsForImportOnly())
+    {
+        return;
+    }
+
+    // Else we should have a type handle.
     assert(clsHnd != nullptr);
 
     LclVarDsc* varDsc = &lvaTable[varNum];
@@ -2378,6 +2387,15 @@ void Compiler::lvaSetClass(unsigned varNum, GenTreePtr tree, CORINFO_CLASS_HANDL
 void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
 {
     noway_assert(varNum < lvaCount);
+
+    // If we are just importing, we cannot reliably track local ref types,
+    // since the jit maps CORINFO_TYPE_VAR to TYP_REF.
+    if (compIsForImportOnly())
+    {
+        return;
+    }
+
+    // Else we should have a class handle to consider
     assert(clsHnd != nullptr);
 
     LclVarDsc* varDsc = &lvaTable[varNum];
@@ -2386,12 +2404,22 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool
     // We should already have a class
     assert(varDsc->lvClassHnd != nullptr);
 
-    // This should be the first and only update for this var
-    assert(!varDsc->lvClassInfoUpdated);
-
 #if defined(DEBUG)
+
+    // In general we only expect one update per local var. However if
+    // a block is re-imported and that block has the only STLOC for
+    // the var, we may see multiple updates. All subsequent updates
+    // should agree on the type, since reimportation is triggered by
+    // type mismatches for things other than ref types.
+    if (varDsc->lvClassInfoUpdated)
+    {
+        assert(varDsc->lvClassHnd == clsHnd);
+        assert(varDsc->lvClassIsExact == isExact);
+    }
+
     // This counts as an update, even if nothing changes.
     varDsc->lvClassInfoUpdated = true;
+
 #endif // defined(DEBUG)
 
     // If previous type was exact, there is nothing to update.  Would
diff --git a/src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.il b/src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.il
new file mode 100644 (file)
index 0000000..65cc41d
--- /dev/null
@@ -0,0 +1,436 @@
+// 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 mscorlib
+{
+}
+
+.assembly extern System.Console as console
+{
+}
+
+.assembly sin3double
+{
+}
+
+.class private sequential ansi sealed beforefieldinit VV extends [mscorlib]System.ValueType
+{
+  .pack 0
+  .size 40
+}
+
+.class public auto ansi beforefieldinit Z extends [mscorlib] System.Object
+{
+
+.method static float64 mySin(float64 Angle) cil managed
+{
+  .locals (int32 V_0,
+           float64 V_1,
+           float64 V_2,
+           float64 V_3,
+           float64 V_4,
+           object V_5,
+           object V_6,
+           object V_7,
+           object V_8,
+           object V_9,
+           object V_10,
+           object V_11,
+           object V_12,
+           object V_13,
+           object V_14,
+           float64 V_15,
+           float64 V_16)
+  IL_0000:  ldnull
+  IL_0001:  stloc.s    V_14
+  IL_0003:  ldnull
+  IL_0004:  stloc.s    V_13
+  IL_0006:  ldnull
+  IL_0007:  stloc.s    V_12
+  IL_0009:  ldnull
+  IL_000a:  stloc.s    V_11
+  IL_000c:  ldnull
+  IL_000d:  stloc.s    V_10
+  IL_000f:  ldc.r8     0.0
+  IL_0018:  box        [mscorlib]System.Double
+  IL_001d:  stloc.s    V_14
+  IL_001f:  ldc.r8     0.0
+  IL_0028:  box        [mscorlib]System.Double
+  IL_002d:  stloc.s    V_13
+  IL_002f:  ldc.r8     0.0
+  IL_0038:  box        [mscorlib]System.Double
+  IL_003d:  stloc.s    V_12
+  IL_003f:  ldc.r8     0.0
+  IL_0048:  box        [mscorlib]System.Double
+  IL_004d:  stloc.s    V_11
+  IL_004f:  ldc.r8     1.
+  IL_0058:  box        [mscorlib]System.Double
+  IL_005d:  stloc.s    V_10
+  IL_005f:  ldloc.s    V_14
+  IL_0061:  stloc.s    V_9
+  IL_0063:  ldloc.s    V_9
+  IL_0065:  isinst     [mscorlib]System.Double
+  IL_006a:  brfalse.s  IL_0075
+
+  IL_006c:  ldloc.s    V_9
+  IL_006e:  unbox      [mscorlib]System.Double
+  IL_0073:  br.s       IL_0077
+
+  IL_0075:  ldc.i4.0
+  IL_0076:  conv.i
+  IL_0077:  ldind.r8
+  IL_0078:  stloc.s    V_4
+  IL_007a:  ldloc.s    V_13
+  IL_007c:  stloc.s    V_8
+  IL_007e:  ldloc.s    V_8
+  IL_0080:  isinst     [mscorlib]System.Double
+  IL_0085:  brfalse.s  IL_0090
+
+  IL_0087:  ldloc.s    V_8
+  IL_0089:  unbox      [mscorlib]System.Double
+  IL_008e:  br.s       IL_0092
+
+  IL_0090:  ldc.i4.0
+  IL_0091:  conv.i
+  IL_0092:  ldind.r8
+  IL_0093:  stloc.3
+  IL_0094:  ldloc.s    V_12
+  IL_0096:  stloc.s    V_7
+  IL_0098:  ldloc.s    V_7
+  IL_009a:  isinst     [mscorlib]System.Double
+  IL_009f:  brfalse.s  IL_00aa
+
+  IL_00a1:  ldloc.s    V_7
+  IL_00a3:  unbox      [mscorlib]System.Double
+  IL_00a8:  br.s       IL_00ac
+
+  IL_00aa:  ldc.i4.0
+  IL_00ab:  conv.i
+  IL_00ac:  ldind.r8
+  IL_00ad:  stloc.2
+  IL_00ae:  ldloc.s    V_11
+  IL_00b0:  stloc.s    V_6
+  IL_00b2:  ldloc.s    V_6
+  IL_00b4:  isinst     [mscorlib]System.Double
+  IL_00b9:  brfalse.s  IL_00c4
+
+  IL_00bb:  ldloc.s    V_6
+  IL_00bd:  unbox      [mscorlib]System.Double
+  IL_00c2:  br.s       IL_00c6
+
+  IL_00c4:  ldc.i4.0
+  IL_00c5:  conv.i
+  IL_00c6:  ldind.r8
+  IL_00c7:  stloc.s    V_16
+  IL_00c9:  ldloc.s    V_10
+  IL_00cb:  stloc.s    V_5
+  IL_00cd:  ldloc.s    V_5
+  IL_00cf:  isinst     [mscorlib]System.Double
+  IL_00d4:  brfalse.s  IL_00df
+
+  IL_00d6:  ldloc.s    V_5
+  IL_00d8:  unbox      [mscorlib]System.Double
+  IL_00dd:  br.s       IL_00e1
+
+  IL_00df:  ldc.i4.0
+  IL_00e0:  conv.i
+  IL_00e1:  ldind.r8
+  IL_00e2:  stloc.1
+  IL_00e3:  ldarg.0
+  IL_00e4:  stloc.2
+  IL_00e5:  ldloc.2
+  IL_00e6:  stloc.s    V_4
+  IL_00e8:  ldc.r8     0.0
+  IL_00f1:  stloc.3
+  IL_00f2:  ldc.i4.1
+  IL_00f3:  stloc.0
+  IL_00f4:  br.s       IL_00fa
+
+  IL_00f6:  ldloc.0
+  IL_00f7:  ldc.i4.2
+  IL_00f8:  add
+  IL_00f9:  stloc.0
+  IL_00fa:  ldloc.0
+  IL_00fb:  ldc.i4     0xc8
+  IL_0100:  bgt.s      IL_012b
+
+  IL_0102:  ldloc.3
+  IL_0103:  ldloc.2
+  IL_0104:  add
+  IL_0105:  stloc.3
+  IL_0106:  ldloc.s    V_4
+  IL_0108:  ldarg.0
+  IL_0109:  neg
+  IL_010a:  ldarg.0
+  IL_010b:  mul
+  IL_010c:  mul
+  IL_010d:  stloc.s    V_4
+  IL_010f:  ldloc.1
+  IL_0110:  ldloc.0
+  IL_0111:  ldc.i4.1
+  IL_0112:  add
+  IL_0113:  ldloc.0
+  IL_0114:  ldc.i4.2
+  IL_0115:  add
+  IL_0116:  mul
+  IL_0117:  conv.r8
+  IL_0118:  mul
+  IL_0119:  stloc.1
+  IL_011a:  ldloc.1
+  IL_011b:  call       bool [mscorlib]System.Double::IsInfinity(float64)
+  IL_0120:  brfalse.s  IL_0124
+
+  IL_0122:  br.s       IL_012b
+
+  IL_0124:  ldloc.s    V_4
+  IL_0126:  ldloc.1
+  IL_0127:  div
+  IL_0128:  stloc.2
+  IL_0129:  br.s       IL_00f6
+
+  IL_012b:  ldloc.3
+  IL_012c:  stloc.s    V_15
+  IL_012e:  ldloc.s    V_15
+  IL_0130:  ret
+}
+
+.method static int32 Main() cil managed
+{
+  .entrypoint
+  .locals (int32 V_0,
+           float64 V_1,
+           float64 V_2,
+           float64 V_3,
+           int32 V_4,
+           object V_5,
+           object V_6,
+           object V_7,
+           object V_8,
+           object V_9,
+           object V_10,
+           valuetype VV V_11)
+  IL_0000:  ldc.i4.0
+  IL_0001:  stloc.s    V_4
+  IL_0003:  ldnull
+  IL_0004:  stloc.s    V_10
+  IL_0006:  ldnull
+  IL_0007:  stloc.s    V_9
+  IL_0009:  ldnull
+  IL_000a:  stloc.s    V_8
+  IL_000c:  ldc.r8     0.0
+  IL_0015:  box        [mscorlib]System.Double
+  IL_001a:  stloc.s    V_10
+  IL_001c:  ldc.r8     0.0
+  IL_0025:  box        [mscorlib]System.Double
+  IL_002a:  stloc.s    V_9
+  IL_002c:  ldc.r8     0.0
+  IL_0035:  box        [mscorlib]System.Double
+  IL_003a:  stloc.s    V_8
+  IL_003c:  ldloc.s    V_10
+  IL_003e:  stloc.s    V_7
+  IL_0040:  ldloc.s    V_7
+  IL_0042:  isinst     [mscorlib]System.Double
+  IL_0047:  brfalse.s  IL_0052
+
+  IL_0049:  ldloc.s    V_7
+  IL_004b:  unbox      [mscorlib]System.Double
+  IL_0050:  br.s       IL_0054
+
+  IL_0052:  ldc.i4.0
+  IL_0053:  conv.i
+  IL_0054:  ldind.r8
+  IL_0055:  stloc.3
+  IL_0056:  ldloc.s    V_9
+  IL_0058:  stloc.s    V_6
+  IL_005a:  ldloc.s    V_6
+  IL_005c:  isinst     [mscorlib]System.Double
+  IL_0061:  brfalse.s  IL_006c
+
+  IL_0063:  ldloc.s    V_6
+  IL_0065:  unbox      [mscorlib]System.Double
+  IL_006a:  br.s       IL_006e
+
+  IL_006c:  ldc.i4.0
+  IL_006d:  conv.i
+  IL_006e:  ldind.r8
+  IL_006f:  stloc.2
+  IL_0070:  ldloc.s    V_8
+  IL_0072:  stloc.s    V_5
+  IL_0074:  ldloc.s    V_5
+  IL_0076:  isinst     [mscorlib]System.Double
+  IL_007b:  brfalse.s  IL_0086
+
+  IL_007d:  ldloc.s    V_5
+  IL_007f:  unbox      [mscorlib]System.Double
+  IL_0084:  br.s       IL_0088
+
+  IL_0086:  ldc.i4.0
+  IL_0087:  conv.i
+  IL_0088:  ldind.r8
+  IL_0089:  stloc.1
+  IL_008a:  ldloca.s   V_11
+  IL_008c:  ldc.r4     0.0
+  IL_0091:  stind.r4
+  IL_0092:  ldloca.s   V_11
+  IL_0094:  ldc.i4.4
+  IL_0095:  add
+  IL_0096:  ldc.r4     0.309017
+  IL_009b:  stind.r4
+  IL_009c:  ldloca.s   V_11
+  IL_009e:  ldc.i4.8
+  IL_009f:  add
+  IL_00a0:  ldc.r4     0.58778524
+  IL_00a5:  stind.r4
+  IL_00a6:  ldloca.s   V_11
+  IL_00a8:  ldc.i4.s   12
+  IL_00aa:  add
+  IL_00ab:  ldc.r4     0.809017
+  IL_00b0:  stind.r4
+  IL_00b1:  ldloca.s   V_11
+  IL_00b3:  ldc.i4.s   16
+  IL_00b5:  add
+  IL_00b6:  ldc.r4     0.95105654
+  IL_00bb:  stind.r4
+  IL_00bc:  ldloca.s   V_11
+  IL_00be:  ldc.i4.s   20
+  IL_00c0:  add
+  IL_00c1:  ldc.r4     1.
+  IL_00c6:  stind.r4
+  IL_00c7:  ldloca.s   V_11
+  IL_00c9:  ldc.i4.s   24
+  IL_00cb:  add
+  IL_00cc:  ldc.r4     0.95105654
+  IL_00d1:  stind.r4
+  IL_00d2:  ldloca.s   V_11
+  IL_00d4:  ldc.i4.s   28
+  IL_00d6:  add
+  IL_00d7:  ldc.r4     0.809017
+  IL_00dc:  stind.r4
+  IL_00dd:  ldloca.s   V_11
+  IL_00df:  ldc.i4.s   32
+  IL_00e1:  add
+  IL_00e2:  ldc.r4     0.58778524
+  IL_00e7:  stind.r4
+  IL_00e8:  ldloca.s   V_11
+  IL_00ea:  ldc.i4.s   36
+  IL_00ec:  add
+  IL_00ed:  ldc.r4     0.309017
+  IL_00f2:  stind.r4
+  IL_00f3:  ldc.i4.0
+  IL_00f4:  stloc.0
+  IL_00f5:  br.s       IL_00fb
+
+  IL_00f7:  ldloc.0
+  IL_00f8:  ldc.i4.1
+  IL_00f9:  add
+  IL_00fa:  stloc.0
+  IL_00fb:  ldloc.0
+  IL_00fc:  ldc.i4.s   10
+  IL_00fe:  bge        IL_0227
+
+  IL_0103:  ldc.r8     3.1415926535897931
+  IL_010c:  ldloc.0
+  IL_010d:  conv.r8
+  IL_010e:  ldc.r8     10.
+  IL_0117:  div
+  IL_0118:  mul
+  IL_0119:  stloc.3
+  IL_011a:  ldstr      "Classlib Sin("
+  IL_0124:  call       void [console]System.Console::Write(string)
+  IL_0129:  ldloc.3
+  IL_012a:  call       void [console]System.Console::Write(float64)
+  IL_012f:  ldstr      ")="
+  IL_0139:  call       void [console]System.Console::Write(string)
+  IL_013e:  ldloc.3
+  IL_013f:  call       float64 [mscorlib]System.Math::Sin(float64)
+  IL_0144:  stloc.2
+  IL_0145:  ldloc.2
+  IL_0146:  call       void [console]System.Console::WriteLine(float64)
+  IL_014b:  ldstr      "This Version("
+  IL_0155:  call       void [console]System.Console::Write(string)
+  IL_015a:  ldloc.3
+  IL_015b:  call       void [console]System.Console::Write(float64)
+  IL_0160:  ldstr      ")="
+  IL_016a:  call       void [console]System.Console::Write(string)
+  IL_016f:  ldloc.3
+  IL_0170:  call       float64 Z::mySin(float64)
+  IL_0175:  stloc.1
+  IL_0176:  ldloc.1
+  IL_0177:  call       void [console]System.Console::WriteLine(float64)
+  IL_017c:  ldstr      "Error is:"
+  IL_0186:  call       void [console]System.Console::Write(string)
+  IL_018b:  ldloc.2
+  IL_018c:  ldloc.1
+  IL_018d:  sub
+  IL_018e:  call       void [console]System.Console::WriteLine(float64)
+  IL_0193:  call       void [console]System.Console::WriteLine()
+  IL_0198:  ldloc.2
+  IL_0199:  ldloc.1
+  IL_019a:  sub
+  IL_019b:  call       float64 [mscorlib]System.Math::Abs(float64)
+  IL_01a0:  ldc.r8     1.0000000000000001e-005
+  IL_01a9:  ble.un.s   IL_01c2
+
+  IL_01ab:  ldstr      "ERROR, Versions too far apart!"
+  IL_01b5:  call       void [console]System.Console::WriteLine(string)
+  IL_01ba:  ldc.i4.1
+  IL_01bb:  stloc.s    V_4
+  IL_01bd:  br         IL_023a
+
+  IL_01c2:  ldloca.s   V_11
+  IL_01c4:  ldloc.0
+  IL_01c5:  conv.i8
+  IL_01c6:  ldc.i4.4
+  IL_01c7:  conv.i8
+  IL_01c8:  mul
+  IL_01c9:  add
+            conv.i
+  IL_01ca:  ldind.r4
+  IL_01cb:  conv.r8
+  IL_01cc:  ldloc.2
+  IL_01cd:  sub
+  IL_01ce:  call       float64 [mscorlib]System.Math::Abs(float64)
+  IL_01d3:  ldc.r8     1.0000000000000001e-005
+  IL_01dc:  ble.un.s   IL_01f2
+
+  IL_01de:  ldstr      "ERROR, ClassLib version isn't right!"
+  IL_01e8:  call       void [console]System.Console::WriteLine(string)
+  IL_01ed:  ldc.i4.1
+  IL_01ee:  stloc.s    V_4
+  IL_01f0:  br.s       IL_023a
+
+  IL_01f2:  ldloca.s   V_11
+  IL_01f4:  ldloc.0
+  IL_01f5:  conv.i8
+  IL_01f6:  ldc.i4.4
+  IL_01f7:  conv.i8
+  IL_01f8:  mul
+  IL_01f9:  add
+            conv.i
+  IL_01fa:  ldind.r4
+  IL_01fb:  conv.r8
+  IL_01fc:  ldloc.1
+  IL_01fd:  sub
+  IL_01fe:  call       float64 [mscorlib]System.Math::Abs(float64)
+  IL_0203:  ldc.r8     1.0000000000000001e-005
+  IL_020c:  ble.un.s   IL_0222
+
+  IL_020e:  ldstr      "ERROR, our version isn't right!"
+  IL_0218:  call       void [console]System.Console::WriteLine(string)
+  IL_021d:  ldc.i4.1
+  IL_021e:  stloc.s    V_4
+  IL_0220:  br.s       IL_023a
+
+  IL_0222:  br         IL_00f7
+
+  IL_0227:  ldstr      "Yippee, all correct"
+  IL_0231:  call       void [console]System.Console::WriteLine(string)
+  IL_0236:  ldc.i4.s   100
+  IL_0238:  stloc.s    V_4
+  IL_023a:  ldloc.s    V_4
+  IL_023c:  ret
+}
+
+}
+
diff --git a/src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj b/src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj
new file mode 100644 (file)
index 0000000..d8ec34d
--- /dev/null
@@ -0,0 +1,42 @@
+<?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>
+    <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ </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="sin3double.il" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup> 
+</Project>
\ No newline at end of file
diff --git a/src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il b/src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il
new file mode 100644 (file)
index 0000000..2e1fc4a
--- /dev/null
@@ -0,0 +1,437 @@
+// 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 mscorlib
+{
+}
+
+.assembly extern System.Console as console
+{
+}
+
+.assembly boxing001 
+{
+}
+
+.class private sequential ansi sealed beforefieldinit V extends [mscorlib] System.ValueType
+{
+  .field public int32 m_i
+}
+
+.class public auto ansi beforefieldinit Z extends [mscorlib] System.Object
+{
+
+.field static int32 nFailures
+
+.method static int32 Assert(int32 line, string f) cil managed
+{
+  .locals (int32 V_0)
+   ldstr      "ASSERTION FAILED AT LINE"
+   call       void [console]System.Console::Write(string)
+   ldarg.0
+   call       void [console]System.Console::Write(int32)
+   ldstr      ": '"
+   call       void [console]System.Console::Write(string)
+   ldarg.1
+   call       void [console]System.Console::Write(string)
+   ldstr      "'"
+   call       void [console]System.Console::WriteLine(string)
+   ldsfld     int32 Z::nFailures
+   ldc.i4.1
+   add
+   stsfld     int32 Z::nFailures
+   ldsfld     int32 Z::nFailures
+   stloc.0
+   ldloc.0
+   ret
+}
+
+.method public static int32 Main() cil managed
+{
+  .entrypoint
+  .locals (int32 V_0,
+           object V1,
+           valuetype V V_2,
+           valuetype V& V_3,
+           object V_4,
+           object V_5,
+           object V_6,
+           int32 V_7,
+           int32 V_8,
+           object V_9,
+           object V_10,
+           object V_11,
+           object V_12,
+           string V_13,
+           string V_14,
+           valuetype V& V_15,
+           valuetype V V_16,
+           valuetype V V_17)
+  ldc.i4.0
+  stloc.s    V_7
+  ldnull
+  stloc.1
+  ldnull
+  stloc.s    V_4
+  ldnull
+  stloc.s    V_14
+  ldnull
+  stloc.s    V_13
+  ldnull
+  stloc.s    V_6
+  ldnull
+  stloc.s    V_5
+  ldnull
+  stloc.s    V_12
+  ldnull
+  stloc.s    V_11
+  ldloca.s   V_2
+  initobj    V
+  ldloca.s   V_2
+  ldc.i4.5
+  stfld      int32 V::m_i
+  ldloc.2
+  box        V
+  stloc.1
+  ldloc.1
+  unbox      V
+  ldfld      int32 V::m_i
+  stloc.0
+  ldloc.0
+  ldc.i4.5
+  beq.s      T1
+
+  ldc.i4.s   50
+  ldstr      "i == 5"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T1:
+
+  ldloc.1
+  unbox      V
+  stloc.3
+  ldloc.3
+  ldfld      int32 V::m_i
+  ldc.i4.5
+  beq.s      T2
+
+  ldc.i4.s   53
+  ldstr      "pv->m_i == 5"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T2:
+
+  ldloc.3
+  ldfld      int32 V::m_i
+  ldc.i4.5
+  beq.s      T3
+
+  ldc.i4.s   55
+  ldstr      "(*pv).m_i == 5"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T3:
+
+  ldloc.3
+  ldobj      V
+  stloc.s    V_17
+  ldloca.s   V_17
+  ldc.i4.s   10
+  stfld      int32 V::m_i
+  ldloca.s   V_17
+  ldfld      int32 V::m_i
+  ldc.i4.s   10
+  beq.s      T4
+
+  ldc.i4.s   60
+  ldstr      "v3.m_i == 10"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T4:
+
+  ldloc.3
+  ldfld      int32 V::m_i
+  ldc.i4.5
+  beq.s      T5
+
+  ldc.i4.s   61
+  ldstr      "(*pv).m_i == 5"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T5:
+
+  ldloca.s   V_17
+  stloc.3
+  ldloc.3
+  ldfld      int32 V::m_i
+  ldc.i4.s   10
+  beq.s      T6
+
+  ldc.i4.s   64
+  ldstr      "(*pv).m_i == 10"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T6:
+
+  ldloc.1
+  unbox      V
+  ldobj      V
+  stloc.s    V_16
+  ldloca.s   V_16
+  ldfld      int32 V::m_i
+  ldc.i4.5
+  beq.s      T7
+
+  ldc.i4.s   68
+  ldstr      "v2.m_i == 5"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T7:
+
+  ldloc.1
+  unbox      V
+  ldc.i4.s   10
+  stfld      int32 V::m_i
+  ldloc.1
+  unbox      V
+  ldfld      int32 V::m_i
+  stloc.0
+  ldloc.0
+  ldc.i4.s   10
+  beq.s      T8
+
+  ldc.i4.s   72
+  ldstr      "i == 10"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T8:
+
+  ldloc.1
+  unbox      V
+  ldc.i4.s   123
+  stfld      int32 V::m_i
+  ldloc.1
+  unbox      V
+  ldobj      V
+  stloc.2
+  ldloca.s   V_2
+  ldfld      int32 V::m_i
+  ldc.i4.s   123
+  beq.s      T9
+
+  ldc.i4.s   76
+  ldstr      "v.m_i == 123"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T9:
+
+  ldloc.2
+  box        V
+  stloc.s    V_4
+  ldloc.s    V_4
+  stloc.1
+  ldloc.1
+  unbox      V
+  ldfld      int32 V::m_i
+  stloc.0
+  ldloc.0
+  ldc.i4.s   123
+  beq.s      T10
+
+  ldc.i4.s   82
+  ldstr      "i == 123"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T10:
+
+  ldstr      "V"
+  stloc.s    V_14
+  ldloc.1
+  callvirt   instance string [mscorlib]System.ValueType::ToString()
+  stloc.s    V_13
+  ldloc.s    V_14
+  ldloc.s    V_13
+  callvirt   instance bool [mscorlib]System.String::Equals(string)
+  brtrue.s   T11
+
+  ldc.i4.s   86
+  ldstr      "str1->Equals( str2 )"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T11:
+
+  ldloc.2
+  box        V
+  stloc.s    V_4
+  ldloc.s    V_4
+  stloc.s    V_10
+  ldloc.s    V_10
+  isinst     V
+  brfalse.s  X0
+
+  ldloc.s    V_10
+  unbox      V
+  br.s       X1
+
+X0:
+
+  ldc.i4.0
+  conv.i
+
+X1:
+
+  stloc.s    V_15
+  ldloc.s    V_15
+  ldobj      V
+  stloc.2
+  ldloc.s    V_4
+  stloc.s    V_9
+  ldloc.s    V_9
+  isinst     V
+  brfalse.s  X2
+
+  ldloc.s    V_9
+  unbox      V
+  br.s       X3
+
+X2:
+
+  ldc.i4.0
+  conv.i
+
+X3:
+
+  ldobj      V
+  stloc.2
+  ldloc.1
+  unbox      V
+  ldobj      V
+  box        V
+  unbox      V
+  ldobj      V
+  box        V
+  unbox      V
+  ldobj      V
+  stloc.2
+  ldloca.s   V_2
+  ldfld      int32 V::m_i
+  stloc.0
+  ldloc.1
+  unbox      V
+  ldobj      V
+  box        V
+  unbox      V
+  ldobj      V
+  box        V
+  unbox      V
+  ldobj      V
+  box        V
+  unbox      V
+  ldobj      V
+  box        V
+  stloc.1
+  ldloc.0
+  ldloc.1
+  unbox      V
+  ldfld      int32 V::m_i
+  sub
+  stloc.0
+  ldloc.0
+  brfalse.s  T12
+
+  ldc.i4.s   101
+  ldstr      "i == 0"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T12:
+  ldc.i4.5
+  stloc.s    V_8
+  ldc.i4.0
+  stloc.0
+  ldc.i4.5
+  box        [mscorlib]System.Int32
+  stloc.s    V_6
+  ldloc.0
+  ldloc.s    V_6
+  unbox      [mscorlib]System.Int32
+  ldind.i4
+  add
+  stloc.0
+  ldc.i4.5
+  box        [mscorlib]System.Int32
+  stloc.s    V_5
+  ldloc.0
+  ldloc.s    V_5
+  unbox      [mscorlib]System.Int32
+  ldind.i4
+  add
+  stloc.0
+  ldloc.s    V_8
+  box        [mscorlib]System.Int32
+  stloc.s    V_12
+  ldloc.0
+  ldloc.s    V_12
+  unbox      [mscorlib]System.Int32
+  ldind.i4
+  add
+  stloc.0
+  ldloc.s    V_8
+  box        [mscorlib]System.Int32
+  stloc.s    V_11
+  ldloc.0
+  ldloc.s    V_11
+  unbox      [mscorlib]System.Int32
+  ldind.i4
+  add
+  stloc.0
+  ldloc.0
+  ldc.i4.s   20
+  beq.s      T13
+
+  ldc.i4.s   114
+  ldstr      "i == 5+5+5+5"
+  call       int32 Z::Assert(int32, string)
+  pop
+
+T13:
+
+  ldloc.s    V_5
+  stloc.s    V_6
+  ldsfld     int32 Z::nFailures
+  brtrue.s   Fail
+
+  ldstr      "PASSED"
+  call       void [console]System.Console::WriteLine(string)
+  ldc.i4.s   100
+  stloc.s    V_7
+  br.s       Done
+
+Fail:
+
+  ldstr      "FAILED"
+  call       void [console]System.Console::WriteLine(string)
+  ldsfld     int32 Z::nFailures
+  stloc.s    V_7
+
+Done:
+
+  ldloc.s    V_7
+  ret
+}
+
+}
+
diff --git a/src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj b/src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj
new file mode 100644 (file)
index 0000000..3d7729f
--- /dev/null
@@ -0,0 +1,42 @@
+<?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>
+    <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ </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="boxing001.il" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup> 
+</Project>
\ No newline at end of file