JIT: Optimize linear mapping of values inside switch
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/E1j3nM6c6
Something like the following can frequently happen when converting between enums:
```cs
static int GetFuncArgumentReg(int argumentId)
{
if (argumentId == 0)
{
return 4;
}
if (argumentId == 1)
{
return 5;
}
if (argumentId == 2)
{
return 6;
}
if (argumentId == 3)
{
return 7;
}
throw new Exception();
}
```
There is a simple linear mapping: `argumentId + 4`.
We already have an optimization for `GT_SWITCH` that turns it into a rangecheck if possible. So adding this would be nothing new. However I see that the above code doesn't get switch-recognized, so that'd be the first thing to delve into probably.
Current assembly:
```assembly
Program:GetFuncArgumentReg(int):int (FullOpts):
push rbp
push rbx
push rax
lea rbp, [rsp+0x10]
test edi, edi
je SHORT G_M29572_IG09
cmp edi, 1
je SHORT G_M29572_IG07
cmp edi, 2
je SHORT G_M29572_IG05
cmp edi, 3
jne SHORT G_M29572_IG11
mov eax, 7
add rsp, 8
pop rbx
pop rbp
ret
G_M29572_IG05: ;; offset=0x0027
mov eax, 6
add rsp, 8
pop rbx
pop rbp
ret
G_M29572_IG07: ;; offset=0x0033
mov eax, 5
add rsp, 8
pop rbx
pop rbp
ret
G_M29572_IG09: ;; offset=0x003F
mov eax, 4
add rsp, 8
pop rbx
pop rbp
ret
G_M29572_IG11: ;; offset=0x004B
mov rdi, 0x7D7F3F541690 ; System.Exception
call CORINFO_HELP_NEWSFAST
mov rbx, rax
mov rdi, rbx
call [System.Exception:.ctor():this]
mov rdi, rbx
call CORINFO_HELP_THROW
int3
```
Contributor guide
Research direction
Start with the GetFuncArgumentReg reproducer and its Godbolt link, then trace how the JIT recognizes and optimizes the switch or GT_SWITCH pattern. Compare the generated assembly before and after the change; done means the linear mapping is optimized while the out-of-range exception behavior remains intact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100