diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp index 25e9e102e7cb..3736f7a510cf 100644 --- a/src/jit/gentree.cpp +++ b/src/jit/gentree.cpp @@ -8050,7 +8050,8 @@ GenTreePtr Compiler::gtCloneExpr( case GT_BOX: copy = new (this, GT_BOX) - GenTreeBox(tree->TypeGet(), tree->gtOp.gtOp1, tree->gtBox.gtAsgStmtWhenInlinedBoxValue); + GenTreeBox(tree->TypeGet(), tree->gtOp.gtOp1, tree->gtBox.gtAsgStmtWhenInlinedBoxValue, + tree->gtBox.gtCopyStmtWhenInlinedBoxValue); break; case GT_INTRINSIC: @@ -12459,32 +12460,168 @@ GenTreePtr Compiler::gtFoldExprSpecial(GenTreePtr tree) switch (oper) { - case GT_EQ: case GT_NE: + case GT_GT: // Optimize boxed value classes; these are always false. This IL is // generated when a generic value is tested against null: // ... foo(T x) { ... if ((object)x == null) ... if (val == 0 && op->IsBoxedValue()) { - // Change the assignment node so we don't generate any code for it. + // The tree under the box must be side effect free + // since we drop it if we optimize the compare. + assert(!gtTreeHasSideEffects(op->gtBox.gtOp.gtOp1, GTF_SIDE_EFFECT)); + // grab related parts for the optimization GenTreePtr asgStmt = op->gtBox.gtAsgStmtWhenInlinedBoxValue; assert(asgStmt->gtOper == GT_STMT); - GenTreePtr asg = asgStmt->gtStmt.gtStmtExpr; - assert(asg->gtOper == GT_ASG); + GenTreePtr copyStmt = op->gtBox.gtCopyStmtWhenInlinedBoxValue; + assert(copyStmt->gtOper == GT_STMT); #ifdef DEBUG if (verbose) { - printf("Bashing "); - printTreeID(asg); - printf(" to NOP as part of dead box operation\n"); + printf("\nAttempting to optimize BOX(valueType) %s null\n", GenTree::OpName(oper)); gtDispTree(tree); + printf("\nWith assign\n"); + gtDispTree(asgStmt); + printf("\nAnd copy\n"); + gtDispTree(copyStmt); } #endif + + // We don't expect GT_GT with signed compares, and we + // can't predict the result if we do see it, since the + // boxed object addr could have its high bit set. + if ((oper == GT_GT) && !tree->IsUnsigned()) + { + JITDUMP(" bailing; unexpected signed compare via GT_GT\n"); + goto FAIL; + } + + // If we don't recognize the form of the assign, bail. + GenTreePtr asg = asgStmt->gtStmt.gtStmtExpr; + if (asg->gtOper != GT_ASG) + { + JITDUMP(" bailing; unexpected assignment op %s\n", GenTree::OpName(asg->gtOper)); + goto FAIL; + } + + // If we don't recognize the form of the copy, bail. + GenTree* copy = copyStmt->gtStmt.gtStmtExpr; + if (copy->gtOper != GT_ASG) + { + // GT_RET_EXPR is a tolerable temporary failure. + // The jit will revisit this optimization after + // inlining is done. + if (copy->gtOper == GT_RET_EXPR) + { + JITDUMP(" bailing; must wait for replacement of copy %s\n", GenTree::OpName(copy->gtOper)); + } + else + { + // Anything else is a missed case we should + // figure out how to handle. One known case + // is GT_COMMAs enclosing the GT_ASG we are + // looking for. + JITDUMP(" bailing; unexpected copy op %s\n", GenTree::OpName(copy->gtOper)); + } + goto FAIL; + } + + // If the copy is a struct copy, make sure we know how to isolate + // any source side effects. + GenTreePtr copySrc = copy->gtOp.gtOp2; + + // If the copy source is from a pending inline, wait for it to resolve. + if (copySrc->gtOper == GT_RET_EXPR) + { + JITDUMP(" bailing; must wait for replacement of copy source %s\n", + GenTree::OpName(copySrc->gtOper)); + goto FAIL; + } + + bool hasSrcSideEffect = false; + bool isStructCopy = false; + + if (gtTreeHasSideEffects(copySrc, GTF_SIDE_EFFECT)) + { + hasSrcSideEffect = true; + + if (copySrc->gtType == TYP_STRUCT) + { + isStructCopy = true; + + if ((copySrc->gtOper != GT_OBJ) && (copySrc->gtOper != GT_IND) && (copySrc->gtOper != GT_FIELD)) + { + // We don't know how to handle other cases, yet. + JITDUMP(" bailing; unexpected copy source struct op with side effect %s\n", + GenTree::OpName(copySrc->gtOper)); + goto FAIL; + } + } + } + + // Proceed with the optimization + // + // Change the assignment expression to a NOP. + JITDUMP("\nBashing NEWOBJ [%06u] to NOP\n", dspTreeID(asg)); asg->gtBashToNOP(); - op = gtNewIconNode(oper == GT_NE); + // Change the copy expression so it preserves key + // source side effects. + JITDUMP("\nBashing COPY [%06u]", dspTreeID(copy)); + + if (!hasSrcSideEffect) + { + // If there were no copy source side effects just bash + // the copy to a NOP. + copy->gtBashToNOP(); + JITDUMP(" to NOP\n"); + } + else if (!isStructCopy) + { + // For scalar types, go ahead and produce the + // value as the copy is fairly cheap and likely + // the optimizer can trim things down to just the + // minimal side effect parts. + copyStmt->gtStmt.gtStmtExpr = copySrc; + JITDUMP(" to scalar read via [%06u]\n", dspTreeID(copySrc)); + } + else + { + // For struct types read the first byte of the + // source struct; there's no need to read the + // entire thing, and no place to put it. + assert(copySrc->gtOper == GT_OBJ || copySrc->gtOper == GT_IND || copySrc->gtOper == GT_FIELD); + copySrc->ChangeOper(GT_IND); + copySrc->gtType = TYP_BYTE; + copyStmt->gtStmt.gtStmtExpr = copySrc; + JITDUMP(" to read first byte of struct via modified [%06u]\n", dspTreeID(copySrc)); + } + + // Set up the result of the compare. + int compareResult = 0; + if (oper == GT_GT) + { + // GT_GT(null, box) == false + // GT_GT(box, null) == true + compareResult = (op1 == op); + } + else if (oper == GT_EQ) + { + // GT_EQ(box, null) == false + // GT_EQ(null, box) == false + compareResult = 0; + } + else + { + assert(oper == GT_NE); + // GT_NE(box, null) == true + // GT_NE(null, box) == true + compareResult = 1; + } + op = gtNewIconNode(compareResult); + if (fgGlobalMorph) { if (!fgIsInlining()) @@ -12497,9 +12634,15 @@ GenTreePtr Compiler::gtFoldExprSpecial(GenTreePtr tree) op->gtNext = tree->gtNext; op->gtPrev = tree->gtPrev; } - fgSetStmtSeq(asgStmt); + + if (fgStmtListThreaded) + { + fgSetStmtSeq(asgStmt); + fgSetStmtSeq(copyStmt); + } return op; } + break; case GT_ADD: @@ -12667,7 +12810,9 @@ GenTreePtr Compiler::gtFoldExprSpecial(GenTreePtr tree) break; } - /* The node is not foldable */ +/* The node is not foldable */ + +FAIL: return tree; diff --git a/src/jit/gentree.h b/src/jit/gentree.h index 1833a3904b65..41f65f032f41 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -2848,9 +2848,16 @@ struct GenTreeBox : public GenTreeUnOp // This is the statement that contains the assignment tree when the node is an inlined GT_BOX on a value // type GenTreePtr gtAsgStmtWhenInlinedBoxValue; - - GenTreeBox(var_types type, GenTreePtr boxOp, GenTreePtr asgStmtWhenInlinedBoxValue) - : GenTreeUnOp(GT_BOX, type, boxOp), gtAsgStmtWhenInlinedBoxValue(asgStmtWhenInlinedBoxValue) + // And this is the statement that copies from the value being boxed to the box payload + GenTreePtr gtCopyStmtWhenInlinedBoxValue; + + GenTreeBox(var_types type, + GenTreePtr boxOp, + GenTreePtr asgStmtWhenInlinedBoxValue, + GenTreePtr copyStmtWhenInlinedBoxValue) + : GenTreeUnOp(GT_BOX, type, boxOp) + , gtAsgStmtWhenInlinedBoxValue(asgStmtWhenInlinedBoxValue) + , gtCopyStmtWhenInlinedBoxValue(copyStmtWhenInlinedBoxValue) { } #if DEBUGGABLE_GENTREE diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 74018c48d4f1..1c1db83db9bc 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -5210,7 +5210,7 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken) gtNewArgList(op2)); } - /* Remember that this basic block contains 'new' of an array */ + /* Remember that this basic block contains 'new' of an object */ compCurBB->bbFlags |= BBF_HAS_NEWOBJ; GenTreePtr asg = gtNewTempAssign(impBoxTemp, op1); @@ -5252,11 +5252,16 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken) op1 = gtNewAssignNode(gtNewOperNode(GT_IND, lclTyp, op1), exprToBox); } - op2 = gtNewLclvNode(impBoxTemp, TYP_REF); - op1 = gtNewOperNode(GT_COMMA, TYP_REF, op1, op2); + // Spill eval stack to flush out any pending side effects. + impSpillSideEffects(true, (unsigned)CHECK_SPILL_ALL DEBUGARG("impImportAndPushBox")); - // Record that this is a "box" node. - op1 = new (this, GT_BOX) GenTreeBox(TYP_REF, op1, asgStmt); + // Set up this copy as a second assignment. + GenTreePtr copyStmt = impAppendTree(op1, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs); + + op1 = gtNewLclvNode(impBoxTemp, TYP_REF); + + // Record that this is a "box" node and keep track of the matching parts. + op1 = new (this, GT_BOX) GenTreeBox(TYP_REF, op1, asgStmt, copyStmt); // If it is a value class, mark the "box" node. We can use this information // to optimise several cases: diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_1.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_1.cs new file mode 100644 index 000000000000..c436802e40e4 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_1.cs @@ -0,0 +1,51 @@ +// 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. + +using System; + +public struct S +{ + public int x; + public int y; + public K val; +} + +public class X +{ + public X(K k) + { + a = new S[2]; + a[1].val = k; + a[1].x = 3; + a[1].y = 4; + } + + public void Assert(bool b) + { + if (!b) throw new Exception("bad!"); + } + + public int Test() + { + int r = 0; + for (int i = 0; i < a.Length; i++) + { + Assert(a[i].val != null); + r += a[i].val.GetHashCode(); + } + return r; + } + + S[] a; +} + +class B +{ + public static int Main() + { + var a = new X(11); + int z = a.Test(); + return (z == 11 ? 100 : 0); + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_1.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_1.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_1.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_2.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_2.cs new file mode 100644 index 000000000000..bbdc67ddc8e7 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_2.cs @@ -0,0 +1,43 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; + +public class X +{ + public X(K k1) + { + k = k1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public K Get() + { + Console.WriteLine("Get called"); + count++; + return k; + } + + public bool Test() + { + bool x = Get() != null; + bool y = (count == 1); + return x && y; + } + + K k; + int count; +} + +class B +{ + public static int Main() + { + var a = new X(11); + bool result = a.Test(); + Console.WriteLine("Passed: {0}", result); + return result ? 100 : 0; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_2.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_2.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_2.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_3.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_3.cs new file mode 100644 index 000000000000..b7247c15a152 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_3.cs @@ -0,0 +1,41 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; + +public class X +{ + public X(K k1) + { + k = k1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static bool Test(X a) + { + return (a.k != null); + } + + public K k; +} + +class B +{ + public static int Main() + { + X a = null; + bool result = false; + try + { + X.Test(a); + } + catch (Exception) + { + result = true; + } + Console.WriteLine("Passed: {0}", result); + return result ? 100 : 0; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_3.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_3.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_3.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_4.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_4.cs new file mode 100644 index 000000000000..126cdb9e3bbf --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_4.cs @@ -0,0 +1,41 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; + +public class X +{ + public X(K k1) + { + k = k1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static bool Test(X a) + { + return (a.k == null); + } + + public K k; +} + +class B +{ + public static int Main() + { + X a = null; + bool result = false; + try + { + X.Test(a); + } + catch (Exception) + { + result = true; + } + Console.WriteLine("Passed: {0}", result); + return result ? 100 : 0; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_4.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_4.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_4.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_5.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_5.cs new file mode 100644 index 000000000000..95a89457edd7 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_5.cs @@ -0,0 +1,46 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; + +struct R +{ + int a; +} + +public class X +{ + public X(K k1) + { + k = k1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static bool Test(X a) + { + return (a.k != null); + } + + public K k; +} + +class B +{ + public static int Main() + { + X a = null; + bool result = false; + try + { + X.Test(a); + } + catch (Exception) + { + result = true; + } + Console.WriteLine("Passed: {0}", result); + return result ? 100 : 0; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_5.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_5.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_5.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_6.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_6.cs new file mode 100644 index 000000000000..1371dbbd47a3 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_6.cs @@ -0,0 +1,60 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; + +public interface IGet +{ + int Get(); +} + +public struct R : IGet +{ + public double d; + public int a; + + public int Get() { return a; } +} + +public class X where K: IGet +{ + public X(K r) + { + a = new K[2]; + a[0] = r; + } + + public void Assert(bool b) + { + if (!b) throw new Exception("bad!"); + } + + public int Test() + { + int r = 0; + for (int i = 0; i < a.Length; i++) + { + Assert(a[i] != null); + r += a[i].Get(); + } + return r; + } + + K[] a; +} + +class B +{ + public static int Main() + { + var r = new R(); + r.a = 3; + var a = new X(r); + int result = a.Test(); + bool passed = result == 3; + Console.WriteLine("Passed: {0}", passed); + return passed ? 100 : 0; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_6.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_6.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_6.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_7.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_7.cs new file mode 100644 index 000000000000..3ba6cd2e6814 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_7.cs @@ -0,0 +1,58 @@ +// 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. + +using System; + +public struct V +{ + public V(int x) + { + Token = x; + } + + public int Token; +} + +class M +{ + static int F(int x, object a) + { + int result = 0; + + if (a is V) + { + int token = ((V)a).Token; + Console.WriteLine("F: Token is {0}", token); + result = x + token; + } + + return result; + } + + static int G(object a, int x) + { + return F(x, a); + } + + static int Trouble(ref V v) + { + Console.WriteLine("T: Token is {0}", v.Token); + int result = v.Token; + v.Token++; + return result; + } + + public static int Main() + { + // Ensure we get right order of side effects from boxes + // now that we are splitting them into multiple statments. + V v1 = new V(11); + int result1 = F(Trouble(ref v1), v1); + V v2 = new V(11); + int result2 = G(v2, Trouble(ref v2)); + Console.WriteLine("Result1 = {0}; Result2 = {1}", result1, result2); + return result1 + result2 + 55; + } +} + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_7.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_7.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_7.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + + diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_8.cs b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_8.cs new file mode 100644 index 000000000000..d5daa43f67bc --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_8.cs @@ -0,0 +1,42 @@ +// 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. + +using System; +using System.Runtime.CompilerServices; +using System.Numerics; + +public class X +{ + public X(K k1) + { + k = k1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static bool Test(X a) + { + return (a.k != null); + } + + public K k; +} + +class B +{ + public static int Main() + { + X a = null; + bool result = false; + try + { + X.Test(a); + } + catch (Exception) + { + result = true; + } + Console.WriteLine("Passed: {0}", result); + return result ? 100 : 0; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_8.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_8.csproj new file mode 100644 index 000000000000..5cd573d7fd36 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_12949/GitHub_12949_8.csproj @@ -0,0 +1,43 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {7B521917-193E-48BB-86C6-FE013F3DFF35} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + True + + + + + + + + + + +