Hi!

These simplifications are only simplifications if the (~D ^ C) or (D ^ C)
expressions fold into constants, but in that case they decrease number of
operations by 1.

For the first transformation I guess I should add reverse simplification
when C and D are arbitrary (constants would fold before;
to be tried incrementally).

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

2021-01-13  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/96691
        * match.pd ((~X | C) ^ D -> (X | C) ^ (~D ^ C),
        (~X & C) ^ D -> (X & C) ^ (D ^ C)): New simplifications for constant
        C and D.

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

--- gcc/match.pd.jj     2021-01-12 13:17:35.000000000 +0100
+++ gcc/match.pd        2021-01-12 21:39:51.310921835 +0100
@@ -947,6 +947,20 @@ (define_operator_list COND_TERNARY
  (bit_ior:c (bit_xor:c@3 @0 @1) (bit_xor:c (bit_xor:c @1 @2) @0))
  (bit_ior @3 @2))
 
+/* (~X | C) ^ D -> (X | C) ^ (~D ^ C) if C and D are constants.  */
+(simplify
+ (bit_xor (bit_ior:s (bit_not @0) @1) @2)
+  (if ((TREE_CODE (@1) == INTEGER_CST || TREE_CODE (@1) == VECTOR_CST)
+       && TREE_CODE (@1) == TREE_CODE (@2))
+   (bit_xor (bit_ior @0 @1) (bit_xor (bit_not @2) @1))))
+
+/* (~X & C) ^ D -> (X & C) ^ (D ^ C) if C and D are constants.  */
+(simplify
+ (bit_xor (bit_and:s (bit_not @0) @1) @2)
+  (if ((TREE_CODE (@1) == INTEGER_CST || TREE_CODE (@1) == VECTOR_CST)
+       && TREE_CODE (@1) == TREE_CODE (@2))
+   (bit_xor (bit_and @0 @1) (bit_xor @2 @1))))
+
 /* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0.  */
 #if GIMPLE
 (simplify
--- gcc/testsuite/gcc.dg/tree-ssa/pr96691.c.jj  2021-01-12 21:48:35.763025413 
+0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr96691.c     2021-01-12 21:48:19.579207370 
+0100
@@ -0,0 +1,21 @@
+/* PR tree-optimization/96691 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " \\\| 123;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\\& 123;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\\^ -315;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\\^ 314;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\\^ 321;" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " = ~" "optimized" } } */
+
+int
+foo (int x)
+{
+  return (~x | 123) ^ 321;
+}
+
+int
+bar (int x)
+{
+  return (~x & 123) ^ 321;
+}

        Jakub

Reply via email to