diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index ee576b1bc35964..ae8411da83d15b 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -5918,10 +5918,35 @@ void Compiler::optRemoveRedundantZeroInits() assert(fgNodeThreading == NodeThreading::AllTrees); - for (BasicBlock* block = fgFirstBB; (block != nullptr) && !block->HasFlag(BBF_MARKED); - block = block->GetUniqueSucc()) + for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->GetUniqueSucc()) { - block->SetFlags(BBF_MARKED); + if (m_dfsTree->HasCycle()) + { + // See if this block is a cycle entry + // + bool stop = false; + for (FlowEdge* predEdge = BlockPredsWithEH(block); predEdge != nullptr; + predEdge = predEdge->getNextPredEdge()) + { + BasicBlock* const predBlock = predEdge->getSourceBlock(); + if (m_dfsTree->IsAncestor(block, predBlock)) + { + JITDUMP(FMT_BB " is part of a cycle, stopping the block scan\n", block->bbNum); + stop = true; + break; + } + } + + // If so, stop looking for redundant zero inits + // + if (stop) + { + break; + } + } + + JITDUMP("Analyzing " FMT_BB "\n", block->bbNum); + CompAllocator allocator(getAllocator(CMK_ZeroInit)); LclVarRefCounts defsInBlock(allocator); bool removedTrackedDefs = false; @@ -6038,7 +6063,7 @@ void Compiler::optRemoveRedundantZeroInits() if (tree->Data()->IsIntegralConst(0)) { - bool bbInALoop = block->HasFlag(BBF_BACKWARD_JUMP); + bool bbInALoop = false; bool bbIsReturn = block->KindIs(BBJ_RETURN); if (!bbInALoop || bbIsReturn) @@ -6116,12 +6141,6 @@ void Compiler::optRemoveRedundantZeroInits() } } } - - for (BasicBlock* block = fgFirstBB; (block != nullptr) && block->HasFlag(BBF_MARKED); - block = block->GetUniqueSucc()) - { - block->RemoveFlags(BBF_MARKED); - } } //------------------------------------------------------------------------ diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_103477/Runtime_103477.cs b/src/tests/JIT/Regression/JitBlue/Runtime_103477/Runtime_103477.cs new file mode 100644 index 00000000000000..66923ef0330fdb --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_103477/Runtime_103477.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_103477 +{ + static int s_count; + + [Fact] + public static int Test() + { + int result = -1; + try + { + Problem(); + result = 100; + } + catch (Exception) + { + } + return result; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Problem() + { + string s = "12151"; + int i = 0; + + char? a = null; + int count = 0; + while (true) + { + string? res = get(s, ref i, ref a); + if (res != null) + { + Count(res); + a = null; // !!! this line is removed from the published version + continue; + } + + if (i >= s.Length) + break; + + a = '.'; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Count(string s) + { + s_count++; + if (s_count > 5) throw new Exception(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static string? get(string s, ref int index, ref char? a) + { + if (index >= s.Length) + return null; + + if (a == '.') + return "."; + + a ??= s[index++]; + return (a == '1') ? "1" : null; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_103477/Runtime_103477.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_103477/Runtime_103477.csproj new file mode 100644 index 00000000000000..197767e2c4e249 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_103477/Runtime_103477.csproj @@ -0,0 +1,5 @@ + + + + +