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

Reply via email to