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:
parent
5a784d350c
commit
56b4b16eb1
6 changed files with 35 additions and 5 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
6
gcc/testsuite/gcc.dg/pr92768.c
Normal file
6
gcc/testsuite/gcc.dg/pr92768.c
Normal 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" } } */
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue