On Thu, Sep 19, 2024 at 2:18 PM Konstantinos Eleftheriou <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) cmp d || a != b --> 0 cmp d || a != b > (a ^ b) cmp c || a != b --> 0 cmp c || a != b
OK. Thanks, Richard. > 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. > > Tested-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 | 32 ++++++++++- > .../gcc.dg/tree-ssa/fold-xor-and-or.c | 55 +++++++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or.c | 55 +++++++++++++++++++ > 3 files changed, 141 insertions(+), 1 deletion(-) > 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 4aa610e2270..3c4f9b5f774 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -3761,6 +3761,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (if (types_match (type, TREE_TYPE (@0))) > (bit_xor @0 { build_one_cst (type); } )))))) > > +/* ((a ^ b) & c) cmp d || a != b --> (0 cmp d || a != b). */ > +(for cmp (simple_comparison) > + (simplify > + (bit_ior > + (cmp:c > + (bit_and:c > + (bit_xor:c @0 @1) > + tree_expr_nonzero_p@2) > + @3) > + (ne:c@4 @0 @1)) > + (bit_ior > + (cmp > + { build_zero_cst (TREE_TYPE (@0)); } > + @3) > + @4))) > + > +/* (a ^ b) cmp c || a != b --> (0 cmp c || a != b). */ > +(for cmp (simple_comparison) > + (simplify > + (bit_ior > + (cmp:c > + (bit_xor:c @0 @1) > + @2) > + (ne:c@3 @0 @1)) > + (bit_ior > + (cmp > + { build_zero_cst (TREE_TYPE (@0)); } > + @2) > + @3))) > + > /* We can't reassociate at all for saturating types. */ > (if (!TYPE_SATURATING (type)) > > @@ -10763,4 +10793,4 @@ and, > } > } > (if (full_perm_p) > - (vec_perm (op@3 @0 @1) @3 @2)))))) > + (vec_perm (op@3 @0 @1) @3 @2)))))) Spurious whitespace change? > \ 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..e5dc98e7541 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-and-or.c > @@ -0,0 +1,55 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -fdump-tree-optimized" } */ > + > +typedef unsigned long int uint64_t; > + > +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; > +} > + > +int cmp3(int d1, int d2) { > + if (10 > (0xabcd & (d2 ^ d1)) || d2 != d1) > + return 0; > + return 1; > +} > + > +int cmp4(int d1, int d2) { > + if (d2 != d1 || 10 > (0xabcd & (d2 ^ d1))) > + return 0; > + return 1; > +} > + > +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; > +} > + > +int cmp3_64(uint64_t d1, uint64_t d2) { > + if (10 > (0xabcd & (d2 ^ d1)) || d2 != d1) > + return 0; > + return 1; > +} > + > +int cmp4_64(uint64_t d1, uint64_t d2) { > + if (d2 != d1 || 10 > (0xabcd & (d2 ^ d1))) > + 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..c55cfbcc84c > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/fold-xor-or.c > @@ -0,0 +1,55 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -fdump-tree-optimized" } */ > + > +typedef unsigned long int uint64_t; > + > +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; > +} > + > +int cmp3(int d1, int d2) { > + if (0xabcd > (d2 ^ d1) || d2 != d1) > + return 0; > + return 1; > +} > + > +int cmp4(int d1, int d2) { > + if (d2 != d1 || 0xabcd > (d2 ^ d1)) > + return 0; > + return 1; > +} > + > +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; > +} > + > +int cmp3_64(uint64_t d1, uint64_t d2) { > + if (0xabcd > (d2 ^ d1) || d2 != d1) > + return 0; > + return 1; > +} > + > +int cmp4_64(uint64_t d1, uint64_t d2) { > + if (d2 != d1 || 0xabcd > (d2 ^ d1)) > + 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 >