Hi!

On the following testcase, we only optimize bar where this optimization
is performed at GENERIC folding time, but on GIMPLE it doesn't trigger
anymore, as we actually don't see
  (bit_and (ne @1 min_value) (ge @0 @1))
but
  (bit_and (ne @1 min_value) (le @1 @0))
genmatch handles :c modifier not just on commutative operations, but
also comparisons and in that case it means it swaps the comparison.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2022-06-16  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/105983
        * match.pd (y == XXX_MIN || x < y -> x <= y - 1,
        y != XXX_MIN && x >= y -> x > y - 1): Use :cs instead of :s
        on non-equality comparisons.

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

--- gcc/match.pd.jj     2022-06-15 12:52:04.640981511 +0200
+++ gcc/match.pd        2022-06-15 16:25:58.133845269 +0200
@@ -2379,14 +2379,14 @@ (define_operator_list SYNC_FETCH_AND_AND
 
 /* y == XXX_MIN || x < y --> x <= y - 1 */
 (simplify
- (bit_ior:c (eq:s @1 min_value) (lt:s @0 @1))
+ (bit_ior:c (eq:s @1 min_value) (lt:cs @0 @1))
   (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
        && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
   (le @0 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); }))))
 
 /* y != XXX_MIN && x >= y --> x > y - 1 */
 (simplify
- (bit_and:c (ne:s @1 min_value) (ge:s @0 @1))
+ (bit_and:c (ne:s @1 min_value) (ge:cs @0 @1))
   (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
        && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
   (gt @0 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); }))))
--- gcc/testsuite/gcc.dg/tree-ssa/pr105983.c.jj 2022-06-15 16:41:56.214166604 
+0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr105983.c    2022-06-15 16:41:33.150470043 
+0200
@@ -0,0 +1,17 @@
+/* PR tree-optimization/105983 */
+/* { dg-do compile } */
+/* { dg-options "-O2 --param=logical-op-non-short-circuit=1 
-fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " != 0;" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " & " "optimized" } } */
+
+int
+foo (unsigned a, unsigned b)
+{
+  return b != 0 && a >= b;
+}
+
+int
+bar (unsigned a, unsigned b)
+{
+  return b != 0 & a >= b;
+}

        Jakub

Reply via email to