diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 64c6f4563850..d47e3dfb97db 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -10094,7 +10094,11 @@ void Compiler::impImportBlockCode(BasicBlock* block) const bool isSingleILStoreLocal = !lvaTable[lclNum].lvHasMultipleILStoreOp && !lvaTable[lclNum].lvHasLdAddrOp; - if (isSingleILStoreLocal) + // Conservative check that there is just one + // definition that reaches this store. + const bool hasSingleReachingDef = (block->bbStackDepthOnEntry() == 0); + + if (isSingleILStoreLocal && hasSingleReachingDef) { lvaUpdateClass(lclNum, op1, clsHnd); } diff --git a/tests/src/JIT/opt/Devirtualization/GitHub_10858.cs b/tests/src/JIT/opt/Devirtualization/GitHub_10858.cs new file mode 100644 index 000000000000..a02d025593c6 --- /dev/null +++ b/tests/src/JIT/opt/Devirtualization/GitHub_10858.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; + +class B +{ + public virtual string F() { return "B"; } +} + +sealed class D : B +{ + public override string F() { return "D"; } +} + +sealed class E : B +{ + public override string F() { return "E"; } +} + +class X +{ + public static int Main(string[] args) + { + // When optimizing IL, CSC will leave the newobj's on the stack + // across the branches to the common def point. + B b1 = (args.Length > 0) ? (B)new E() : (B)new D(); + B b2 = null; + + // Conditional flow here to forces b1 to a local instead of + // remaining on the stack. So we have a single def point with + // two reaching values. + if (args.Length > 0) + { + b2 = new D(); + } + else + { + b2 = new E(); + } + + // We should not be able to devirtualize either call. + return b2.F()[0] + b1.F()[0] - 37; + } +} diff --git a/tests/src/JIT/opt/Devirtualization/GitHub_10858.csproj b/tests/src/JIT/opt/Devirtualization/GitHub_10858.csproj new file mode 100644 index 000000000000..fdf04a29e00e --- /dev/null +++ b/tests/src/JIT/opt/Devirtualization/GitHub_10858.csproj @@ -0,0 +1,37 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + + + False + + + + None + True + + + + + + + + + + +