https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125562
Bug ID: 125562
Summary: float-double-float conversion does not change
signaling NaN (sNaN) to quiet NaN (qNaN)
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: vincent-gcc at vinc17 dot net
Target Milestone: ---
With a float-double-float conversion, GCC does not change signaling NaN (sNaN)
to quiet NaN (qNaN), as shown by the following test:
#include <stdio.h>
#include <inttypes.h>
#include <float.h>
typedef union { float f; uint32_t i; } ieee_float_t;
int main (void)
{
volatile ieee_float_t x;
x.f = NAN;
printf ("%x (%g)\n", x.i, x.f);
x.f = FLT_SNAN;
printf ("%x (%g)\n", x.i, x.f);
x.f = (double) x.f;
printf ("%x (%g)\n", x.i, x.f);
return 0;
}
which outputs
7fc00000 (nan)
7fa00000 (nan)
7fa00000 (nan)
on x86_64, in any optimization level, even if -std=c23 and -fsignaling-nans are
given. The 3rd value is a signaling NaN (since it has the same encoding as the
2nd value), while it should have been a quiet NaN.
Tested GCC versions (under Debian/unstable):
* gcc (Debian 15.2.0-17) 15.2.0
* gcc (Debian 20260503-1) 17.0.0 20260503 (experimental) [trunk
r17-283-g00f6fb9df07]
According to ISO C23, a conversion to a different format corresponds to the
IEEE 754 convertFormat operation, so that NaNs should be quieted. Also note
that F.2.2 says: "Where specification of signaling NaNs is not provided, the
behavior of signaling NaNs is implementation-defined (either treated as an
ISO/IEC 60559 quiet NaN or treated as an ISO/IEC 60559 signaling NaN)." But
whether the input NaN is treated as quiet or signaling, its conversion to a
different format should always give a quiet NaN.