I have seen this a few places though the testcase from PR 95906
is an obvious place where this shows up for sure.
This convert `cmp - 1` into `-icmp` as that form is more useful
in many cases.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/110949
        PR tree-optimization/95906

gcc/ChangeLog:

        * match.pd (cmp - 1): New pattern.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/cmp-2.c: New test.
        * gcc.dg/tree-ssa/max-bitcmp-1.c: New test.

Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
---
 gcc/match.pd                                 | 17 ++++++++++++++++-
 gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c        | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c | 19 +++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 7f84d5149f4..3e8b324e376 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7035,6 +7035,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (icmp @0 @1)
     (if (ic == ncmp)
      (ncmp @0 @1)))))
+ /* ((cast)cmp) - 1 -> -(cast)icmp . */
+ (simplify
+  (plus (convert? (cmp@2 @0 @1)) integer_minus_onep)
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@2)) &&  TYPE_PRECISION (TREE_TYPE (@2)) == 
1)
+   /* Comparison inversion may be impossible for trapping math,
+      invert_tree_comparison will tell us.  But we can't use
+      a computed operator in the replacement tree thus we have
+      to play the trick below.  */
+   (with { enum tree_code ic = invert_tree_comparison
+             (cmp, HONOR_NANS (@0));
+           tree cmptype = TREE_TYPE (@2); }
+    (if (ic == icmp)
+     (negate (convert (icmp:cmptype @0 @1)))
+     (if (ic == ncmp)
+      (negate (convert (ncmp:cmptype @0 @1))))))))
  /* The following bits are handled by fold_binary_op_with_conditional_arg.  */
  (simplify
   (ne (cmp@2 @0 @1) integer_zerop)
@@ -11678,4 +11693,4 @@ and,
       && VECTOR_TYPE_P (type)
       && direct_internal_fn_supported_p (IFN_AVG_CEIL, type, 
OPTIMIZE_FOR_BOTH))
       (IFN_AVG_CEIL @0 @2)))
-#endif
\ No newline at end of file
+#endif
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c
new file mode 100644
index 00000000000..9b029019c06
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop" } */
+
+/* PR tree-optimization/110949 */
+/* Transform `(cmp) - 1` into `-icmp`. */
+
+int f1(int a)
+{
+  int t = a == 115;
+  return t - 1;
+}
+
+/* { dg-final { scan-tree-dump " != 115" "forwprop1" } } */
+/* { dg-final { scan-tree-dump-not " == 115" "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c
new file mode 100644
index 00000000000..81b5a27c045
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop -fdump-tree-optimized" } */
+
+/* PR tree-optimization/95906 */
+/* this should become MAX_EXPR<a,b> */
+
+int f2(int a, int b)
+{
+    int cmp = -(a > b);
+    return (cmp & a) | (~cmp & b);
+}
+
+/*  we should not end up with -_2 */
+/*  we should not end up and & nor a `+ -1` */
+/* In optimized we should have a max.  */
+/* { dg-final { scan-tree-dump-not " -\[a-zA-Z_\]" "forwprop1" } } */
+/* { dg-final { scan-tree-dump-not " & " "forwprop1" } } */
+/* { dg-final { scan-tree-dump-not " . -1" "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR " 1 "optimized" } } */
-- 
2.43.0

Reply via email to