I have sent a new version
(https://gcc.gnu.org/pipermail/gcc-patches/2024-September/663350.html).
I also added :c to the ne operations.

Thanks,
Konstantinos

On Wed, Sep 18, 2024 at 1:52 PM Richard Biener
<richard.guent...@gmail.com> wrote:
>
> On Wed, Sep 18, 2024 at 10:42 AM Konstantinos Eleftheriou
> <konstantinos.elefther...@vrull.eu> wrote:
> >
> > On Mon, Sep 9, 2024 at 3:11 PM Richard Biener
> > <richard.guent...@gmail.com> wrote:
> > >
> > > On Thu, Aug 29, 2024 at 9:03 AM <konstantinos.elefther...@vrull.eu> wrote:
> > > >
> > > > From: kelefth <konstantinos.elefther...@vrull.eu>
> > > >
> > > > In expressions like (a != b || ((a ^ b) & c) == d) and
> > > > (a != b || (a ^ b) == c), (a ^ b) is folded to false.
> > > > In the equivalent expressions (((a ^ b) & c) == d || a != b) and
> > > > ((a ^ b) == c || a != b) this is not happening.
> > > >
> > > > This patch adds the following simplifications in match.pd:
> > > > ((a ^ b) & c) == d || a != b --> 0 == d || a != b
> > > > (a ^ b) == c || a != b --> 0 == c || 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.c: New test.
> > > >         * gcc.dg/tree-ssa/fold-xor-or.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.c         | 31 +++++++++++++++++++
> > > >  gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or.c   | 31 +++++++++++++++++++
> > > >  3 files changed, 92 insertions(+)
> > > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or.c
> > > >
> > > > diff --git a/gcc/match.pd b/gcc/match.pd
> > > > index be211535a49..6bab3cfbde1 100644
> > > > --- a/gcc/match.pd
> > > > +++ b/gcc/match.pd
> > > > @@ -10727,3 +10727,33 @@ and,
> > > >        }
> > > >        (if (full_perm_p)
> > > >         (vec_perm (op@3 @0 @1) @3 @2))))))
> > >
> > >> Can you please place those patterns next to related ones?  I suggest
> > >> after (type)([0,1]@a != 0) -> (type)a and before
> > >> /* We can't reassociate at all for saturating types.  */
> >
> > Yes, I will fix that.
> > >
> > >
> > > > +/* ((a ^ b) & c) == d || a != b --> (0 == d || a != b). */
> > >
> > >> The comment indicates == d but you also test for other
> > >> comparison ops.  As far as I can see your testcases also
> > >> only cover ==.
> >
> > I will change "=="  to "cmp" in the comments and add additional testcases.
> > My intention is to cover all operations included in "simple_comparison".
> > >
> > >
> > > > +(for cmp (simple_comparison)
> > > > +  (simplify
> > > > +    (bit_ior
> > > > +      (cmp
> > > > +       (bit_and
> > >
> > > This needs :c
> > >
> > > > +         (bit_xor @0 @1)
> > >
> > > Likewise.
> >
> > Right, I will fix these cases.
> > >
> > >
> > >> I think you also need :c on the comparison to match
> > >> d == (...).
> >
> > In that case, I would need to handle non-commutative operations (e.g.
> > >) separately, right?
>
> The non-commutative operations can be handled as well, the tree code
> will be inverted accordingly.
>
> Richard.
>
> > >
> > >
> > > > +         tree_expr_nonzero_p@2)
> > > > +       @3)
> > > > +      (ne@4 @0 @1))
> > > > +    (bit_ior
> > > > +      (cmp
> > > > +       { build_zero_cst (TREE_TYPE (@0)); }
> > > > +       @3)
> > > > +      @4)))
> > > > +
> > > > +/* (a ^ b) == c || a != b --> (0 == c || a != b). */
> > > > +(for cmp (simple_comparison)
> > > > +  (simplify
> > > > +    (bit_ior
> > > > +      (cmp
> > > > +       (bit_xor @0 @1)
> > >
> > > similar, :c here and also on the comparison.  Same
> > > question with regard to == c.
> > >
> > > > +       @2)
> > > > +      (ne@3 @0 @1))
> > > > +    (bit_ior
> > > > +      (cmp
> > > > +       { build_zero_cst (TREE_TYPE (@0)); }
> > > > +       @2)
> > > > +      @3)))
> > > > \ No newline at end of file
> > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c 
> > > > b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c
> > > > new file mode 100644
> > > > index 00000000000..ec327e62f6e
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c
> > > > @@ -0,0 +1,31 @@
> > > > +/* { 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;
> > > > +}
> > > > +
> > > > +typedef unsigned long int uint64_t;
> > > > +
> > > > +int cmp1_64(uint64_t d1, uint64_t d2) {
> > > > +  if (((d1 ^ d2) & 0xabcd) == 0 || d1 != d2)
> > > > +    return 0;
> > > > +  return 1;
> > > > +}
> > > > +
> > > > +int cmp2_64(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.c 
> > > > b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or.c
> > > > new file mode 100644
> > > > index 00000000000..f5fce847394
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or.c
> > > > @@ -0,0 +1,31 @@
> > > > +/* { 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;
> > > > +}
> > > > +
> > > > +typedef unsigned long int uint64_t;
> > > > +
> > > > +int cmp1_64(uint64_t d1, uint64_t d2) {
> > > > +  if ((d1 ^ d2) == 0xabcd || d1 != d2)
> > > > +    return 0;
> > > > +  return 1;
> > > > +}
> > > > +
> > > > +int cmp2_64(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
> > > >
> >
> > Thanks for the feedback,
> > Konstantinos

Reply via email to