On Sat, Sep 16, 2023 at 6:00 PM Andrew Pinski via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > `(a == CST) & a` can be either simplified to simplying `a == CST` > or 0 depending on the first bit of the CST. > This is an extension of the already pattern of `X & !X` and allows > us to remove the 2 xfails on gcc.dg/binop-notand1a.c and > gcc.dg/binop-notand4a.c. > > OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
OK. > PR tree-optimization/111431 > > gcc/ChangeLog: > > * match.pd (`(a == CST) & a`): New pattern. > > gcc/testsuite/ChangeLog: > > * gcc.dg/binop-notand1a.c: Remove xfail. > * gcc.dg/binop-notand4a.c: Likewise. > * gcc.c-torture/execute/pr111431-1.c: New test. > * gcc.dg/binop-andeq1.c: New test. > * gcc.dg/binop-andeq2.c: New test. > * gcc.dg/binop-notand7.c: New test. > * gcc.dg/binop-notand7a.c: New test. > --- > gcc/match.pd | 8 ++++ > .../gcc.c-torture/execute/pr111431-1.c | 39 +++++++++++++++++++ > gcc/testsuite/gcc.dg/binop-andeq1.c | 12 ++++++ > gcc/testsuite/gcc.dg/binop-andeq2.c | 14 +++++++ > gcc/testsuite/gcc.dg/binop-notand1a.c | 4 +- > gcc/testsuite/gcc.dg/binop-notand4a.c | 4 +- > gcc/testsuite/gcc.dg/binop-notand7.c | 12 ++++++ > gcc/testsuite/gcc.dg/binop-notand7a.c | 12 ++++++ > 8 files changed, 99 insertions(+), 6 deletions(-) > create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr111431-1.c > create mode 100644 gcc/testsuite/gcc.dg/binop-andeq1.c > create mode 100644 gcc/testsuite/gcc.dg/binop-andeq2.c > create mode 100644 gcc/testsuite/gcc.dg/binop-notand7.c > create mode 100644 gcc/testsuite/gcc.dg/binop-notand7a.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index ebb50ee0581..65960a1701e 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -5172,6 +5172,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > ) > ) > > +/* `(a == CST) & a` can be simplified to `0` or `(a == CST)` depending > + on the first bit of the CST. */ > +(simplify > + (bit_and:c (convert@2 (eq @0 INTEGER_CST@1)) (convert? @0)) > + (if ((wi::to_wide (@1) & 1) != 0) > + @2 > + { build_zero_cst (type); })) > + > /* Optimize > # x_5 in range [cst1, cst2] where cst2 = cst1 + 1 > x_5 ? cstN ? cst4 : cst3 > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111431-1.c > b/gcc/testsuite/gcc.c-torture/execute/pr111431-1.c > new file mode 100644 > index 00000000000..a96dbadf2b5 > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/execute/pr111431-1.c > @@ -0,0 +1,39 @@ > +int > +foo (int a) > +{ > + int b = a == 0; > + return (a & b); > +} > + > +#define function(vol,cst) \ > +__attribute__((noipa)) \ > +_Bool func_##cst##_##vol(vol int a) \ > +{ \ > + vol int b = a == cst; \ > + return (a & b); \ > +} > + > +#define funcdefs(cst) \ > +function(,cst) \ > +function(volatile,cst) > + > +#define funcs(f) \ > +f(0) \ > +f(1) \ > +f(5) > + > +funcs(funcdefs) > + > +#define test(cst) \ > +do { \ > + if(func_##cst##_(a) != func_##cst##_volatile(a))\ > + __builtin_abort(); \ > +} while(0); > +int main(void) > +{ > + for(int a = -10; a <= 10; a++) > + { > + funcs(test) > + } > +} > + > diff --git a/gcc/testsuite/gcc.dg/binop-andeq1.c > b/gcc/testsuite/gcc.dg/binop-andeq1.c > new file mode 100644 > index 00000000000..2a92b8f95df > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/binop-andeq1.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* PR tree-optimization/111431 */ > + > +int > +foo (int a) > +{ > + int b = a == 2; > + return (a & b); > +} > + > +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ > diff --git a/gcc/testsuite/gcc.dg/binop-andeq2.c > b/gcc/testsuite/gcc.dg/binop-andeq2.c > new file mode 100644 > index 00000000000..895262fc17e > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/binop-andeq2.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* PR tree-optimization/111431 */ > + > +int > +foo (int a) > +{ > + int b = a == 1025; > + return (a & b); > +} > + > +/* { dg-final { scan-tree-dump-not "return 0" "optimized" } } */ > +/* { dg-final { scan-tree-dump-not " & " "optimized" } } */ > +/* { dg-final { scan-tree-dump-times " == 1025;" 1 "optimized" } } */ > diff --git a/gcc/testsuite/gcc.dg/binop-notand1a.c > b/gcc/testsuite/gcc.dg/binop-notand1a.c > index c7e932b2638..d94685eb4ce 100644 > --- a/gcc/testsuite/gcc.dg/binop-notand1a.c > +++ b/gcc/testsuite/gcc.dg/binop-notand1a.c > @@ -7,6 +7,4 @@ foo (char a, unsigned short b) > return (a & !a) | (b & !b); > } > > -/* As long as comparisons aren't boolified and casts from boolean-types > - aren't preserved, the folding of X & !X to zero fails. */ > -/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" { xfail *-*-* > } } } */ > +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ > diff --git a/gcc/testsuite/gcc.dg/binop-notand4a.c > b/gcc/testsuite/gcc.dg/binop-notand4a.c > index dce6a5c7eb5..bd9c7cce638 100644 > --- a/gcc/testsuite/gcc.dg/binop-notand4a.c > +++ b/gcc/testsuite/gcc.dg/binop-notand4a.c > @@ -7,6 +7,4 @@ foo (unsigned char a, _Bool b) > return (!a & a) | (b & !b); > } > > -/* As long as comparisons aren't boolified and casts from boolean-types > - aren't preserved, the folding of X & !X to zero fails. */ > -/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" { xfail *-*-* > } } } */ > +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ > diff --git a/gcc/testsuite/gcc.dg/binop-notand7.c > b/gcc/testsuite/gcc.dg/binop-notand7.c > new file mode 100644 > index 00000000000..c2bb6a0449d > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/binop-notand7.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* PR tree-optimization/111431 */ > + > +int > +foo (int a) > +{ > + int b = !a; > + return (a & b); > +} > + > +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ > diff --git a/gcc/testsuite/gcc.dg/binop-notand7a.c > b/gcc/testsuite/gcc.dg/binop-notand7a.c > new file mode 100644 > index 00000000000..dd50916da61 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/binop-notand7a.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* PR tree-optimization/111431 */ > + > +unsigned > +foo (int a) > +{ > + int b = !a; > + return (a & b); > +} > + > +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */ > -- > 2.31.1 >