[gcc r17-2828] [frange] Rewrite union to merge sub-ranges.
Aldy Hernandez via Gcc-cvs <[email protected]> Thu, 30 Jul 2026 14:05:50 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:8cfdd1ed0f0da83a8426ac6a30e33dc945fbfcde commit r17-2828-g8cfdd1ed0f0da83a8426ac6a30e33dc945fbfcde Author: Aldy Hernandez <[email protected]> Date: Thu Jul 30 08:55:14 2026 +0000 [frange] Rewrite union to merge sub-ranges. 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. gcc/ChangeLog: * value-range.cc (frange::union_): Merge both operands' sub-ranges via set_pairs instead of widening to the hull. Diff: --- 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 472ff37a1df2..18aa82733a4b 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.