aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2023-10-09 10:15:07 -0400
committerAndrew MacLeod <amacleod@redhat.com>2023-10-09 12:15:17 -0400
commitb0892b1fc637fadf14d7016858983bc5776a1e69 (patch)
tree521c05bbad3d113c397dd710a2f8ea5fd4124123
parent5ee51119d1345f3f13af784455a4ae466766912b (diff)
downloadgcc-b0892b1fc637fadf14d7016858983bc5776a1e69.zip
gcc-b0892b1fc637fadf14d7016858983bc5776a1e69.tar.gz
gcc-b0892b1fc637fadf14d7016858983bc5776a1e69.tar.bz2
Ensure float equivalences include + and - zero.
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.
-rw-r--r--gcc/gimple-range-cache.cc3
-rw-r--r--gcc/testsuite/gcc.dg/pr111694.c19
-rw-r--r--gcc/value-relation.cc19
-rw-r--r--gcc/value-relation.h3
4 files changed, 44 insertions, 0 deletions
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 3c81993..89c0845 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1470,6 +1470,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
index 0000000..a70b030
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr111694.c
@@ -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);
+}
+
diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc
index a2ae396..0326fe7 100644
--- a/gcc/value-relation.cc
+++ b/gcc/value-relation.cc
@@ -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);
+ // If range includes 0 make sure both signs of zero are included.
+ if (fr.contains_p (dconst0) || fr.contains_p (dconstm0))
+ {
+ frange zeros (range.type (), dconstm0, dconst0);
+ range.union_ (zeros);
+ }
+ }
+
// This vector maps a relation to the equivalent tree code.
static const tree_code relation_to_code [VREL_LAST] = {
diff --git a/gcc/value-relation.h b/gcc/value-relation.h
index be6e277..31d4890 100644
--- a/gcc/value-relation.h
+++ b/gcc/value-relation.h
@@ -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: