[llvm] [InstCombine] Fold extended add/sub of the same type (PR #185259)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 9 17:48:24 PDT 2026
suoyuan666 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)`
> > ```
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > I'm currently conducting this test locally, along with the other scenarios mentioned by @sweiglbosker . Once my locally written test and existing tests pass, I will push and update the PR description.
>
> I'm not sure exactly what fold you are talking about, please write proofs.
>
> If you mean `umin(a+b, <N>_MAX) -> uadd.sat.i<N>(a, b)`, you are incorrect: https://alive2.llvm.org/ce/z/bs36GM
>
> but if the result of a + b is known to not overflow (this is what the zext contributes to the pattern), they are equivalent
>
> the trunc is what makes it directly fold to the uadd.sat (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 generalizations are possible but the many motivation was to handle this case:
>
> ```c
> uint8_t saturating_add_scalar(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"
You're right, I didn't consider this situation. Then I'll just revert to the treatment for saturated addition and subtraction.
https://github.com/llvm/llvm-project/pull/185259
More information about the llvm-commits
mailing list