On Wed, Jan 13, 2021 at 08:35:01AM +0100, Richard Biener wrote: > I guess you could use > > (bit_xor (bit_ior @0 @1) (bit_xor! (bit_not! @2) @1))
I wasn't aware of !. I had to put it under #if GIMPLE because ! doesn't seem to be implemented for GENERIC, but otherwise it works fine. Though, shouldn't I add then :c on bit_xor and bit_ior/bit_and then? The rationale for not adding them before was that constants are canonicalized to go last, but if we simplify other things, they might not be last anymore... Ok for trunk if it passes another bootstrap/regtest? 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 if (~D ^ C) or (D ^ C) can be simplified. * gcc.dg/tree-ssa/pr96691.c: New test. --- gcc/match.pd.jj 2021-01-13 08:01:58.197627154 +0100 +++ gcc/match.pd 2021-01-13 10:25:32.327321918 +0100 @@ -947,8 +947,18 @@ (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)) -/* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0. */ #if GIMPLE +/* (~X | C) ^ D -> (X | C) ^ (~D ^ C) if (~D ^ C) can be simplified. */ +(simplify + (bit_xor (bit_ior:s (bit_not @0) @1) @2) + (bit_xor (bit_ior @0 @1) (bit_xor! (bit_not! @2) @1))) + +/* (~X & C) ^ D -> (X & C) ^ (D ^ C) if (D ^ C) can be simplified. */ +(simplify + (bit_xor (bit_and:s (bit_not @0) @1) @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. */ (simplify (bit_and (bit_not SSA_NAME@0) INTEGER_CST@1) (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) --- gcc/testsuite/gcc.dg/tree-ssa/pr96691.c.jj 2021-01-13 10:16:45.828331557 +0100 +++ gcc/testsuite/gcc.dg/tree-ssa/pr96691.c 2021-01-13 10:16:45.828331557 +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