dotnet / dotnet/runtime

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

Closed
#133,759 1 comment 1 reaction 2 assignees Claimed by @jakobbotsch View on GitHub
area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Minimal repro

```csharp
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 = `"). `Simplify` (`scev.cpp:1132-1136`) then distributes the `zext` into `` producing ``, 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;`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.