From: Andrew Pinski <apin...@marvell.com>

Combine disabled this optimization in r10-254-gddbb5da5199fb42 but it makes
sense to do this on the gimple level and then let expand decide which way is
better. So this adds the transformation on the gimple level (late like was
done for the multiply case).

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

        PR tree-optimization/92342

gcc/ChangeLog:

        * match.pd (b & -(a CMP c) -> (a CMP c)?b:0): New pattern.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/andnegcmp-1.c: New test.
        * gcc.dg/tree-ssa/andnegcmp-2.c: New test.
---
 gcc/match.pd                                |  8 +++++++-
 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c | 14 ++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c

diff --git a/gcc/match.pd b/gcc/match.pd
index ed43c321cbc..b55cbc91b57 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1794,7 +1794,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (for cmp (tcc_comparison)
   (simplify
    (mult:c (convert (cmp @0 @1)) @2)
-   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))))
+   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))
+/* (-(m1 CMP m2)) & d -> (m1 CMP m2) ? d : 0  */
+  (simplify
+   (bit_and:c (negate (convert (cmp @0 @1))) @2)
+   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))
+ )
+)
 
 /* For integral types with undefined overflow and C != 0 fold
    x * C EQ/NE y * C into x EQ/NE y.  */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
new file mode 100644
index 00000000000..6f16783f169
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/92342 */
+
+int
+f (int m1, int m2, int c)
+{
+  int d = m1 == m2;
+  d = -d;
+  int e = d & c;
+  return e;
+}
+
+/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "optimized" 
} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
new file mode 100644
index 00000000000..0e25c8abc39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/andnegcmp-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/92342 */
+
+int
+f (int m1, int m2, int c)
+{
+  int d = m1 < m2;
+  d = -d;
+  int e = c & d;
+  return e;
+}
+
+/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "optimized" 
} } */
-- 
2.17.1

Reply via email to