Negating dconst0 is getting pretty old, and we will keep adding copies
of the same idiom.  Fixed by adding a dconstm0 constant to go along
with dconst1, dconstm1, etc.

OK for trunk?

gcc/ChangeLog:

        * emit-rtl.cc (init_emit_once): Initialize dconstm0.
        * gimple-range-op.cc (class cfn_signbit): Remove dconstm0
        declaration.
        * range-op-float.cc (zero_range): Use dconstm0.
        (zero_to_inf_range): Same.
        * real.h (dconstm0): New.
        * value-range.cc (frange::flush_denormals_to_zero): Use dconstm0.
        (frange::set_zero): Do not declare dconstm0.
---
 gcc/emit-rtl.cc        | 4 ++++
 gcc/gimple-range-op.cc | 2 --
 gcc/range-op-float.cc  | 6 +++---
 gcc/real.h             | 1 +
 gcc/value-range.cc     | 7 +++----
 5 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index a11f72f606b..4036f4b64f7 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -105,6 +105,7 @@ rtx const_true_rtx;
 REAL_VALUE_TYPE dconst0;
 REAL_VALUE_TYPE dconst1;
 REAL_VALUE_TYPE dconst2;
+REAL_VALUE_TYPE dconstm0;
 REAL_VALUE_TYPE dconstm1;
 REAL_VALUE_TYPE dconsthalf;
 REAL_VALUE_TYPE dconstinf;
@@ -6206,6 +6207,9 @@ init_emit_once (void)
   real_from_integer (&dconst1, double_mode, 1, SIGNED);
   real_from_integer (&dconst2, double_mode, 2, SIGNED);
 
+  dconstm0 = dconst0;
+  dconstm0.sign = 1;
+
   dconstm1 = dconst1;
   dconstm1.sign = 1;
 
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 4ca32a7b5d5..f7409e35a99 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -360,8 +360,6 @@ public:
       }
     if (!lhs.contains_p (build_zero_cst (lhs.type ())))
       {
-       REAL_VALUE_TYPE dconstm0 = dconst0;
-       dconstm0.sign = 1;
        r.set (type, frange_val_min (type), dconstm0);
        r.update_nan (true);
        return true;
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index e0e91bad44d..9d184611ae9 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -2263,7 +2263,7 @@ zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int 
signbit_known)
 {
   ub = lb = dconst0;
   if (signbit_known <= 0)
-    lb = real_value_negate (&dconst0);
+    lb = dconstm0;
   if (signbit_known < 0)
     ub = lb;
 }
@@ -2297,7 +2297,7 @@ zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE 
&ub, int signbit_known)
   else if (signbit_known < 0)
     {
       lb = dconstninf;
-      ub = real_value_negate (&dconst0);
+      ub = dconstm0;
     }
   else
     {
@@ -2634,7 +2634,7 @@ private:
            if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
              cp[1] = dconst0;
            else
-             cp[1] = real_value_negate (&dconst0);
+             cp[1] = dconstm0;
          }
        else
          cp[1] = cp[0];
diff --git a/gcc/real.h b/gcc/real.h
index dd41c65d786..9e02139ad63 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -468,6 +468,7 @@ extern void real_ldexp (REAL_VALUE_TYPE *, const 
REAL_VALUE_TYPE *, int);
 extern REAL_VALUE_TYPE dconst0;
 extern REAL_VALUE_TYPE dconst1;
 extern REAL_VALUE_TYPE dconst2;
+extern REAL_VALUE_TYPE dconstm0;
 extern REAL_VALUE_TYPE dconstm1;
 extern REAL_VALUE_TYPE dconsthalf;
 extern REAL_VALUE_TYPE dconstinf;
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index c14a27e23af..34817fc0159 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -322,9 +322,10 @@ frange::flush_denormals_to_zero ()
   // Flush [x, -DENORMAL] to [x, -0.0].
   if (real_isdenormal (&m_max, mode) && real_isneg (&m_max))
     {
-      m_max = dconst0;
       if (HONOR_SIGNED_ZEROS (m_type))
-       m_max.sign = 1;
+       m_max = dconstm0;
+      else
+       m_max = dconst0;
     }
   // Flush [+DENORMAL, x] to [+0.0, x].
   if (real_isdenormal (&m_min, mode) && !real_isneg (&m_min))
@@ -840,8 +841,6 @@ frange::set_zero (tree type)
 {
   if (HONOR_SIGNED_ZEROS (type))
     {
-      REAL_VALUE_TYPE dconstm0 = dconst0;
-      dconstm0.sign = 1;
       set (type, dconstm0, dconst0);
       clear_nan ();
     }
-- 
2.39.2

Reply via email to