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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.