Skip to content

JIT: (bug) Strength reduction produces wrong values: AddRecMayOverflow treats a non-constant add-recurrence start as zero #133759

Description

@EgorBo

Minimal repro

using System;
using System.Runtime.CompilerServices;

public static class Program
{
    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
    public static void Test(int seed, long[] dst)
    {
        int c = seed;
        for (int i = 0; i < 10; i++)
        {
            dst[i] = (uint)c * 8L;
            c++;
        }
    }

    public static int Main()
    {
        long[] actual = new long[10];
        Test(-3, actual);

        long[] expected = new long[10];
        for (int i = 0, c = -3; i < 10; i++, c++)
            expected[i] = (uint)c * 8L;

        Console.WriteLine("expected: " + string.Join(",", expected));
        Console.WriteLine("actual:   " + string.Join(",", actual));
        for (int i = 0; i < 10; i++)
            if (actual[i] != expected[i]) { Console.WriteLine("FAILED"); return 101; }
        Console.WriteLine("PASSED");
        return 100;
    }
}

Expected

34359738344,34359738352,34359738360,0,8,16,24,32,40,48 (the int counter wraps through zero, so (uint)c restarts at 0). Reproduced with DOTNET_JitEnableStrengthReduction=0.

Actual

34359738344,34359738352,34359738360,34359738368,34359738376,34359738384,34359738392,34359738400,34359738408,34359738416 — the sequence keeps climbing past 2^32*8, exit code 101.

Notes

scev.cpp:1738-1742 in AddRecMayOverflow returns "cannot overflow" whenever Start->GetConstantValue() fails, i.e. treats any symbolic start as 0, contradicting the comment at scev.cpp:1731 ("only ... addRec = <L, 0, 1>"). Simplify (scev.cpp:1132-1136) then distributes the zext into <L, V02.2, 1> producing <L, zext(V02.2), 1>, and strength reduction materializes it as a new 64-bit primary IV. Correct shape would be the step guard's form: if (!GetConstantValue(...) || (startCns != 0)) return true;.

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