Re: [PATCH][v2] match: fold the sum of a min/max pair
Jeffrey Law <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
On 8/5/2026 5:53 AM, [email protected] wrote: > From: Kyrylo Tkachov <[email protected]> > > The minimum and the maximum of two values add up to the sum of those > values, so subtracting one of them from the sum yields the other one. > That identity holds in modular arithmetic. It also holds for floating > point when reassociation is enabled and signed zeros and traps are not > honoured. > > int f (int a, int b) { int mn = a < b ? a : b; return (a + b) - mn; } > > aarch64 -O2: > > before after > cmp w1, w0 cmp w1, w0 > add w2, w1, w0 csel w0, w1, w0, ge > csel w0, w1, w0, le > sub w0, w2, w0 > > Bootstrapped and tested on aarch64-none-linux-gnu. > Ok for trunk? > Thanks, > Kyrill > > gcc/ChangeLog: > > * match.pd ((x + y) - minmax (x, y)): New simplification. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/minmax-sum-1.c: New test. > * gcc.dg/tree-ssa/minmax-sum-fp-1.c: Likewise. > * gcc.dg/tree-ssa/minmax-sum-fp-2.c: Likewise. > * g++.target/aarch64/minmax-sum-1.C: Likewise. > > Signed-off-by: Kyrylo Tkachov <[email protected]> > --- > gcc/match.pd | 15 +++++++++++++++ > .../g++.target/aarch64/minmax-sum-1.C | 17 +++++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/minmax-sum-1.c | 18 ++++++++++++++++++ > .../gcc.dg/tree-ssa/minmax-sum-fp-1.c | 15 +++++++++++++++ > .../gcc.dg/tree-ssa/minmax-sum-fp-2.c | 10 ++++++++++ > 5 files changed, 75 insertions(+) > create mode 100644 gcc/testsuite/g++.target/aarch64/minmax-sum-1.C > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-sum-1.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-sum-fp-1.c > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-sum-fp-2.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 728fa8a8d63..35cc995ebf9 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -2051,6 +2051,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > && !TYPE_SATURATING (type)) > (res @0 @1)))) > > +/* (x + y) - min (x, y) -> max (x, y) > + (x + y) - max (x, y) -> min (x, y) > + The sum of the minimum and the maximum is the sum of the operands. */ > +(for minmax (min max) > + maxmin (max min) > + (simplify > + (minus (plus @0 @1) (minmax @0 @1)) > + (if ((ANY_INTEGRAL_TYPE_P (type) > + && !TYPE_OVERFLOW_SANITIZED (type) && !TYPE_OVERFLOW_TRAPS (type)) > + || (FLOAT_TYPE_P (type) > + && flag_associative_math > + && !HONOR_SIGNED_ZEROS (type) > + && !flag_trapping_math)) > + (maxmin @0 @1)))) > + LOL. I was going to suggest a :c on the plus and minmax expressions, but it looks like that was something Andrea explicitly indicated you didn't need :-) OK for the trunk. jeffh