DBL_DENORM_MIN should never be 0

Marc Glisse marc.glisse@inria.fr
Wed Sep 10 09:42:00 GMT 2014


Hello,

according to the C++ standard, numeric_limits::denorm_min should return 
min (not 0) when there are no denormals.

Tested with bootstrap+testsuite on x86_64-linux-gnu. I also tested a basic 
make all-gcc for vax (only target without denormals apparently) and the 
macro did change as expected.

The next step might be to define has_denorm as false in more cases 
(-mno-ieee on alpha, -ffast-math on x86, etc) but that's a different 
issue.

(this is C++ but I believe Joseph is the floating-point expert, hence the 
cc)

gcc/c-family/

2014-09-10  Marc Glisse  <marc.glisse@inria.fr>

 	* c-cppbuiltin.c (builtin_define_float_constants): Correct
 	__*_DENORM_MIN__ without denormals.

-- 
Marc Glisse
-------------- next part --------------
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c	(revision 215103)
+++ gcc/c-family/c-cppbuiltin.c	(working copy)
@@ -264,34 +264,27 @@ builtin_define_float_constants (const ch
   sprintf (name, "__%s_EPSILON__", name_prefix);
   if (fmt->pnan < fmt->p)
     /* This is an IBM extended double format, so 1.0 + any double is
        representable precisely.  */
       sprintf (buf, "0x1p%d", fmt->emin - fmt->p);
     else
       sprintf (buf, "0x1p%d", 1 - fmt->p);
   builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
 
   /* For C++ std::numeric_limits<T>::denorm_min.  The minimum denormalized
-     positive floating-point number, b**(emin-p).  Zero for formats that
-     don't support denormals.  */
+     positive floating-point number, b**(emin-p).  The minimum normalized
+     positive floating-point number for formats that don't support
+     denormals.  */
   sprintf (name, "__%s_DENORM_MIN__", name_prefix);
-  if (fmt->has_denorm)
-    {
-      sprintf (buf, "0x1p%d", fmt->emin - fmt->p);
-      builtin_define_with_hex_fp_value (name, type, decimal_dig,
-					buf, fp_suffix, fp_cast);
-    }
-  else
-    {
-      sprintf (buf, "0.0%s", fp_suffix);
-      builtin_define_with_value (name, buf, 0);
-    }
+  sprintf (buf, "0x1p%d", fmt->emin - (fmt->has_denorm ? fmt->p : 1));
+  builtin_define_with_hex_fp_value (name, type, decimal_dig,
+				    buf, fp_suffix, fp_cast);
 
   sprintf (name, "__%s_HAS_DENORM__", name_prefix);
   builtin_define_with_value (name, fmt->has_denorm ? "1" : "0", 0);
 
   /* For C++ std::numeric_limits<T>::has_infinity.  */
   sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
   builtin_define_with_int_value (name,
 				 MODE_HAS_INFINITIES (TYPE_MODE (type)));
   /* For C++ std::numeric_limits<T>::has_quiet_NaN.  We do not have a
      predicate to distinguish a target that has both quiet and


More information about the Gcc-patches mailing list