JIT generates redundant mov for inline ++i (pre-increment)
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/aYMq87E9G
```csharp
// Simplified repro
public static int N(ReadOnlySpan s, int i)
{
while (true)
{
if ((uint)++i >= (uint)s.Length)
break;
if (s[i] == '?')
return i;
}
return -1;
}
```
**Generated ASM:**
```asm
lea eax, [rdx+0x01]
mov edx, eax ; redundant
cmp edx, esi
```
**With a separate increment:**
```csharp
++i;
if ((uint)i >= (uint)s.Length)
break;
```
**Generated ASM:**
```asm
inc edx
cmp edx, esi
```
**.NET 8.0 behavior:** both variants generate identical `inc`; `cmp` code.
**Issue:**
- Inline `++i` adds an extra `mov`, increasing register pressure
- Causes spills in register-constrained methods
- Larger binary size
Contributor guide
Research direction
Start with the C# reproducer and generated assembly at the linked Godbolt example, comparing inline ++i with the separate increment under .NET 8. Identify the JIT path that produces the redundant mov; done when the inline form avoids that move and preserves the demonstrated inc/cmp sequence without regressions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100