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

Reply via email to