This is a follow-up to the -O1 patch for PR112533.

At -O2, GCC lowers (~a & 1) == (~b & 1) via inlining into:
  _14 = ~a;
  _12 = (bool) _14;
  _13 = ~b;
  _9  = (bool) _13;
  _8  = _9 == _12;

At -O2, the ne case of (bool)(~x) != (bool)(~y) is already handled
by CCP1 before forwprop runs.
However the eq case was missing from match.pd.

Add match.pd rule for the eq form:

  (bool)(~x) == (bool)(~y) -> (bool)(~(x ^ y))

The NOTs cancel on both sides, reducing the equality comparison
to XNOR.

Bootstrapped and regression tested on aarch64-linux-gnu with
RUNTESTFLAGS="tree-ssa.exp".

PR tree-optimization/112533

gcc/ChangeLog:
        * match.pd: Add eq case for (bool)(~x)==(bool)(~y),
        the ne case was already handled by CCP1.

gcc/testsuite/ChangeLog:
        * gcc.dg/tree-ssa/bool-eq-simplify-O2.c: New test.

Signed-off-by: Shivam Gupta <[email protected]>
---
 gcc/match.pd                                  |  8 +++++
 .../gcc.dg/tree-ssa/bool-eq-simplify-O2.c     | 30 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-eq-simplify-O2.c

diff --git a/gcc/match.pd b/gcc/match.pd
index ff13a07ea94..85a8d1cba50 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2033,6 +2033,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && element_precision (type) <= element_precision (TREE_TYPE (@1)))
   (bit_xor (convert @0) (convert @1))))
 
+/* (bool)(~X) == (bool)(~Y) -> (bool)(~(X ^ Y)).  */
+(simplify
+ (eq (convert (bit_not @0))
+     (convert (bit_not @1)))
+ (if (TREE_CODE (type) == BOOLEAN_TYPE
+      && types_match (@0, @1))
+ (convert (bit_not (bit_xor @0 @1)))))
+
 /* Convert ~X ^ C to X ^ ~C.  */
 (simplify
  (bit_xor (convert? (bit_not @0)) INTEGER_CST@1)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-eq-simplify-O2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/bool-eq-simplify-O2.c
new file mode 100644
index 00000000000..7e096828be8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-eq-simplify-O2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+/* Verify the fix for PR112533 at -O2:
+   (~a & 1) == (~b & 1) is lowered to (bool)(~a) == (bool)(~b)
+   which should be simplified to (bool)(~(a ^ b)).  */
+
+typedef unsigned int u32;
+
+/* Source-level form from the bug report.  */
+static _Bool
+is_even (u32 a)
+{
+  return a % 2 == 0;
+}
+
+_Bool
+same_evenness (u32 a, u32 b)
+{
+  return is_even (a) == is_even (b);
+}
+
+_Bool
+diff_evenness (u32 a, u32 b)
+{
+  return is_even (a) != is_even (b);
+}
+
+/* Verify the XOR form is produced.  */
+/* { dg-final { scan-tree-dump-times "\\\^" 2 "optimized" } } */
-- 
2.34.1

Reply via email to