Go patch committed: Avoid negative zero in float constants

Ian Lance Taylor iant@golang.org
Mon Feb 5 19:26:00 GMT 2018


On Mon, Feb 5, 2018 at 10:47 AM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
>
>> This patch to the Go frontend checks for negative numbers with very
>> small magnitudes that will round to negative zero, and forces them to
>> positive zero instead.  This implements the spec clarification in
>> https://golang.org/cl/14727.  The test is in
>> https://golang.org/cl/91895.  This fixes golang.org/issue/12621.
>> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
>> to mainline.
>
> unfortunately, this broke bootstrap with mpfr 2.4.2, which is still the
> minimum version documented in install.texi:

Bother.  Thanks for the note.  I've rolled back the patch, as follows.

Ian
-------------- next part --------------
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 257390)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@
-7eebd495df915ab87926b8dd88f554674cfdacea
+c02c71187c9794b50444e2858c582e66a3442ee8
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 257390)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -16158,16 +16158,10 @@ Numeric_constant::set_float(Type* type,
   this->clear();
   this->classification_ = NC_FLOAT;
   this->type_ = type;
-
   // Numeric constants do not have negative zero values, so remove
   // them here.  They also don't have infinity or NaN values, but we
   // should never see them here.
-  int bits = 0;
-  if (type != NULL
-      && type->float_type() != NULL
-      && !type->float_type()->is_abstract())
-    bits = type->float_type()->bits();
-  if (Numeric_constant::is_float_zero(val, bits))
+  if (mpfr_zero_p(val))
     mpfr_init_set_ui(this->u_.float_val, 0, GMP_RNDN);
   else
     mpfr_init_set(this->u_.float_val, val, GMP_RNDN);
@@ -16181,50 +16175,8 @@ Numeric_constant::set_complex(Type* type
   this->clear();
   this->classification_ = NC_COMPLEX;
   this->type_ = type;
-
-  // Avoid negative zero as in set_float.
-  int bits = 0;
-  if (type != NULL
-      && type->complex_type() != NULL
-      && !type->complex_type()->is_abstract())
-    bits = type->complex_type()->bits() / 2;
-
-  mpfr_t real;
-  mpfr_init_set(real, mpc_realref(val), GMP_RNDN);
-  if (Numeric_constant::is_float_zero(real, bits))
-    mpfr_set_ui(real, 0, GMP_RNDN);
-
-  mpfr_t imag;
-  mpfr_init_set(imag, mpc_imagref(val), GMP_RNDN);
-  if (Numeric_constant::is_float_zero(imag, bits))
-    mpfr_set_ui(imag, 0, GMP_RNDN);
-
   mpc_init2(this->u_.complex_val, mpc_precision);
-  mpc_set_fr_fr(this->u_.complex_val, real, imag, MPC_RNDNN);
-
-  mpfr_clear(real);
-  mpfr_clear(imag);
-}
-
-// Return whether VAL, at a precision of BITS, is zero.  BITS may be
-// zero in which case it is ignored.
-
-bool
-Numeric_constant::is_float_zero(const mpfr_t val, int bits)
-{
-  if (mpfr_zero_p(val))
-    return true;
-  switch (bits)
-    {
-    case 0:
-      return false;
-    case 32:
-      return mpfr_get_flt(val, GMP_RNDN) == 0;
-    case 64:
-      return mpfr_get_d(val, GMP_RNDN) == 0;
-    default:
-      go_unreachable();
-    }
+  mpc_set(this->u_.complex_val, val, MPC_RNDNN);
 }
 
 // Get an int value.
Index: gcc/go/gofrontend/expressions.h
===================================================================
--- gcc/go/gofrontend/expressions.h	(revision 257390)
+++ gcc/go/gofrontend/expressions.h	(working copy)
@@ -4220,9 +4220,6 @@ class Numeric_constant
   bool
   check_complex_type(Complex_type*, bool, Location);
 
-  static bool
-  is_float_zero(const mpfr_t, int bits);
-
   // The kinds of constants.
   enum Classification
   {


More information about the Gcc-patches mailing list