JIT: (bug) Loop cloning drops bounds checks when an arr.Length + K loop limit overflows to a negative value
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
`optDeriveLoopCloningConditions` only emits the `arr.Length + offset >= 0` guard when the peeled limit offset is negative, but the 32-bit add also wraps negative for large positive offsets, so the check-free fast clone runs out of bounds.
### Minimal Repro
```csharp
using System;
using System.Runtime.CompilerServices;
public class Program
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
public static int Test(int[] a, int[] b)
{
int sum = 0;
for (int i = a.Length - 1; i > b.Length + int.MaxValue; i--)
{
sum += a[i];
}
return sum;
}
public static void Main()
{
int[] a = new int[4];
int[] b = new int[4];
try
{
Console.WriteLine("result " + Test(a, b));
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("IndexOutOfRangeException");
}
}
}
```
`b.Length + int.MaxValue` wraps to `-2147483645`, so the decreasing loop must walk `i` below `0` and throw.
### Expected
```
IndexOutOfRangeException
```
`DOTNET_JitCloneLoops=0` produces this correct result.
### Actual
```
Fatal error.
```
Exit code `0xC0000005`. Silent out-of-bounds read from safe C#.
### Notes
- `MatchLimit` / `NaturalLoopIterInfo::LimitOffset` (`src/coreclr/jit/flowgraph.cpp`) peel the constant out of `b.Length + K`; `loopcloning.cpp` guards `arr.Length + offset >= 0` only under `if (iterInfo->LimitOffset < 0)`.
- The derived conditions are only about the initial IV (`(V03 GE 0) && (V03 LT V00.Length)`), both true here, so the check-free clone is entered and `i` walks down through negative values.
- Fix direction: emit the `arr.Length + offset >= 0` condition for positive offsets too, or reject offsets where the add can overflow.
- .NET 11 regression (10.0.12 is correct, 11.0.0-rc.1 Release is bad); introduced by "JIT: extend loop cloning for span+stride>1 and ±const limits" (#129309).
Contributor guide
Assessment
This issue has not been assessed yet.