On Sun, Sep 13, 2026 at 12:58 PM Jeff Law <[email protected]> wrote: > > > > On 9/12/26 1:24 AM, Andrea Pinski wrote: > > This adds a simplification for `x+umax(x,1)` to `umax(x*2, 1)` when `x*2` > > is known not to overflow. This shows up with std::vector::push_back > > after the patch which adds `x+minmax(a,b)` simplification; it is also > > a special case of that patch for `umax and 1`. This gives a small > > code generation improvement with std::vector::push_back because we > > trade an add after the umax with a shift beforehand. > > > > Bootstrapped and tested on x86_64-linux-gnu. > > > > PR tree-optimization/127103 > > > > gcc/ChangeLog: > > > > * match.pd (`x+umax(x,1)`): New pattern. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.dg/tree-ssa/max1-plus-1.c: New test. > > > > Signed-off-by: Andrea Pinski <[email protected]> > Not objecting, more a general question. It seems like this is just > trading one form for another. We haven't dropped the number of > expression evaluations nor have we reduced the height of the dependency > tree. So this feels more likely a canonicalizatino pattern or a pattern > designed to change forms to make other optimizations more effective. Is > that a fair characterization?
It is canonicalization to some extent. It is more of a reassociation really. In a similar way `a+(a+b)` and `a+(a*b)` are handled. Note The general form of this is `x+max<a, b>` can be transformed into `max<a+x, b+x>` (assuming both `a+x` and `b+x` have no overflow). In the case of b being 1, the `x+1` can become 1 because we know that if x*2 is 0, x+1 will be 1, otherwise `x+1 >= x*2` (with no overflow which is checked upon) so the only value that matters is 1. Also even though we don't reduce the height of dependencies, the add (shift) is simpler than a max expression so having it first will allow for more issuing first. Note the second patch is enough to remove the branch so this one is less of an important to me. > > Jeff > >
