diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 0d2c3c99d58edc..1bc95700b2facc 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -4304,17 +4304,19 @@ PhaseStatus Compiler::optUnrollLoops() // Heuristic: Estimated cost in code size of the unrolled loop. { - ClrSafeInt loopCostSz; // Cost is size of one iteration - auto tryIndex = loop.lpTop->bbTryIndex; + ClrSafeInt loopCostSz; // Cost is size of one iteration + const BasicBlock* const top = loop.lpTop; // Besides calculating the loop cost, also ensure that all loop blocks are within the same EH // region, and count the number of BBJ_RETURN blocks in the loop. loopRetCount = 0; for (BasicBlock* const block : loop.LoopBlocks()) { - if (block->bbTryIndex != tryIndex) + if (!BasicBlock::sameEHRegion(block, top)) { // Unrolling would require cloning EH regions + // Note that only non-funclet model (x86) could actually have a loop including a handler + // but not it's corresponding `try`, if its `try` was moved due to being marked "rare". JITDUMP("Failed to unroll loop " FMT_LP ": EH constraint\n", lnum); goto DONE_LOOP; } @@ -8804,6 +8806,12 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk) } } } + + // Clear the Value Number from the statement root node, if it was set above. This is to + // ensure that for those blocks that are unreachable, which we still handle in this loop + // but not during Value Numbering, fgDebugCheckExceptionSets() will skip the trees. Ideally, + // we wouldn't be touching the gtVNPair at all (here) before actual Value Numbering. + stmt->GetRootNode()->gtVNPair.SetBoth(ValueNumStore::NoVN); } if (memoryHavoc != emptyMemoryKindSet) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_81675/Runtime_81675.cs b/src/tests/JIT/Regression/JitBlue/Runtime_81675/Runtime_81675.cs new file mode 100644 index 00000000000000..183aa1378f6c24 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_81675/Runtime_81675.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Generated by Fuzzlyn v1.5 on 2023-02-06 00:41:34 +// Run on X86 Windows +// Seed: 12611629827253727687 +// Reduced from 444.9 KiB to 1.1 KiB in 00:13:23 +// Hits JIT assert in Release: +// Assertion failed '!"Jump into the middle of handler region"' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Unroll loops' (IL size 131; hash 0xade6b36b; FullOpts) +// +// File: D:\a\_work\1\s\src\coreclr\jit\fgdiagnostic.cpp Line: 2609 +// +public interface I0 +{ +} + +public class C0 : I0 +{ + public sbyte F3; +} + +public class Runtime_81675 +{ + public static ushort s_11; + public static bool[][] s_18; + public static C0 s_26; + public static short[] s_42; + public static int Main() + { + short vr7 = default(short); + for (int vr8 = 0; vr8 < 0; vr8++) + { + try + { + System.Console.WriteLine(32767); + } + finally + { + I0 vr9 = new C0(); + } + } + + for (int vr10 = 0; vr10 < 0; vr10++) + { + if (s_18[0][0]) + { + var vr11 = s_26.F3; + } + else + { + System.Console.WriteLine(0); + } + + if (!((ushort)(-s_11++) >= 0)) + { + vr7 = vr7; + try + { + vr7 = 0; + } + finally + { + vr7 = s_42[0]; + } + } + } + + return 100; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_81675/Runtime_81675.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_81675/Runtime_81675.csproj new file mode 100644 index 00000000000000..c0a5f3d0484e39 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_81675/Runtime_81675.csproj @@ -0,0 +1,9 @@ + + + Exe + True + + + + + \ No newline at end of file