]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Ensure float equivalences include + and - zero.
authorAndrew MacLeod <amacleod@redhat.com>
Mon, 9 Oct 2023 17:40:15 +0000 (13:40 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Wed, 11 Oct 2023 19:51:43 +0000 (15:51 -0400)
A floating point equivalence may not properly reflect both signs of
zero, so be pessimsitic and ensure both signs are included.

PR tree-optimization/111694
gcc/
* gimple-range-cache.cc (ranger_cache::fill_block_cache): Adjust
equivalence range.
* value-relation.cc (adjust_equivalence_range): New.
* value-relation.h (adjust_equivalence_range): New prototype.

gcc/testsuite/
* gcc.dg/pr111694.c: New.

gcc/gimple-range-cache.cc
gcc/testsuite/gcc.dg/pr111694.c [new file with mode: 0644]
gcc/value-relation.cc
gcc/value-relation.h

index 2314478d55849d7ae973a4bc65e26edfe565ac28..e4e75943632820af975069db9a8014f51a0577f3 100644 (file)
@@ -1258,6 +1258,9 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
                {
                  if (rel != VREL_EQ)
                    range_cast (equiv_range, type);
+                 else
+                   adjust_equivalence_range (equiv_range);
+
                  if (block_result.intersect (equiv_range))
                    {
                      if (DEBUG_RANGE_CACHE)
diff --git a/gcc/testsuite/gcc.dg/pr111694.c b/gcc/testsuite/gcc.dg/pr111694.c
new file mode 100644 (file)
index 0000000..a70b030
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR tree-optimization/111009 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#define signbit(x) __builtin_signbit(x)
+
+static void test(double l, double r)
+{
+  if (l == r && (signbit(l) || signbit(r)))
+    ;
+  else
+    __builtin_abort();
+}
+
+int main()
+{
+  test(0.0, -0.0);
+}
+
index 30a02d3c9d36c84e1010682dc7b550aa5123dd6c..fc792a4d5bc2a1908f88973fceffb62afecbbd9d 100644 (file)
@@ -183,6 +183,25 @@ relation_transitive (relation_kind r1, relation_kind r2)
   return relation_kind (rr_transitive_table[r1][r2]);
 }
 
+// When one name is an equivalence of another, ensure the equivalence
+// range is correct.  Specifically for floating point, a +0 is also
+// equivalent to a -0 which may not be reflected.  See PR 111694.
+
+void
+adjust_equivalence_range (vrange &range)
+{
+  if (range.undefined_p () || !is_a<frange> (range))
+    return;
+
+  frange fr = as_a<frange> (range);
+  REAL_VALUE_TYPE dconstm0 = dconst0;
+  dconstm0.sign = 1;
+  frange zeros (range.type (), dconstm0, dconst0);
+  // If range includes a 0 make sure both signs of zero are included.
+  if (fr.intersect (zeros) && !fr.undefined_p ())
+    range.union_ (zeros);
+ }
+
 // This vector maps a relation to the equivalent tree code.
 
 static const tree_code relation_to_code [VREL_LAST] = {
index 3177ecb1ad0b0e9d0d4337168796df2fcca3ce2c..6412cbbe98b3aea9b9124e8faea1c87128ba38ed 100644 (file)
@@ -91,6 +91,9 @@ inline bool relation_equiv_p (relation_kind r)
 
 void print_relation (FILE *f, relation_kind rel);
 
+// Adjust range as an equivalence.
+void adjust_equivalence_range (vrange &range);
+
 class relation_oracle
 {
 public: