On Thu, Dec 5, 2019 at 11:26 AM Richard Sandiford <richard.sandif...@arm.com> wrote: > > This PR shows that we weren't checking for bitwise-identical values > when trying to encode a VECTOR_CST, so -0.0 was treated the same as > 0.0 for -fno-signed-zeros. The patch adds a new OEP flag to select > that behaviour. > > Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install?
OK. Thanks, Richard. > Richard > > > 2019-12-05 Richard Sandiford <richard.sandif...@arm.com> > > gcc/ > PR middle-end/92768 > * tree-core.h (OEP_BITWISE): New flag. > * fold-const.c (operand_compare::operand_equal_p): Handle it. > * tree-vector-builder.h (tree_vector_builder::equal_p): Pass it. > > gcc/testsuite/ > PR middle-end/92768 > * gcc.dg/pr92768.c: New test. > > Index: gcc/tree-core.h > =================================================================== > --- gcc/tree-core.h 2019-11-29 13:04:14.458669072 +0000 > +++ gcc/tree-core.h 2019-12-05 10:25:10.660172853 +0000 > @@ -881,7 +881,8 @@ enum operand_equal_flag { > /* Internal within inchash::add_expr: */ > OEP_HASH_CHECK = 32, > /* Makes operand_equal_p handle more expressions: */ > - OEP_LEXICOGRAPHIC = 64 > + OEP_LEXICOGRAPHIC = 64, > + OEP_BITWISE = 128 > }; > > /* Enum and arrays used for tree allocation stats. > Index: gcc/fold-const.c > =================================================================== > --- gcc/fold-const.c 2019-12-04 13:14:12.222218581 +0000 > +++ gcc/fold-const.c 2019-12-05 10:25:10.656172882 +0000 > @@ -2938,6 +2938,11 @@ combine_comparisons (location_t loc, > If OEP_LEXICOGRAPHIC is set, then also handle expressions with > side-effects > such as MODIFY_EXPR, RETURN_EXPR, as well as STATEMENT_LISTs. > > + If OEP_BITWISE is set, then require the values to be bitwise identical > + rather than simply numerically equal. Do not take advantage of things > + like math-related flags or undefined behavior; only return true for > + values that are provably bitwise identical in all circumstances. > + > Unless OEP_MATCH_SIDE_EFFECTS is set, the function returns false on > any operand with side effect. This is unnecesarily conservative in the > case we know that arg0 and arg1 are in disjoint code paths (such as in > @@ -2967,6 +2972,11 @@ operand_compare::operand_equal_p (const_ > if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1)) > return false; > > + /* Bitwise identity makes no sense if the values have different layouts. > */ > + if ((flags & OEP_BITWISE) > + && !tree_nop_conversion_p (TREE_TYPE (arg0), TREE_TYPE (arg1))) > + return false; > + > /* We cannot consider pointers to different address space equal. */ > if (POINTER_TYPE_P (TREE_TYPE (arg0)) > && POINTER_TYPE_P (TREE_TYPE (arg1)) > @@ -3099,8 +3109,7 @@ operand_compare::operand_equal_p (const_ > if (real_identical (&TREE_REAL_CST (arg0), &TREE_REAL_CST (arg1))) > return true; > > - > - if (!HONOR_SIGNED_ZEROS (arg0)) > + if (!(flags & OEP_BITWISE) && !HONOR_SIGNED_ZEROS (arg0)) > { > /* If we do not distinguish between signed and unsigned zero, > consider them equal. */ > @@ -3152,7 +3161,9 @@ operand_compare::operand_equal_p (const_ > break; > } > > - if (flags & OEP_ONLY_CONST) > + /* Don't handle more cases for OEP_BITWISE, since we can't guarantee that > + two instances of undefined behavior will give identical results. */ > + if (flags & (OEP_ONLY_CONST | OEP_BITWISE)) > return false; > > /* Define macros to test an operand from arg0 and arg1 for equality and a > Index: gcc/tree-vector-builder.h > =================================================================== > --- gcc/tree-vector-builder.h 2019-07-29 09:40:10.142001362 +0100 > +++ gcc/tree-vector-builder.h 2019-12-05 10:25:10.660172853 +0000 > @@ -88,7 +88,7 @@ tree_vector_builder::new_vector (tree ty > inline bool > tree_vector_builder::equal_p (const_tree elt1, const_tree elt2) const > { > - return operand_equal_p (elt1, elt2, 0); > + return operand_equal_p (elt1, elt2, OEP_BITWISE); > } > > /* Return true if a stepped representation is OK. We don't allow > Index: gcc/testsuite/gcc.dg/pr92768.c > =================================================================== > --- /dev/null 2019-09-17 11:41:18.176664108 +0100 > +++ gcc/testsuite/gcc.dg/pr92768.c 2019-12-05 10:25:10.660172853 +0000 > @@ -0,0 +1,6 @@ > +/* { dg-options "-O2 -fno-signed-zeros -fdump-tree-optimized" } */ > + > +typedef float v4sf __attribute__((vector_size(16))); > +v4sf f () { return (v4sf) { 0.0, -0.0, 0.0, -0.0 }; } > + > +/* { dg-final { scan-tree-dump {{ 0\.0, -0\.0, 0\.0, -0\.0 }} "optimized" } > } */