[gcc r17-3042] [frange] Convert operator_negate::fold_range to sub-ranges.

Aldy Hernandez via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:75978536389062ca8bc48a62f0d096b0f27caecb

commit r17-3042-g75978536389062ca8bc48a62f0d096b0f27caecb
Author: Aldy Hernandez <[email protected]>
Date:   Tue Aug 4 13:13:36 2026 +0000

    [frange] Convert operator_negate::fold_range to sub-ranges.
    
    Negate each sub-range on its own and union the results, so the gaps
    between sub-ranges survive instead of collapsing to the [lower, upper]
    hull.
    
    Tested on ppc64le: regstrap, LAPACK.
    
    gcc/ChangeLog:
    
            * range-op-float.cc (operator_negate::fold_range): Negate each
            sub-range and union the results.
            (range_op_float_tests): New test.

Diff:
---
 gcc/range-op-float.cc | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index ebf4f4e8ad80..3e0258c4cc01 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -1491,11 +1491,16 @@ operator_negate::fold_range (frange &r, tree type,
       return true;
     }
 
-  REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
-  REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
-  lh_lb = real_value_negate (&lh_lb);
-  lh_ub = real_value_negate (&lh_ub);
-  r.set (type, lh_ub, lh_lb);
+  r.set_undefined ();
+  for (unsigned i = 0; i < op1.num_pairs (); ++i)
+    {
+      REAL_VALUE_TYPE lb = op1.lower_bound (i);
+      REAL_VALUE_TYPE ub = op1.upper_bound (i);
+      lb = real_value_negate (&lb);
+      ub = real_value_negate (&ub);
+      frange tmp (type, ub, lb);
+      r.union_ (tmp);
+    }
   if (op1.maybe_isnan ())
     {
       bool sign;
@@ -3280,6 +3285,14 @@ range_op_float_tests ()
   int_range<2> bool_true = range_true ();
   range_op_handler (EQ_EXPR).op1_range (r, float_type_node, bool_true, r0);
   ASSERT_TRUE (r.contains_p (dconst0));
+
+  // negate([1, 2] U [10, 11]) => [-11, -10] U [-2, -1], keeping the gap.
+  r0 = frange_float ("1.0", "2.0");
+  r1 = frange_float ("10.0", "11.0");
+  r0.union_ (r1);
+  r0.clear_nan ();
+  range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
+  ASSERT_EQ (r.num_pairs (), 2);
 }
 
 } // namespace selftest
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.