]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[frange] Rewrite union to merge sub-ranges.
authorAldy Hernandez <aldy@quesejoda.com>
Thu, 30 Jul 2026 08:55:14 +0000 (08:55 +0000)
committerAldy Hernandez <aldy@quesejoda.com>
Thu, 30 Jul 2026 14:05:28 +0000 (16:05 +0200)
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.

gcc/value-range.cc

index 472ff37a1df209320e5d835f90b4422ea530d48b..18aa82733a4b6ca44b663d5f002a5688d1b1aa57 100644 (file)
@@ -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.