Check for bitwise identity when encoding VECTOR_CSTs (PR 92768)
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 5 Dec 2019 14:20:38 +0000 (14:20 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 5 Dec 2019 14:20:38 +0000 (14:20 +0000)
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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr92768.c [new file with mode: 0644]
gcc/tree-core.h
gcc/tree-vector-builder.h

index 4a894859761a7b58a8b146783bf21274dfd4aa49..83d66f1673ed691cc0bba65434a996b03886f476 100644 (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
index 84b3bb062174cac57ace9be3bf1951d347950672..c5bd45a6e34466fb4da365592f929aa6e1d9ea73 100644 (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
index 900e3bece8c3015cb0bd7bfcc152ce2263248825..b2c6d104c61be26ca8ed1867d254dda0c72ac271 100644 (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
diff --git a/gcc/testsuite/gcc.dg/pr92768.c b/gcc/testsuite/gcc.dg/pr92768.c
new file mode 100644 (file)
index 0000000..fa6a9cb
--- /dev/null
@@ -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" } } */
index f76f68d835d2539e20ed26537af0669f0e6eaa2f..631f3712b20036d85671bc2335f9e5e1c0dcfec0 100644 (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.
index 6a4cf6fbe01e1880c41fa3f756dd1deaf46d9487..add79e476adfe4b0782c3929cb39338d40425f73 100644 (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