Replace the single-interval union_ with a sub-range aware one.
Like the intersect rewrite, do this ahead of raising MAX_PAIRS. It is
still 1, so set_pairs collapses the result back to a single range. No
functional change.
Tested on ppc64le: regstrap, LAPACK, no changes on a corpus of Fortran
files.
Pushed.
gcc/ChangeLog:
* value-range.cc (frange::union_): Merge both operands' sub-ranges
via set_pairs instead of widening to the hull.
---
gcc/value-range.cc | 39 ++++++++++++++++++---------------------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 472ff37a1df..18aa82733a4 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1324,29 +1324,26 @@ frange::union_ (const vrange &v)
// Combine NAN info.
if (known_isnan () || r.known_isnan ())
return union_nans (r);
- bool changed = false;
- if (m_pos_nan != r.m_pos_nan || m_neg_nan != r.m_neg_nan)
- {
- m_pos_nan |= r.m_pos_nan;
- m_neg_nan |= r.m_neg_nan;
- changed = true;
- }
- // FIXME: Rewrite for sub-ranges.
- // Combine endpoints. This needs to be rewritten for sub-ranges.
- if (frange_cmp (r.m_pairs[0].min, m_pairs[0].min) < 0)
- {
- m_pairs[0].min = r.m_pairs[0].min;
- changed = true;
- }
- if (frange_cmp (m_pairs[0].max, r.m_pairs[0].max) < 0)
- {
- m_pairs[0].max = r.m_pairs[0].max;
- changed = true;
- }
+ frange save = *this;
+ m_pos_nan |= r.m_pos_nan;
+ m_neg_nan |= r.m_neg_nan;
- changed |= normalize_kind ();
- return changed;
+ // Throw both operands' sub-ranges into the pot as set_pairs will
+ // canonicalize things and hand us back at most MAX_PAIRS.
+ //
+ // NOTE: Both operands are already sorted and disjoint, so a merge could
+ // combine them in O(n) like irange::union_ rather than have set_pairs
+ // re-sort. Not worth it while MAX_PAIRS is tiny; revisit if it grows.
+ frange_pair pairs[2 * MAX_PAIRS];
+ unsigned n = 0;
+ for (unsigned i = 0; i < save.m_num_ranges; ++i)
+ pairs[n++] = save.m_pairs[i];
+ for (unsigned i = 0; i < r.m_num_ranges; ++i)
+ pairs[n++] = r.m_pairs[i];
+
+ set_pairs (pairs, n);
+ return *this != save;
}
// Intersect two ranges when one is known to be a NAN.
--
2.47.3