From 06055495d96093502deae21c33134338229f6554 Mon Sep 17 00:00:00 2001 From: Carol Eidt Date: Tue, 9 Jan 2018 15:56:25 -0800 Subject: [PATCH] Fix change to fgMorphBlockOperand My recent fix broke the `DYN_BLK` case. In addition to checking that types match, we *still* need to check that the sizes match. This was caught by desktop testing. The test cases are somewhat complex, so I created a smaller repro. --- src/jit/morph.cpp | 8 +- tests/src/JIT/Methodical/xxblk/dynblk.il | 99 +++++++++++++++++++ .../JIT/Methodical/xxblk/dynblk_il_d.ilproj | 36 +++++++ .../JIT/Methodical/xxblk/dynblk_il_r.ilproj | 35 +++++++ 4 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 tests/src/JIT/Methodical/xxblk/dynblk.il create mode 100644 tests/src/JIT/Methodical/xxblk/dynblk_il_d.ilproj create mode 100644 tests/src/JIT/Methodical/xxblk/dynblk_il_r.ilproj diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index f85bafb19a..afdc7dc60f 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -10208,10 +10208,14 @@ GenTree* Compiler::fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigne if (lclNode != nullptr) { LclVarDsc* varDsc = &(lvaTable[lclNode->gtLclNum]); - if (varTypeIsStruct(varDsc) && (varDsc->lvType == asgType)) + if (varTypeIsStruct(varDsc) && (varDsc->lvExactSize == blockWidth) && (varDsc->lvType == asgType)) { #ifndef LEGACY_BACKEND - effectiveVal = lclNode; + if (effectiveVal != lclNode) + { + JITDUMP("Replacing block node [%06d] with lclVar V%02u\n", dspTreeID(tree), lclNode->gtLclNum); + effectiveVal = lclNode; + } needsIndirection = false; #endif // !LEGACY_BACKEND } diff --git a/tests/src/JIT/Methodical/xxblk/dynblk.il b/tests/src/JIT/Methodical/xxblk/dynblk.il new file mode 100644 index 0000000000..b0acbb4d4f --- /dev/null +++ b/tests/src/JIT/Methodical/xxblk/dynblk.il @@ -0,0 +1,99 @@ +// 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. + +// Test for a bug involving an initblk with a non-constant size, +// for which the DYN_BLK(ADDR(lcl)) can't be optimized away. + +.assembly extern legacy library mscorlib {} +.assembly extern System.Console +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) + .ver 4:0:0:0 +} + +.assembly dynblk {} + +.class public sequential ansi sealed beforefieldinit S8 + extends [mscorlib]System.ValueType +{ + .field public uint64 val +} // end of class S8 + +.class private auto ansi beforefieldinit Program + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 GetSize3() cil managed noinlining + { + ldc.i4 3 + ret + } // end of method Program::Init + + .method public hidebysig static int32 GetSize5() cil managed noinlining + { + ldc.i4 5 + ret + } // end of method Program::Init + + .method private hidebysig static int32 + Main() cil managed + { + .entrypoint + .locals init (valuetype S8 S, int32 retVal, int32 size) + ldloca.s S + ldc.i4 0 + ldc.i4 8 + initblk + + call int32 Program::GetSize5() + stloc.s size + + ldloca.s S + ldc.i4 0x55 + ldloc.s size + initblk + + call int32 Program::GetSize3() + stloc.s size + + ldloca.s S + ldc.i4 0x33 + ldloc.s size + initblk + + ldloca.s S + ldfld uint64 S8::val + ldc.i8 0x5555333333 + ceq + brtrue.s L1 + + ldstr "Fail" + call void [mscorlib]System.Console::WriteLine(string) + nop + ldc.i4.m1 + stloc.s retVal + br.s L2 + + L1: ldstr "Pass" + call void [mscorlib]System.Console::WriteLine(string) + nop + ldc.i4.s 100 + stloc.s retVal + + L2: ldloc.s retVal + ret + } // end of method Program::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + nop + ret + } // end of method Program::.ctor + +} // end of class Program + diff --git a/tests/src/JIT/Methodical/xxblk/dynblk_il_d.ilproj b/tests/src/JIT/Methodical/xxblk/dynblk_il_d.ilproj new file mode 100644 index 0000000000..1c81e9afac --- /dev/null +++ b/tests/src/JIT/Methodical/xxblk/dynblk_il_d.ilproj @@ -0,0 +1,36 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + + + False + + + + Full + + + + + + + + + + + diff --git a/tests/src/JIT/Methodical/xxblk/dynblk_il_r.ilproj b/tests/src/JIT/Methodical/xxblk/dynblk_il_r.ilproj new file mode 100644 index 0000000000..fb41dd60b0 --- /dev/null +++ b/tests/src/JIT/Methodical/xxblk/dynblk_il_r.ilproj @@ -0,0 +1,35 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + PdbOnly + False + + + + False + + + + + + + + + + + + -- 2.34.1