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.

Reply via email to