diff mbox

DBL_DENORM_MIN should never be 0

Message ID alpine.DEB.2.02.1409101124130.29968@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse Sept. 10, 2014, 9:42 a.m. UTC
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.

Comments

Joseph Myers Sept. 10, 2014, 4:42 p.m. UTC | #1
On Wed, 10 Sep 2014, Marc Glisse wrote:

> 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)

This is a C issue as well (for C11 *_TRUE_MIN).

> gcc/c-family/
> 
> 2014-09-10  Marc Glisse  <marc.glisse@inria.fr>
> 

	PR target/58757

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

I think there should be some sort of testcase that these values aren't 0.
diff mbox

Patch

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