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.gli...@inria.fr> * c-cppbuiltin.c (builtin_define_float_constants): Correct __*_DENORM_MIN__ without denormals. -- Marc Glisse
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