From f0efc4b25cba1bd35b08b7dfbab0f8fc81b55c66 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 9 Oct 2023 13:40:15 -0400 Subject: [PATCH] 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. --- gcc/gimple-range-cache.cc | 3 +++ gcc/testsuite/gcc.dg/pr111694.c | 19 +++++++++++++++++++ gcc/value-relation.cc | 19 +++++++++++++++++++ gcc/value-relation.h | 3 +++ 4 files changed, 44 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr111694.c diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 2314478d5584..e4e759436328 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -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 index 000000000000..a70b03069dce --- /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 30a02d3c9d36..fc792a4d5bc2 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 (range)) + return; + + frange fr = as_a (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] = { diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 3177ecb1ad0b..6412cbbe98b3 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: -- 2.47.3