[COMMITTED] Clear NAN when reading back a global range if necessary.
Checks
Commit Message
When reading back from the global store, we must clear the NAN bit if
necessary. The reason it's not happening is because the constructor
sets a NAN by default (when HONOR_NANS). We must be careful to clear
the NAN bit if the original range didn't have a NAN.
I have commented the reason we use the constructor instead of filling
out the fields by hand, because it wasn't clear at re-reading this
code.
PR 107569/tree-optimization
gcc/ChangeLog:
* value-range-storage.cc (frange_storage_slot::get_frange): Clear
NAN if appropriate.
* value-range.cc (range_tests_floats): New test.
---
gcc/value-range-storage.cc | 9 ++++++++-
gcc/value-range.cc | 9 +++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
@@ -276,13 +276,20 @@ frange_storage_slot::get_frange (frange &r, tree type) const
return;
}
- // Use the constructor because it will canonicalize the range.
+ // We use the constructor to create the new range instead of writing
+ // out the bits into the frange directly, because the global range
+ // being read may be being inlined into a function with different
+ // restrictions as when it was originally written. We want to make
+ // sure the resulting range is canonicalized correctly for the new
+ // consumer.
r = frange (type, m_min, m_max, m_kind);
// The constructor will set the NAN bits for HONOR_NANS, but we must
// make sure to set the NAN sign if known.
if (HONOR_NANS (type) && (m_pos_nan ^ m_neg_nan) == 1)
r.update_nan (m_neg_nan);
+ else if (!m_pos_nan && !m_neg_nan)
+ r.clear_nan ();
}
bool
@@ -4051,6 +4051,15 @@ range_tests_floats ()
ASSERT_TRUE (real_isinf (&r0.lower_bound (), true));
ASSERT_TRUE (real_isinf (&r0.upper_bound (), true));
}
+
+ // Test that reading back a global range yields the same result as
+ // what we wrote into it.
+ tree ssa = make_temp_ssa_name (float_type_node, NULL, "blah");
+ r0.set_varying (float_type_node);
+ r0.clear_nan ();
+ set_range_info (ssa, r0);
+ get_global_range_query ()->range_of_expr (r1, ssa);
+ ASSERT_EQ (r0, r1);
}
// Run floating range tests for various combinations of NAN and INF