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]>
---
 gcc/match.pd                             | 16 +++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr124560.c | 42 ++++++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr124560.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 7b652afb43d..e9af83db3df 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4970,6 +4970,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 00000000000..761d64ee5a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr124560.c
@@ -0,0 +1,42 @@
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+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 "\\+" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\-" 2 "optimized" } } */
-- 
2.34.1

Reply via email to