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