NANs don't have bounds, so there's no need to stream them out. gcc/ChangeLog:
* data-streamer-in.cc (streamer_read_value_range): Handle NANs. * data-streamer-out.cc (streamer_write_vrange): Same. * value-range.h (class vrange): Make streamer_write_vrange a friend. --- gcc/data-streamer-in.cc | 16 ++++++++++++---- gcc/data-streamer-out.cc | 17 ++++++++++++----- gcc/value-range.h | 1 + 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/gcc/data-streamer-in.cc b/gcc/data-streamer-in.cc index 07728bef413..578c328475f 100644 --- a/gcc/data-streamer-in.cc +++ b/gcc/data-streamer-in.cc @@ -248,14 +248,22 @@ streamer_read_value_range (class lto_input_block *ib, data_in *data_in, if (is_a <frange> (vr)) { frange &r = as_a <frange> (vr); - REAL_VALUE_TYPE lb, ub; - streamer_read_real_value (ib, &lb); - streamer_read_real_value (ib, &ub); + + // Stream in NAN bits. struct bitpack_d bp = streamer_read_bitpack (ib); bool pos_nan = (bool) bp_unpack_value (&bp, 1); bool neg_nan = (bool) bp_unpack_value (&bp, 1); nan_state nan (pos_nan, neg_nan); - r.set (type, lb, ub, nan); + + if (kind == VR_NAN) + r.set_nan (type, nan); + else + { + REAL_VALUE_TYPE lb, ub; + streamer_read_real_value (ib, &lb); + streamer_read_real_value (ib, &ub); + r.set (type, lb, ub, nan); + } return; } gcc_unreachable (); diff --git a/gcc/data-streamer-out.cc b/gcc/data-streamer-out.cc index afc9862062b..93dedfcb895 100644 --- a/gcc/data-streamer-out.cc +++ b/gcc/data-streamer-out.cc @@ -410,7 +410,7 @@ streamer_write_vrange (struct output_block *ob, const vrange &v) gcc_checking_assert (!v.undefined_p ()); // Write the common fields to all vranges. - value_range_kind kind = v.varying_p () ? VR_VARYING : VR_RANGE; + value_range_kind kind = v.m_kind; streamer_write_enum (ob->main_stream, value_range_kind, VR_LAST, kind); stream_write_tree (ob, v.type (), true); @@ -429,15 +429,22 @@ streamer_write_vrange (struct output_block *ob, const vrange &v) if (is_a <frange> (v)) { const frange &r = as_a <frange> (v); - REAL_VALUE_TYPE lb = r.lower_bound (); - REAL_VALUE_TYPE ub = r.upper_bound (); - streamer_write_real_value (ob, &lb); - streamer_write_real_value (ob, &ub); + + // Stream out NAN bits. bitpack_d bp = bitpack_create (ob->main_stream); nan_state nan = r.get_nan_state (); bp_pack_value (&bp, nan.pos_p (), 1); bp_pack_value (&bp, nan.neg_p (), 1); streamer_write_bitpack (&bp); + + // Stream out bounds. + if (kind != VR_NAN) + { + REAL_VALUE_TYPE lb = r.lower_bound (); + REAL_VALUE_TYPE ub = r.upper_bound (); + streamer_write_real_value (ob, &lb); + streamer_write_real_value (ob, &ub); + } return; } gcc_unreachable (); diff --git a/gcc/value-range.h b/gcc/value-range.h index 39023e7b5eb..2b4ebabe7c8 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -76,6 +76,7 @@ class GTY((user)) vrange { template <typename T> friend bool is_a (vrange &); friend class Value_Range; + friend void streamer_write_vrange (struct output_block *, const vrange &); public: virtual void accept (const class vrange_visitor &v) const = 0; virtual void set (tree, tree, value_range_kind = VR_RANGE); -- 2.40.1