[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