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
> >
>

Reply via email to