From 747c705e7fd71e7ed958a35aaa825a0ceb6274e3 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Sat, 1 Apr 2017 00:56:33 -0700 Subject: [PATCH] Jit: fix a few issues with single def local tracking (dotnet/coreclr#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 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 | 8 + src/coreclr/src/jit/importer.cpp | 12 + src/coreclr/src/jit/lclvars.cpp | 34 +- .../src/JIT/Methodical/Boxing/morph/sin3double.il | 436 ++++++++++++++++++++ .../JIT/Methodical/Boxing/morph/sin3double.ilproj | 42 ++ .../JIT/Methodical/acceptance/Boxing/boxing001.il | 437 +++++++++++++++++++++ .../Methodical/acceptance/Boxing/boxing001.ilproj | 42 ++ 7 files changed, 1008 insertions(+), 3 deletions(-) create mode 100644 src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.il create mode 100644 src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj create mode 100644 src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.il create mode 100644 src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 4e42f4f..3628ff7 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/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/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 969f2df..e4c740e 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/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/coreclr/src/jit/lclvars.cpp b/src/coreclr/src/jit/lclvars.cpp index 2206236..ab7c15d 100644 --- a/src/coreclr/src/jit/lclvars.cpp +++ b/src/coreclr/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/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 index 0000000..65cc41d --- /dev/null +++ b/src/coreclr/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/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 index 0000000..d8ec34d --- /dev/null +++ b/src/coreclr/tests/src/JIT/Methodical/Boxing/morph/sin3double.ilproj @@ -0,0 +1,42 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + $(DefineConstants);STATIC + + + + + + + + + False + + + + None + True + + + + + + + + + $(JitPackagesConfigFileDirectory)benchmark\project.json + $(JitPackagesConfigFileDirectory)benchmark\project.lock.json + + + + + \ 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 index 0000000..2e1fc4a --- /dev/null +++ b/src/coreclr/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/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 index 0000000..3d7729f --- /dev/null +++ b/src/coreclr/tests/src/JIT/Methodical/acceptance/Boxing/boxing001.ilproj @@ -0,0 +1,42 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + $(DefineConstants);STATIC + + + + + + + + + False + + + + None + True + + + + + + + + + $(JitPackagesConfigFileDirectory)benchmark\project.json + $(JitPackagesConfigFileDirectory)benchmark\project.lock.json + + + + + \ No newline at end of file -- 2.7.4