Skip to content

JIT: (bug) Loop cloning drops bounds checks when the limit local is redefined between the zero-trip guard and the loop preheader #133762

Description

@EgorBo

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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions