https://gcc.gnu.org/g:5dee3c6521c2787836c3925221d603a20ef0ae2c
commit r17-370-g5dee3c6521c2787836c3925221d603a20ef0ae2c Author: Pengxuan Zheng <[email protected]> Date: Fri Mar 27 09:54:23 2026 -0700 match: min|max(a+|-c,b+|-c) -> min|max(a,b)+|-c [PR116008,PR124560] The patch adds the following simplification patterns. min|max (a +|- c, b +|- c) -> min|max (a, b) +|- c Bootstrapped and tested on x86_64-linux-gnu and aarch64-linux-gnu. PR tree-optimization/116008 PR tree-optimization/124560 gcc/ChangeLog: * match.pd (min|max(a+|-c,b+|-c)): New patterns. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr124560.c: New test. Signed-off-by: Pengxuan Zheng <[email protected]> Diff: --- gcc/match.pd | 16 ++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr124560.c | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/gcc/match.pd b/gcc/match.pd index 7db8ce7580f3..1a7d820779f4 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5006,6 +5006,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && operand_equal_p (@1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST)) @0))) +/* minmax (a + c, b + c) -> minmax (a, b) + c */ +(for minmax (min max) + (simplify + (minmax:c (plus:cs @0 @2) (plus:s @1 @2)) + (if (TYPE_OVERFLOW_UNDEFINED (type) + && !TYPE_OVERFLOW_SANITIZED (type)) + (plus (minmax @0 @1) @2)))) + +/* minmax (a - c, b - c) -> minmax (a, b) - c */ +(for minmax (min max) + (simplify + (minmax:c (minus:s @0 @2) (minus:s @1 @2)) + (if (TYPE_OVERFLOW_UNDEFINED (type) + && !TYPE_OVERFLOW_SANITIZED (type)) + (minus (minmax @0 @1) @2)))) + /* max (a, a + CST) -> a + CST where CST is positive. */ /* max (a, a + CST) -> a where CST is negative. */ (simplify diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr124560.c b/gcc/testsuite/gcc.dg/tree-ssa/pr124560.c new file mode 100644 index 000000000000..cef7248b61bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr124560.c @@ -0,0 +1,43 @@ + +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop1-folding-raw" } */ + +static inline int +min (int a, int b) +{ + return a < b ? a : b; +} + +static inline int +max (int a, int b) +{ + return a > b ? a : b; +} + +int +f1 (int x, int y, int z) +{ + return min (z + y, x + y); +} + +int +f2 (int x, int y, int z) +{ + return min (z - y, x - y); +} + +int +f3 (int x, int y, int z) +{ + return max (z + y, x + y); +} + +int +f4 (int x, int y, int z) +{ + return max (z - y, x - y); +} + +/* { dg-final { scan-tree-dump-times "Applying pattern" 4 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "plus_expr" 2 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "minus_expr" 2 "forwprop1" } } */
