[llvm] [InstCombine] Fold extended add/sub of the same type (PR #185259)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 10:06:28 PDT 2026
sweiglbosker wrote:
> `zext` and `trunc` don't seem to be involved in the core of this optimization. I think this can be considered more general:
>
> * `umin(a + b, lower bitwidth MAX)` --> `uadd.sat(a, b)`
>
> * `smax(a - b, 0)` --> `usub.sat(a, b)`
Im not sure exactly what fold you are talking about here, pls write proofs. But i will try and guess.
umin(a+b, U<N>_MAX) -> uadd.sat.i<N>(a, b) is invalid, i.e take a = 0, b = 256 for the u16 case.
but if the result of a + b is known to not overflow, (which is what the zext contributes in the pattern), they are equivalent.
the trunc is what makes it directly fold to the uadd (because 8 bit saturating add produces an 8 bit result)
if there is no trunc, you could fold to zext(uadd.sat(a, b)) i guess.
And yes there are probably ways t ogeneralize this pattern, but its fine to keep simple for now.
original motivation was to handle this case,
```cpp
uint8_t uadd_sat8(uint8_t a, uint8_t b) {
uint16_t sum = a + b;
return (sum > 255) ? 255 : (uint8_t)sum;
}
```
which I also now notice is the first result that comes up when you google "c function to do saturating 8 bit add".
https://github.com/llvm/llvm-project/pull/185259
More information about the llvm-commits
mailing list