https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122593
Bug ID: 122593
Summary: `smax(a, -b) + b` -> `smax(a+b, 0)` but only when
wrapping
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
```
static inline int smax(int a, int b)
{
return a > b ? a : b;
}
int f(int a, int b)
{
return smax(a, -b) + b;
}
int g(int a, int b)
{
return smax(a + b, 0);
}
```
f should turn into g. At least on the rtl level it can be done for riscv and
aarch64+cssc with:
```
Trying 7, 8 -> 14:
7: r108:SI=-r105:SI
8: r107:SI=smax(r108:SI,r109:SI)
REG_DEAD r109:SI
REG_DEAD r108:SI
14: x0:SI=r107:SI+r105:SI
REG_DEAD r105:SI
REG_DEAD r107:SI
Failed to match this instruction:
(set (reg/i:SI 0 x0)
(plus:SI (smax:SI (neg:SI (reg/v:SI 105 [ b ]))
(reg:SI 109 [ a ]))
(reg/v:SI 105 [ b ])))
```
For the gimple level you need a way to say the addition is wrapping (or use
unsigned type addition).
This is forwarded from https://github.com/llvm/llvm-project/issues/166878 .
It comes from ffmpeg even:
s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index);
https://ffmpeg.org/doxygen/trunk/get__bits_8h_source.html#L281