JIT: Support constant folding back into SELECT (or branches in general)
- Dominant language
- C#
- Stars
- 18.3k
- Forks
- 5.6k
- PR merge metrics
- PR metrics pending
Description
Example: We could constant fold the addition by ten back into the SELECT arms (so basically `int sel = wide ? 13 : 14`):
https://godbolt.org/z/TdqzqbrcY
```cs
static int GetRex(bool wide)
{
int sel = wide ? 3 : 4;
int res = sel + 10;
return res;
}
```
```assembly
Program:GetRex(bool):int (FullOpts):
mov eax, 3
mov ecx, 4
test dil, dil
cmove eax, ecx
add eax, 10
ret
```
I've encountered this type of thing a few times now dealing with bit-op stuff.
Seems easy in theory, but lack of SSA folding or if-conversion currently running so late makes it near-unfeasible to recognize the shape.
```
------------ BB01 [0000] [000..003) -> BB04(1) (always), preds={} succs={BB04}
***** BB01 [0000]
STMT00003 ( 0x003[E--] ... 0x004 )
N008 ( 12, 12) [000012] DA---+----- * STORE_LCL_VAR int V02 tmp1 d:2 $VN.Void
N007 ( 8, 9) [000019] ----------- \--* SELECT int
N004 ( 5, 6) [000002] J----+-N--- +--* NE int $101
N002 ( 3, 4) [000014] -----+----- | +--* CAST int <- ubyte <- int $100
N001 ( 2, 2) [000000] -----+----- | | \--* LCL_VAR int V00 arg0 u:1 (last use) $80
N003 ( 1, 1) [000001] -----+----- | \--* CNS_INT int 0 $40
N005 ( 1, 1) [000004] -----+----- +--* CNS_INT int 3 $43
N006 ( 1, 1) [000011] -----+----- \--* CNS_INT int 4 $44
------------ BB04 [0003] [007..00B) (return), preds={BB01} succs={}
***** BB04 [0003]
STMT00002 ( ??? ... 0x00A )
N004 ( 6, 5) [000010] -----+----- * RETURN int $VN.Void
N003 ( 5, 4) [000009] -----+----- \--* ADD int $102
N001 ( 3, 2) [000007] -----+----- +--* LCL_VAR int V02 tmp1 u:3 (last use) $140
N002 ( 1, 1) [000008] -----+----- \--* CNS_INT int 10 $45
```
Of course this could be applied to branches in general but that seems even harder without SSA, e.g:
```cs
static int ConstantFoldNoSelect(int a, int b)
{
int res;
if (a < b)
{
res = 3;
Call();
}
else
{
res = 4;
}
res += 10;
return res;
static extern void Call();
}
```
Contributor guide
Research direction
Start with the linked Godbolt reproduction and compare the generated assembly for GetRex with the shown SELECT IR; the issue also provides ConstantFoldNoSelect as a harder branch case. Done means constant additions can fold into SELECT arms where valid, with the branch example remaining behaviorally correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100