[gcc r17-2928] [frange] Factor float_widen_bound out of float_widen_lhs_range.

Aldy Hernandez via Gcc-cvs <[email protected]> Tue, 4 Aug 2026 12:13:03 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:dd4a1a6a494f3afc0fac9ad95824ddf9e1c459c8

commit r17-2928-gdd4a1a6a494f3afc0fac9ad95824ddf9e1c459c8
Author: Aldy Hernandez <[email protected]>
Date:   Mon Aug 3 11:01:40 2026 +0000

    [frange] Factor float_widen_bound out of float_widen_lhs_range.
    
    Factor out the per-bound logic into a helper function.
    
    No functional change.
    
    Tested on ppc64le Linux.  Regstrap plus no changes to assembly over
    LAPACK source files.
    
    gcc/ChangeLog:
    
            * range-op-float.cc (float_widen_bound): New, factored out of...
            (float_widen_lhs_range): ...here.

Diff:
---
 gcc/range-op-float.cc | 83 ++++++++++++++++++++++-----------------------------
 1 file changed, 36 insertions(+), 47 deletions(-)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index c0283a687756..d5a3a49fb7d7 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -2364,6 +2364,40 @@ zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
     }
 }
 
+/* Widen a single bound of a sub-range by 1ulp (or 0.5ulp) in the direction of
+   DIR.  */
+
+static REAL_VALUE_TYPE
+float_widen_bound (tree type, const REAL_VALUE_TYPE &bound,
+		   const REAL_VALUE_TYPE &dir)
+{
+  REAL_VALUE_TYPE res = bound;
+  if (!real_isfinite (&bound) && real_isneg (&bound) == real_isneg (&dir))
+    return res;
+  frange_nextafter (TYPE_MODE (type), res, dir);
+  if (real_isinf (&res))
+    {
+      /* For +-DBL_MAX, instead of +-Inf use nexttoward (+-DBL_MAX, +-LDBL_MAX)
+	 in a hypothetical wider type with the same mantissa precision but
+	 larger exponent range; it is outside of range of double values, but
+	 makes it clear it is just one ulp larger rather than infinite amount
+	 larger.  */
+      res = real_isneg (&dir) ? dconstm1 : dconst1;
+      SET_REAL_EXP (&res, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
+    }
+  if (!flag_rounding_math
+      && !MODE_COMPOSITE_P (TYPE_MODE (type))
+      && real_isfinite (&bound))
+    {
+      /* If not -frounding-math nor IBM double double, actually widen
+	 just by 0.5ulp rather than 1ulp.  */
+      REAL_VALUE_TYPE tem;
+      real_arithmetic (&tem, PLUS_EXPR, &bound, &res);
+      real_arithmetic (&res, RDIV_EXPR, &tem, &dconst2);
+    }
+  return res;
+}
+
 /* Extend the LHS range by 1ulp in each direction.  For op1_range
    or op2_range of binary operations just computing the inverse
    operation on ranges isn't sufficient.  Consider e.g.
@@ -2379,53 +2413,8 @@ float_widen_lhs_range (tree type, const frange &lhs)
   frange ret = lhs;
   if (lhs.known_isnan ())
     return ret;
-  REAL_VALUE_TYPE lb = lhs.lower_bound ();
-  REAL_VALUE_TYPE ub = lhs.upper_bound ();
-  if (real_isfinite (&lb) || !real_isneg (&lb))
-    {
-      frange_nextafter (TYPE_MODE (type), lb, dconstninf);
-      if (real_isinf (&lb))
-	{
-	  /* For -DBL_MAX, instead of -Inf use
-	     nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
-	     wider type with the same mantissa precision but larger
-	     exponent range; it is outside of range of double values,
-	     but makes it clear it is just one ulp larger rather than
-	     infinite amount larger.  */
-	  lb = dconstm1;
-	  SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
-	}
-      if (!flag_rounding_math
-	  && !MODE_COMPOSITE_P (TYPE_MODE (type))
-	  && real_isfinite (&lhs.lower_bound ()))
-	{
-	  /* If not -frounding-math nor IBM double double, actually widen
-	     just by 0.5ulp rather than 1ulp.  */
-	  REAL_VALUE_TYPE tem;
-	  real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
-	  real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
-	}
-    }
-  if (real_isfinite (&ub) || real_isneg (&ub))
-    {
-      frange_nextafter (TYPE_MODE (type), ub, dconstinf);
-      if (real_isinf (&ub))
-	{
-	  /* For DBL_MAX similarly.  */
-	  ub = dconst1;
-	  SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
-	}
-      if (!flag_rounding_math
-	  && !MODE_COMPOSITE_P (TYPE_MODE (type))
-	  && real_isfinite (&lhs.upper_bound ()))
-	{
-	  /* If not -frounding-math nor IBM double double, actually widen
-	     just by 0.5ulp rather than 1ulp.  */
-	  REAL_VALUE_TYPE tem;
-	  real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
-	  real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
-	}
-    }
+  REAL_VALUE_TYPE lb = float_widen_bound (type, lhs.lower_bound (), dconstninf);
+  REAL_VALUE_TYPE ub = float_widen_bound (type, lhs.upper_bound (), dconstinf);
   /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
      reduce the range back to real_min_representable (type) as lower bound
      or real_max_representable (type) as upper bound.  */