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" } 
> } */

Reply via email to