From: Aldy Hernandez Date: Thu, 30 Jul 2026 08:55:14 +0000 (+0000) Subject: [frange] Rewrite union to merge sub-ranges. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8cfdd1ed0f0da83a8426ac6a30e33dc945fbfcde;p=thirdparty%2Fgcc.git [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 --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.