Minimal repro
using System;
using System.Runtime.CompilerServices;
public class Program
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
static int Test(int[] a, int i, int n)
{
int sum = 0;
if (i < n)
{
n = a.Length;
do
{
sum += a[i];
i++;
} while (i < n);
}
return sum;
}
public static int Main()
{
int[] a = new int[10];
try
{
int r = Test(a, 20, 30);
Console.WriteLine($"Expected: IndexOutOfRangeException / Actual: returned {r}");
return 1;
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Expected: IndexOutOfRangeException / Actual: IndexOutOfRangeException");
return 100;
}
}
}
Run: corerun repro.dll (Checked or Release JIT, .NET 11 main @ b44cd90)
Expected
a[20] on a 10-element array throws IndexOutOfRangeException; exit code 100.
Actual
No exception
Notes
No JIT knobs needed. DOTNET_JitCloneLoops=0 restores the exception. FlowGraphNaturalLoop::HasZeroTripTest (flowgraph.cpp:6629) accepts the i < n guard without checking that n is not redefined between the guard and the preheader, so NeedsZeroTripGuard stays false and no entry guard is cloned (loopcloning.cpp:1346).
Minimal repro
Run:
corerun repro.dll(Checked or Release JIT, .NET 11 main @ b44cd90)Expected
a[20]on a 10-element array throwsIndexOutOfRangeException; exit code 100.Actual
No exception
Notes
No JIT knobs needed.
DOTNET_JitCloneLoops=0restores the exception.FlowGraphNaturalLoop::HasZeroTripTest(flowgraph.cpp:6629) accepts thei < nguard without checking thatnis not redefined between the guard and the preheader, soNeedsZeroTripGuardstays false and no entry guard is cloned (loopcloning.cpp:1346).