On Sun, Oct 10, 2021 at 11:41 PM Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On Mon, Oct 11, 2021 at 1:20 AM apinski--- via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: > > > > From: Andrew Pinski <apin...@marvell.com> > > > > So here is the GCC 10 branch version which fixes the wrong code. > > The problem is we create a negation of an one bit signed integer type > > which is undefined if the value was -1. > > This is not needed for GCC 11 branch since the case is handled differently > > there and has been fixed there (and the trunk has now been fixed too). > > So for one bit types, there is no reason to create the negation so just > > setting neg to false for them, just works. > > > > OK? Bootstrapped and tested on x86_64-linux-gnu. > > OK.
Applied to both the 10 branch and 9 branch. Thanks, Andrew > > Thanks, > Richard. > > > PR tree-optimization/102622 > > > > gcc/ChangeLog: > > > > * tree-ssa-phiopt.c (conditional_replacement): Set neg > > to false for one bit signed types. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.c-torture/execute/bitfld-10.c: New test. > > --- > > gcc/testsuite/gcc.c-torture/execute/bitfld-10.c | 24 > > ++++++++++++++++++++++++ > > gcc/tree-ssa-phiopt.c | 5 ++++- > > 2 files changed, 28 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/gcc.c-torture/execute/bitfld-10.c > > > > diff --git a/gcc/testsuite/gcc.c-torture/execute/bitfld-10.c > > b/gcc/testsuite/gcc.c-torture/execute/bitfld-10.c > > new file mode 100644 > > index 0000000..bdbf573 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.c-torture/execute/bitfld-10.c > > @@ -0,0 +1,24 @@ > > +/* PR tree-optimization/102622 */ > > +/* Wrong code introduced due to phi-opt > > + introducing undefined signed interger overflow > > + with one bit signed integer negation. */ > > + > > +struct f{signed t:1;}; > > +int g(struct f *a, int t) __attribute__((noipa)); > > +int g(struct f *a, int t) > > +{ > > + if (t) > > + a->t = -1; > > + else > > + a->t = 0; > > + int t1 = a->t; > > + if (t1) return 1; > > + return t1; > > +} > > + > > +int main(void) > > +{ > > + struct f a; > > + if (!g(&a, 1)) __builtin_abort(); > > + return 0; > > +} > > diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c > > index 9ed26a3..a6c197d 100644 > > --- a/gcc/tree-ssa-phiopt.c > > +++ b/gcc/tree-ssa-phiopt.c > > @@ -770,9 +770,12 @@ conditional_replacement (basic_block cond_bb, > > basic_block middle_bb, > > if ((integer_zerop (arg0) && integer_onep (arg1)) > > || (integer_zerop (arg1) && integer_onep (arg0))) > > neg = false; > > + /* For signed one bit types, the negation is not needed and > > + should be avoided and is the same as 1 case for non-signed > > + one bit types. */ > > else if ((integer_zerop (arg0) && integer_all_onesp (arg1)) > > || (integer_zerop (arg1) && integer_all_onesp (arg0))) > > - neg = true; > > + neg = TYPE_PRECISION (TREE_TYPE (arg0)) != 1; > > else > > return false; > > > > -- > > 1.8.3.1 > >