On Wed, 13 Jan 2021, Jakub Jelinek wrote: > 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))))
I guess you could use (bit_xor (bit_ior @0 @1) (bit_xor! (bit_not! @2) @1)) and relax the constant test. Not sure in which circumstances (bit_xor (bit_not @2) @1) would simplify down to a singleton (within VN it might CSE for example). Maybe global1 = (~D) ^ C; global2 = (~X | C) ^ D; which VN should then simplify to global1 = (~D) ^ C; global2 = (X | C) ^ global1; of course such case may apply to many more patterns so not sure if we should start to use ! more aggressively now (it's relatively new). And yes, the reverse transform would be a simplification in general. Richard. > + > +/* (~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 > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)