summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2017-04-01 00:56:33 -0700
committerGitHub <noreply@github.com>2017-04-01 00:56:33 -0700
commita7ab04cfb152f133d130948709dd5ac4f1494a19 (patch)
tree0a09e6ece32c4e0469970ed95b7981745282222c
parent7c8941ab25b3a4fa49c2a61b707075309b61a26e (diff)
downloadcoreclr-a7ab04cfb152f133d130948709dd5ac4f1494a19.tar.gz
coreclr-a7ab04cfb152f133d130948709dd5ac4f1494a19.tar.bz2
coreclr-a7ab04cfb152f133d130948709dd5ac4f1494a19.zip
Jit: fix a few issues with single def local tracking (#10633)
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 #4853 for some discussion. Since this is desktop only behavior no test was added.
-rw-r--r--src/jit/gentree.cpp8
-rw-r--r--src/jit/importer.cpp12
-rw-r--r--src/jit/lclvars.cpp34
-rw-r--r--tests/src/JIT/Methodical/Boxing/morph/sin3double.il436
-rw-r--r--tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj42
-rw-r--r--tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il437
-rw-r--r--tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj42
7 files changed, 1008 insertions, 3 deletions
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index 4e42f4fa4a..3628ff72be 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -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)
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 969f2df0b9..e4c740e338 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -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;
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index 2206236dca..ab7c15dd35 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -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/tests/src/JIT/Methodical/Boxing/morph/sin3double.il b/tests/src/JIT/Methodical/Boxing/morph/sin3double.il
new file mode 100644
index 0000000000..65cc41d81e
--- /dev/null
+++ b/tests/src/JIT/Methodical/Boxing/morph/sin3double.il
@@ -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/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj b/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj
new file mode 100644
index 0000000000..d8ec34de75
--- /dev/null
+++ b/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj
@@ -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/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il b/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il
new file mode 100644
index 0000000000..2e1fc4a4c4
--- /dev/null
+++ b/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il
@@ -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/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj b/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj
new file mode 100644
index 0000000000..3d7729f5e7
--- /dev/null
+++ b/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj
@@ -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