This adds the simplification of:
  _1 = ~x_4(D);
  _2 = _1 & y_5(D);
  _3 = x_4(D) | y_5(D);
  _6 = _2 ^ _3;
  return _6;

to:
  return x_1(D);

also for ((~x) | y) ^ (x & y) version
  _1 = ~x_4(D);
  _2 = _1 | y_5(D);
  _3 = x_4(D) & y_5(D);
  _6 = _2 ^ _3;
  return _6;

to:
   int _2;
   _2 = ~x_1(D);
   return _2;

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

        PR tree-optimization/112095

gcc/ChangeLog:

        * match.pd: Simplify ((~x) & y) ^ (x | y)
        to x and ((~x) | y) ^ (x & y) to ~x.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Shivam Gupta <[email protected]>
---
 gcc/match.pd                             |  9 +++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr112095.c | 19 +++++++++++++++++++
 2 files changed, 28 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr112095.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 7b652afb43d..08df727ea9d 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2627,6 +2627,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (negate (nop_convert? (bit_not @0)))
  (plus (view_convert @0) { build_each_one_cst (type); }))
 
+/* ((~a) & b) ^ (a | b) -> a */
+/* ((~a) | b) ^ (a & b) -> ~a */
+(simplify
+ (bit_xor:c (bit_ior:c @0 @1) (bit_and:c @2 @1))
+ (with { bool wascmp; }
+  (if (bitwise_inverted_equal_p (@0, @2, wascmp)
+       && (!wascmp || element_precision (type) == 1))
+   @0)))
+
 /* (a & b) ^ (a == b) -> !(a | b) */
 /* (a & b) == (a ^ b) -> !(a | b) */
 (for first_op (bit_xor eq)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr112095.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr112095.c
new file mode 100644
index 00000000000..126705d7731
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr112095.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int
+f (int a, int b)
+{
+  return ((~a) & b) ^ (a | b);
+}
+
+int
+g (int a, int b)
+{
+  return ((~a) | b) ^ (a & b);
+}
+
+/* Above patterns should simplify to a and ~a respectively. */
+/* { dg-final { scan-tree-dump "return a_" "optimized" } } */
+/* { dg-final { scan-tree-dump "~a_" "optimized" } } */
+
-- 
2.34.1

Reply via email to