Check for bitwise identity when encoding VECTOR_CSTs (PR 92768)

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.

2019-12-05  Richard Sandiford  <richard.sandiford@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.

From-SVN: r279002
This commit is contained in:
Richard Sandiford 2019-12-05 14:20:38 +00:00 committed by Richard Sandiford
parent 5a784d350c
commit 56b4b16eb1
6 changed files with 35 additions and 5 deletions

View file

@ -1,3 +1,10 @@
2019-12-05 Richard Sandiford <richard.sandiford@arm.com>
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.
2019-12-05 Richard Biener <rguenther@suse.de>
PR middle-end/92818

View file

@ -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_tree arg0, const_tree arg1,
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_tree arg0, const_tree arg1,
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_tree arg0, const_tree arg1,
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

View file

@ -1,3 +1,8 @@
2019-12-05 Richard Sandiford <richard.sandiford@arm.com>
PR middle-end/92768
* gcc.dg/pr92768.c: New test.
2019-12-05 Richard Biener <rguenther@suse.de>
PR middle-end/92818

View file

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

View file

@ -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.

View file

@ -88,7 +88,7 @@ tree_vector_builder::new_vector (tree type, unsigned int npatterns,
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