diff options
-rw-r--r-- | src/jit/compiler.hpp | 4 | ||||
-rw-r--r-- | src/jit/copyprop.cpp | 2 | ||||
-rw-r--r-- | src/jit/jithashtable.h | 19 | ||||
-rw-r--r-- | src/jit/lclvars.cpp | 4 | ||||
-rw-r--r-- | src/jit/morph.cpp | 20 | ||||
-rw-r--r-- | src/jit/optimizer.cpp | 2 | ||||
-rw-r--r-- | src/jit/rangecheck.cpp | 13 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.cs | 52 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.csproj | 17 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231b.cs | 61 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231b.csproj | 17 |
11 files changed, 193 insertions, 18 deletions
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp index a9dc3bbc5f..c1be6acbbe 100644 --- a/src/jit/compiler.hpp +++ b/src/jit/compiler.hpp @@ -3291,7 +3291,7 @@ inline void Compiler::LoopDsc::AddModifiedField(Compiler* comp, CORINFO_FIELD_HA lpFieldsModified = new (comp->getAllocatorLoopHoist()) Compiler::LoopDsc::FieldHandleSet(comp->getAllocatorLoopHoist()); } - lpFieldsModified->Set(fldHnd, true); + lpFieldsModified->Set(fldHnd, true, FieldHandleSet::Overwrite); } inline void Compiler::LoopDsc::AddModifiedElemType(Compiler* comp, CORINFO_CLASS_HANDLE structHnd) @@ -3301,7 +3301,7 @@ inline void Compiler::LoopDsc::AddModifiedElemType(Compiler* comp, CORINFO_CLASS lpArrayElemTypesModified = new (comp->getAllocatorLoopHoist()) Compiler::LoopDsc::ClassHandleSet(comp->getAllocatorLoopHoist()); } - lpArrayElemTypesModified->Set(structHnd, true); + lpArrayElemTypesModified->Set(structHnd, true, ClassHandleSet::Overwrite); } inline void Compiler::LoopDsc::VERIFY_lpIterTree() diff --git a/src/jit/copyprop.cpp b/src/jit/copyprop.cpp index d0d173d519..4611e91b54 100644 --- a/src/jit/copyprop.cpp +++ b/src/jit/copyprop.cpp @@ -365,7 +365,7 @@ void Compiler::optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curS stack = new (curSsaName->GetAllocator()) GenTreePtrStack(curSsaName->GetAllocator()); } stack->Push(tree); - curSsaName->Set(lclNum, stack); + curSsaName->Set(lclNum, stack, LclNumToGenTreePtrStack::Overwrite); } // If we encounter first use of a param or this pointer add it as a live definition. // Since they are always live, do it only once. diff --git a/src/jit/jithashtable.h b/src/jit/jithashtable.h index d411a2b870..c68e4c8480 100644 --- a/src/jit/jithashtable.h +++ b/src/jit/jithashtable.h @@ -234,15 +234,25 @@ public: // Arguments: // k - the key // v - the value + // kind - Normal, we are not allowed to overwrite + // Overwrite, we are allowed to overwrite + // currently only used by CHK/DBG builds in an assert. // // Return Value: - // `true` if the key already exists, `false` otherwise. + // `true` if the key exists and was overwritten, + // `false` otherwise. // // Notes: - // If the key already exists then its associated value is updated to - // the new value. + // If the key already exists and kind is Normal + // this method will assert // - bool Set(Key k, Value v) + enum SetKind + { + None, + Overwrite + }; + + bool Set(Key k, Value v, SetKind kind = None) { CheckGrowth(); @@ -257,6 +267,7 @@ public: } if (pN != nullptr) { + assert(kind == Overwrite); pN->m_val = v; return true; } diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp index b9cec032b2..a251534bd1 100644 --- a/src/jit/lclvars.cpp +++ b/src/jit/lclvars.cpp @@ -1949,7 +1949,7 @@ Compiler::lvaStructFieldInfo Compiler::StructPromotionHelper::GetFieldInfo(CORIN fieldInfo.fldType = compiler->getSIMDTypeForSize(simdSize); fieldInfo.fldSize = simdSize; #ifdef DEBUG - retypedFieldsMap.Set(fieldInfo.fldHnd, fieldInfo.fldType); + retypedFieldsMap.Set(fieldInfo.fldHnd, fieldInfo.fldType, RetypedAsScalarFieldsMap::Overwrite); #endif // DEBUG } } @@ -2053,7 +2053,7 @@ bool Compiler::StructPromotionHelper::TryPromoteStructField(lvaStructFieldInfo& fieldInfo.fldType = fieldVarType; fieldInfo.fldSize = fieldSize; #ifdef DEBUG - retypedFieldsMap.Set(fieldInfo.fldHnd, fieldInfo.fldType); + retypedFieldsMap.Set(fieldInfo.fldHnd, fieldInfo.fldType, RetypedAsScalarFieldsMap::Overwrite); #endif // DEBUG return true; } diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 48d97cfe4c..9d0193ba85 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -13640,8 +13640,15 @@ DONE_MORPHING_CHILDREN: if (isZeroOffset) { + // The "op1" node might already be annotated with a zero-offset field sequence. + FieldSeqNode* existingZeroOffsetFldSeq = nullptr; + if (GetZeroOffsetFieldMap()->Lookup(op1, &existingZeroOffsetFldSeq)) + { + // Append the zero field sequences + zeroFieldSeq = GetFieldSeqStore()->Append(existingZeroOffsetFldSeq, zeroFieldSeq); + } // Transfer the annotation to the new GT_ADDR node. - GetZeroOffsetFieldMap()->Set(op1, zeroFieldSeq); + GetZeroOffsetFieldMap()->Set(op1, zeroFieldSeq, NodeToFieldSeqMap::Overwrite); } commaNode->gtOp.gtOp2 = op1; // Originally, I gave all the comma nodes type "byref". But the ADDR(IND(x)) == x transform @@ -18743,7 +18750,16 @@ void Compiler::fgAddFieldSeqForZeroOffset(GenTree* op1, FieldSeqNode* fieldSeq) default: // Record in the general zero-offset map. - GetZeroOffsetFieldMap()->Set(op1, fieldSeq); + + // The "op1" node might already be annotated with a zero-offset field sequence. + FieldSeqNode* existingZeroOffsetFldSeq = nullptr; + if (GetZeroOffsetFieldMap()->Lookup(op1, &existingZeroOffsetFldSeq)) + { + // Append the zero field sequences + fieldSeq = GetFieldSeqStore()->Append(existingZeroOffsetFldSeq, fieldSeq); + } + // Set the new field sequence annotation for op1 + GetZeroOffsetFieldMap()->Set(op1, fieldSeq, NodeToFieldSeqMap::Overwrite); break; } } diff --git a/src/jit/optimizer.cpp b/src/jit/optimizer.cpp index 9d9b515ec4..795625aaf2 100644 --- a/src/jit/optimizer.cpp +++ b/src/jit/optimizer.cpp @@ -3775,7 +3775,7 @@ void Compiler::optUnrollLoops() { BasicBlock* newBlock = insertAfter = fgNewBBafter(block->bbJumpKind, insertAfter, /*extendRegion*/ true); - blockMap.Set(block, newBlock); + blockMap.Set(block, newBlock, BlockToBlockMap::Overwrite); if (!BasicBlock::CloneBlockState(this, newBlock, block, lvar, lval)) { diff --git a/src/jit/rangecheck.cpp b/src/jit/rangecheck.cpp index b96374455c..8255afeecf 100644 --- a/src/jit/rangecheck.cpp +++ b/src/jit/rangecheck.cpp @@ -362,7 +362,7 @@ bool RangeCheck::IsMonotonicallyIncreasing(GenTree* expr, bool rejectNegativeCon JITDUMP("[RangeCheck::IsMonotonicallyIncreasing] [%06d]\n", Compiler::dspTreeID(expr)); // Add hashtable entry for expr. - bool alreadyPresent = m_pSearchPath->Set(expr, nullptr); + bool alreadyPresent = !m_pSearchPath->Set(expr, nullptr, SearchPath::Overwrite); if (alreadyPresent) { return true; @@ -1014,7 +1014,7 @@ bool RangeCheck::DoesOverflow(BasicBlock* block, GenTree* expr) bool RangeCheck::ComputeDoesOverflow(BasicBlock* block, GenTree* expr) { JITDUMP("Does overflow [%06d]?\n", Compiler::dspTreeID(expr)); - m_pSearchPath->Set(expr, block); + m_pSearchPath->Set(expr, block, SearchPath::Overwrite); bool overflows = true; @@ -1050,7 +1050,7 @@ bool RangeCheck::ComputeDoesOverflow(BasicBlock* block, GenTree* expr) { overflows = DoesPhiOverflow(block, expr); } - GetOverflowMap()->Set(expr, overflows); + GetOverflowMap()->Set(expr, overflows, OverflowMap::Overwrite); m_pSearchPath->Remove(expr); return overflows; } @@ -1064,11 +1064,12 @@ bool RangeCheck::ComputeDoesOverflow(BasicBlock* block, GenTree* expr) // eg.: merge((0, dep), (dep, dep)) = (0, dep) Range RangeCheck::ComputeRange(BasicBlock* block, GenTree* expr, bool monotonic DEBUGARG(int indent)) { - bool newlyAdded = !m_pSearchPath->Set(expr, block); + bool newlyAdded = !m_pSearchPath->Set(expr, block, SearchPath::Overwrite); Range range = Limit(Limit::keUndef); ValueNum vn = m_pCompiler->vnStore->VNConservativeNormalValue(expr->gtVNPair); - // If newly added in the current search path, then reduce the budget. + + // If we just added 'expr' in the current search path, then reduce the budget. if (newlyAdded) { // Assert that we are not re-entrant for a node which has been @@ -1172,7 +1173,7 @@ Range RangeCheck::ComputeRange(BasicBlock* block, GenTree* expr, bool monotonic range = Range(Limit(Limit::keUnknown)); } - GetRangeMap()->Set(expr, new (m_alloc) Range(range)); + GetRangeMap()->Set(expr, new (m_alloc) Range(range), RangeMap::Overwrite); m_pSearchPath->Remove(expr); return range; } diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.cs b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.cs new file mode 100644 index 0000000000..00466dabd2 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.cs @@ -0,0 +1,52 @@ +// 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; + +// Test case for issue 21231 +// +// +// Debug: Outputs 2 +// Release: Outputs 1 +struct S0 +{ + public sbyte F0; + public S0(sbyte p0): this() + { + F0 = p0; + } +} + +struct S1 +{ + public S0 F2; + public ushort F1; + public S1(S0 p2): this() + { + F2 = p2; + } +} + +public class Program +{ + public static int Main() + { + var vr22 = new S1[]{new S1(new S0(1))}; + S1 vr26; + vr26.F2 = vr22[0].F2; + vr22[0].F2.F0 += vr22[0].F2.F0; + vr26.F2 = vr22[0].F2; + + if (vr26.F2.F0 != 2) + { + System.Console.WriteLine("Failed"); + return -1; + } + else + { + System.Console.WriteLine("Passed"); + return 100; + } + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.csproj new file mode 100644 index 0000000000..d86ed9f3d7 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231a.csproj @@ -0,0 +1,17 @@ +<?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)' == '' ">Release</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>$(MSBuildProjectName)</AssemblyName> + <OutputType>Exe</OutputType> + <DebugType></DebugType> + <Optimize>True</Optimize> + </PropertyGroup> + <ItemGroup> + <Compile Include="$(MSBuildProjectName).cs" /> + </ItemGroup> + <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/Regression/JitBlue/GitHub_21231/GitHub_21231b.cs b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231b.cs new file mode 100644 index 0000000000..66f75a1131 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231b.cs @@ -0,0 +1,61 @@ +// 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; + +// Test case for issue 21231 +// +// +// Debug: Outputs 2 +// Release: Outputs 1 +struct S0 +{ + public sbyte F0; + public S0(sbyte p0): this() + { + F0 = p0; + } +} + +struct S1 +{ + public S0 F1; + public ushort F2; + public S1(S0 p2): this() + { + F1 = p2; + } +} + +struct S2 +{ + public S1 F3; + public S2(S0 p3): this() + { + F3 = new S1(p3); + } +} + +public class Program +{ + public static int Main() + { + var vr22 = new S2[]{new S2(new S0(1))}; + S2 vr26; + vr26.F3.F1 = vr22[0].F3.F1; + vr22[0].F3.F1.F0 += vr22[0].F3.F1.F0; + vr26.F3.F1 = vr22[0].F3.F1; + + if (vr26.F3.F1.F0 != 2) + { + System.Console.WriteLine("Failed"); + return -1; + } + else + { + System.Console.WriteLine("Passed"); + return 100; + } + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231b.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231b.csproj new file mode 100644 index 0000000000..d86ed9f3d7 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_21231/GitHub_21231b.csproj @@ -0,0 +1,17 @@ +<?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)' == '' ">Release</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>$(MSBuildProjectName)</AssemblyName> + <OutputType>Exe</OutputType> + <DebugType></DebugType> + <Optimize>True</Optimize> + </PropertyGroup> + <ItemGroup> + <Compile Include="$(MSBuildProjectName).cs" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> + <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> +</Project>
\ No newline at end of file |