On Fri, Jun 9, 2023 at 3:48 AM Andrew Pinski via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > So for the attached testcase, we assumed that zero_one_valued_p would > be the value [0,1] but currently zero_one_valued_p matches also > signed 1 bit integers. > This changes that not to match that and fixes the 2 new testcases at > all optimization levels. > > OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
OK. > Note the GCC 13 patch will be slightly different due to the changes > made to zero_one_valued_p. > > PR tree-optimization/110165 > PR tree-optimization/110166 > > gcc/ChangeLog: > > * match.pd (zero_one_valued_p): Don't accept > signed 1-bit integers. > > gcc/testsuite/ChangeLog: > > * gcc.c-torture/execute/pr110165-1.c: New test. > * gcc.c-torture/execute/pr110166-1.c: New test. > --- > gcc/match.pd | 13 ++++++-- > .../gcc.c-torture/execute/pr110165-1.c | 28 ++++++++++++++++ > .../gcc.c-torture/execute/pr110166-1.c | 33 +++++++++++++++++++ > 3 files changed, 71 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr110165-1.c > create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr110166-1.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 4ad037d641a..9a6bc2e9348 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -1984,12 +1984,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > @0) > > /* zero_one_valued_p will match when a value is known to be either > - 0 or 1 including constants 0 or 1. */ > + 0 or 1 including constants 0 or 1. > + Signed 1-bits includes -1 so they cannot match here. */ > (match zero_one_valued_p > @0 > - (if (INTEGRAL_TYPE_P (type) && wi::leu_p (tree_nonzero_bits (@0), 1)))) > + (if (INTEGRAL_TYPE_P (type) > + && (TYPE_UNSIGNED (type) > + || TYPE_PRECISION (type) > 1) > + && wi::leu_p (tree_nonzero_bits (@0), 1)))) > (match zero_one_valued_p > - truth_valued_p@0) > + truth_valued_p@0 > + (if (INTEGRAL_TYPE_P (type) > + && (TYPE_UNSIGNED (type) > + || TYPE_PRECISION (type) > 1)))) > > /* Transform { 0 or 1 } * { 0 or 1 } into { 0 or 1 } & { 0 or 1 }. */ > (simplify > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110165-1.c > b/gcc/testsuite/gcc.c-torture/execute/pr110165-1.c > new file mode 100644 > index 00000000000..9521a19428e > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/execute/pr110165-1.c > @@ -0,0 +1,28 @@ > +struct s > +{ > + int t : 1; > +}; > + > +int f(struct s t, int a, int b) __attribute__((noinline)); > +int f(struct s t, int a, int b) > +{ > + int bd = t.t; > + if (bd) a|=b; > + return a; > +} > + > +int main(void) > +{ > + struct s t; > + for(int i = -1;i <= 1; i++) > + { > + int a = 0x10; > + int b = 0x0f; > + int c = a | b; > + struct s t = {i}; > + int r = f(t, a, b); > + int exp = (i != 0) ? a | b : a; > + if (exp != r) > + __builtin_abort(); > + } > +} > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr110166-1.c > b/gcc/testsuite/gcc.c-torture/execute/pr110166-1.c > new file mode 100644 > index 00000000000..f999d47fe69 > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/execute/pr110166-1.c > @@ -0,0 +1,33 @@ > +struct s > +{ > + int t : 1; > + int t1 : 1; > +}; > + > +int f(struct s t) __attribute__((noinline)); > +int f(struct s t) > +{ > + int c = t.t; > + int d = t.t1; > + if (c > d) > + t.t = d; > + else > + t.t = c; > + return t.t; > +} > + > +int main(void) > +{ > + struct s t; > + for(int i = -1;i <= 0; i++) > + { > + for(int j = -1;j <= 0; j++) > + { > + struct s t = {i, j}; > + int r = f(t); > + int exp = i < j ? i : j; > + if (exp != r) > + __builtin_abort(); > + } > + } > +} > -- > 2.31.1 >