JIT: (bug) Strength reduction computes `int.MinValue % -1` in `Gcd`, faulting the JIT with an integer-divide overflow
- 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 class Program
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
public static int Test(int n)
{
int sum = 0;
int i = 0;
for (int c = 0; c < n; c++)
{
sum += i * 1431655765; // derived IV step = 3 * 0x55555555 = -1
sum += i << 31; // derived IV step = 3 << 31 = int.MinValue
i += 3;
}
return sum;
}
public static int Main()
{
Console.WriteLine(Test(5));
return 100;
}
}
```
### Expected
`-10` (printed with `DOTNET_JitEnableStrengthReduction=0`)
### Actual
JIT faults while compiling `Test`; the hardware `#DE` surfaces as
`Unhandled exception. System.OverflowException: Arithmetic operation resulted in an overflow.` at the `Test` call site, exit code `0xE0434352`.
### Notes
Two derived IVs with steps `-1` and `int.MinValue` reach `ComputeRephrasableIVByScaling` (inductionvariableopts.cpp:2156), whose `Gcd` evaluates `b % a` = `int.MinValue % -1` at inductionvariableopts.cpp:2059 — an unrepresentable signed quotient, lowered to `idiv` by MSVC. The `gcd == 1 || gcd == -1` rejection happens only after the remainder. The `int64_t` instantiation has the same hazard.
Contributor guide
Research direction
Start with the minimal C# repro and inspect ComputeRephrasableIVByScaling in inductionvariableopts.cpp around lines 2059 and 2156, including the Gcd implementation. Run the repro with strength reduction enabled and disabled to observe the failure and expected result. Done means the JIT no longer faults for the int32 case and the corresponding int64 hazard is addressed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, csharp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100