https://gcc.gnu.org/g:fa099f248e2462ecd5ab8b0cadd348aaf11bb093

commit r16-2392-gfa099f248e2462ecd5ab8b0cadd348aaf11bb093
Author: Andrew Pinski <quic_apin...@quicinc.com>
Date:   Sun Jul 20 11:21:08 2025 -0700

    match: Add `cmp - 1` simplification to `-icmp` [PR110949]
    
    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.
    
    Changes since v1:
    * v2: Add check for outer type's precision being greater than 1.
    
    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>

Diff:
---
 gcc/match.pd                                 | 18 +++++++++++++++++-
 gcc/testsuite/gcc.dg/tree-ssa/cmp-2.c        | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/max-bitcmp-1.c | 19 +++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 7f84d5149f42..4903552c82a6 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7035,6 +7035,22 @@ 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 (TYPE_PRECISION (type) > 1
+       && 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 +11694,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 000000000000..9b029019c06f
--- /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 000000000000..81b5a27c0458
--- /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" } } */

Reply via email to