Thanks for the feedback. Indeed, the first pattern should apply to non-constants too and some comments were misleading.
I have sent a new version ( https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661754.html). On Thu, Aug 22, 2024 at 3:56 PM Richard Biener <richard.guent...@gmail.com> wrote: > On Fri, Aug 16, 2024 at 4:24 PM Konstantinos Eleftheriou > <konstantinos.elefther...@vrull.eu> wrote: > > > > From: kelefth <konstantinos.elefther...@vrull.eu> > > > > In expressions like (a != b || ((a ^ b) & CST0) == CST1) and > > (a != b || (a ^ b) == CST), (a ^ b) is folded to false. > > In the equivalent expressions (((a ^ b) & CST0) == CST1 || a != b) and > > ((a ^ b) == CST, (a ^ b) || a != b) this is not happening. > > > > This patch adds the following simplifications in match.pd: > > ((a ^ b) & CST0) == CST1 || a != b --> 0 == (CST1 || a != b) > > (a ^ b) == CST || a != b --> 0 == CST || (a != b) > > > > PR tree-optimization/114326 > > > > gcc/ChangeLog: > > > > * match.pd: Add two patterns to fold a ^ b to 0, when a == b. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.dg/tree-ssa/fold-xor-and-or-1.c: New test. > > * gcc.dg/tree-ssa/fold-xor-and-or-2.c: New test. > > * gcc.dg/tree-ssa/fold-xor-or-1.c: New test. > > * gcc.dg/tree-ssa/fold-xor-or-2.c: New test. > > > > Reviewed-by: Christoph Müllner <christoph.muell...@vrull.eu> > > Signed-off-by: Philipp Tomsich <philipp.toms...@vrull.eu> > > Signed-off-by: Konstantinos Eleftheriou < > konstantinos.elefther...@vrull.eu> > > --- > > gcc/match.pd | 30 +++++++++++++++++++ > > .../gcc.dg/tree-ssa/fold-xor-and-or-1.c | 17 +++++++++++ > > .../gcc.dg/tree-ssa/fold-xor-and-or-2.c | 19 ++++++++++++ > > gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-1.c | 17 +++++++++++ > > gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-2.c | 19 ++++++++++++ > > 5 files changed, 102 insertions(+) > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-1.c > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-1.c > > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-2.c > > > > diff --git a/gcc/match.pd b/gcc/match.pd > > index c9c8478d286..1c55bd72f09 100644 > > --- a/gcc/match.pd > > +++ b/gcc/match.pd > > @@ -10680,3 +10680,33 @@ and, > > } > > (if (full_perm_p) > > (vec_perm (op@3 @0 @1) @3 @2)))))) > > + > > +/* ((a ^ b) & CST0) == CST1 || a != b --> 0 == (CST1 || a != b). */ > > So for CST0 == 0 we don't know nothing - you do not verify > this but this might be a reason to force CST0 to be a constant > (CST1 need not be?). CST0 could be a non-constant as well > if you use tree_expr_nonzero_p on it, right? > > > +(for cmp (simple_comparison) > > + (simplify > > + (bit_ior > > + (cmp > > + (bit_and > > + (bit_xor @0 @1) > > + INTEGER_CST) > > + @3) > > + (ne@4 @0 @1)) > > + (bit_ior > > + (cmp > > + { build_zero_cst (TREE_TYPE (@0)); } > > + @3) > > + @4))) > > + > > +/* (a ^ b) == CST || a != b --> 0 == CST || (a != b). */ > > +(for cmp (simple_comparison) > > + (simplify > > + (bit_ior > > + (cmp > > + (bit_xor @0 @1) > > + @2) > > Should this be INTEGER_CST@2? I don't see the comments why CSTs should > be constant and not arbitrary other values? > > > + (ne@3 @0 @1)) > > + (bit_ior > > + (cmp > > + {build_zero_cst (TREE_TYPE (@0)); } > > + @2) > > if @2 is INTEGER_CST you could also statically decide whether it's zero. > > I do wonder why we don't (don't we?) simplify (a ^ b) == 0 to a == b? > Likewise for (a ^ b) != 0. > > But as said, mentioning 'CST' is probably misleading? > > > + @3))) > > \ No newline at end of file > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-1.c > b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-1.c > > new file mode 100644 > > index 00000000000..0e6fc1d5515 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-1.c > > @@ -0,0 +1,17 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O3 -fdump-tree-optimized" } */ > > + > > +int cmp1(int d1, int d2) { > > + if (((d1 ^ d2) & 0xabcd) == 0 || d1 != d2) > > + return 0; > > + return 1; > > +} > > + > > +int cmp2(int d1, int d2) { > > + if (d1 != d2 || ((d1 ^ d2) & 0xabcd) == 0) > > + return 0; > > + return 1; > > +} > > + > > +/* The if should be removed, so the condition should not exist */ > > +/* { dg-final { scan-tree-dump-not "d1_\[0-9\]+.D. \\^ d2_\[0-9\]+.D." > "optimized" } } */ > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c > b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c > > new file mode 100644 > > index 00000000000..3f8da111354 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or-2.c > > @@ -0,0 +1,19 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O3 -fdump-tree-optimized" } */ > > + > > +typedef unsigned long int uint64_t; > > + > > +int cmp1(uint64_t d1, uint64_t d2) { > > + if (((d1 ^ d2) & 0xabcd) == 0 || d1 != d2) > > + return 0; > > + return 1; > > +} > > + > > +int cmp2(uint64_t d1, uint64_t d2) { > > + if (d1 != d2 || ((d1 ^ d2) & 0xabcd) == 0) > > + return 0; > > + return 1; > > +} > > + > > +/* The if should be removed, so the condition should not exist */ > > +/* { dg-final { scan-tree-dump-not "d1_\[0-9\]+.D. \\^ d2_\[0-9\]+.D." > "optimized" } } */ > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-1.c > b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-1.c > > new file mode 100644 > > index 00000000000..0bc849a2d74 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-1.c > > @@ -0,0 +1,17 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O3 -fdump-tree-optimized" } */ > > + > > +int cmp1(int d1, int d2) { > > + if ((d1 ^ d2) == 0xabcd || d1 != d2) > > + return 0; > > + return 1; > > +} > > + > > +int cmp2(int d1, int d2) { > > + if (d1 != d2 || (d1 ^ d2) == 0xabcd) > > + return 0; > > + return 1; > > +} > > + > > +/* The if should be removed, so the condition should not exist */ > > +/* { dg-final { scan-tree-dump-not "d1_\[0-9\]+.D. \\^ d2_\[0-9\]+.D." > "optimized" } } */ > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-2.c > b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-2.c > > new file mode 100644 > > index 00000000000..2276fc1c2ba > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or-2.c > > @@ -0,0 +1,19 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O3 -fdump-tree-optimized" } */ > > + > > +typedef unsigned long int uint64_t; > > + > > +int cmp1(uint64_t d1, uint64_t d2) { > > + if ((d1 ^ d2) == 0xabcd || d1 != d2) > > + return 0; > > + return 1; > > +} > > + > > +int cmp2(uint64_t d1, uint64_t d2) { > > + if (d1 != d2 || (d1 ^ d2) == 0xabcd) > > + return 0; > > + return 1; > > +} > > + > > +/* The if should be removed, so the condition should not exist */ > > +/* { dg-final { scan-tree-dump-not "d1_\[0-9\]+.D. \\^ d2_\[0-9\]+.D." > "optimized" } } */ > > -- > > 2.46.0 > > >