]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
MATCH: Simplify `min(a, b) op max(a, b)` to `a op b` [PR109401]
authorEikansh Gupta <quic_eikagupt@quicinc.com>
Mon, 11 Nov 2024 11:55:45 +0000 (17:25 +0530)
committerAndrew Pinski <quic_apinski@quicinc.com>
Sat, 16 Nov 2024 19:10:49 +0000 (11:10 -0800)
This patch simplify `min(a,b) op max(a,b)` to `a op b`. This optimization
will work for all the binary commutative operations. So, the `op` here can
be one of {plus, mult, bit_and, bit_xor, bit_ior, eq, ne, min, max}.

PR tree-optimization/109401

gcc/ChangeLog:

* match.pd (min(a,b) op max(a,b) -> a op b): New pattern.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/pr109401.c: New test.
* gcc.dg/tree-ssa/pr109401-1.c: New test.

Signed-off-by: Eikansh Gupta <quic_eikagupt@quicinc.com>
gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr109401-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr109401.c [new file with mode: 0644]

index 753bf811f67a1eae7cfe70d71cd8832cad0eadbc..9370764223237c8f219350cdcfb5941553aa8f74 100644 (file)
@@ -4657,6 +4657,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     @0
     @2)))
 
+/* min (a, b) op max (a, b) -> a op b */
+(for op (plus mult bit_and bit_xor bit_ior eq ne min max)
+ (simplify
+  (op:c (min:c @0 @1) (max @0 @1))
+   (if (!HONOR_NANS (@0))
+    (op @0 @1))))
+
 /* Simplify min (&var[off0], &var[off1]) etc. depending on whether
    the addresses are known to be less, equal or greater.  */
 (for minmax (min max)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109401-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109401-1.c
new file mode 100644 (file)
index 0000000..3f72516
--- /dev/null
@@ -0,0 +1,35 @@
+/* PR tree-optimization/109878 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Returns max (a, b) */
+int max(int a, int b) {
+  if (b > a)
+    return b;
+  else
+    return a;
+}
+
+/* Returns min (a, b) */
+int min(int a, int b) {
+  if (b < a)
+    return b;
+  else
+    return a;
+}
+
+/* These functions should return a op b */
+int f8(int a, int b)
+{
+  return min (max (a, b), min (a, b));
+}
+
+int f9(int a, int b)
+{
+  return max (min (a, b), max (a, b));
+}
+
+/* Function min and f8 should have MIN_EXPR */
+/* Function max and f9 should have MAX_EXPR */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109401.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109401.c
new file mode 100644 (file)
index 0000000..11177d9
--- /dev/null
@@ -0,0 +1,61 @@
+/* PR tree-optimization/109878 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Returns max (a, b) */
+int max(int a, int b) {
+  if (b > a)
+    return b;
+  else
+    return a;
+}
+
+/* Returns min (a, b) */
+int min(int a, int b) {
+  if (b < a)
+    return b;
+  else
+    return a;
+}
+
+/* All the functions here shouldn't evalute min or max of a and b
+ * These functions should return a op b */
+int f(int a, int b)
+{
+  return max (a, b) + min (a, b);
+}
+
+int f1(int a, int b)
+{
+  return max (a, b) * min (a, b);
+}
+
+int f2(int a, int b)
+{
+  return max (a, b) | min (a, b);
+}
+
+int f3(int a, int b)
+{
+  return max (a, b) & min (a, b);
+}
+
+int f5(int a, int b)
+{
+  return min (a, b) ^ max (a, b);
+}
+
+int f6(int a, int b)
+{
+  return min (a, b) == max (a, b);
+}
+
+int f7(int a, int b)
+{
+  return min (a, b) != max (a, b);
+}
+
+/* Function min should have MIN_EXPR */
+/* Function max should have MAX_EXPR */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "optimized" } } */