NetBSD Problem Report #60015

From www@netbsd.org  Tue Feb 17 23:20:39 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits)
	 client-signature RSA-PSS (2048 bits))
	(Client CN "mail.netbsd.org", Issuer "R13" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id A11C11A9239
	for <gnats-bugs@gnats.NetBSD.org>; Tue, 17 Feb 2026 23:20:39 +0000 (UTC)
Message-Id: <20260217232038.9E3921A923C@mollari.NetBSD.org>
Date: Tue, 17 Feb 2026 23:20:38 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: x87 makes testing signalling NaN difficult
X-Send-Pr-Version: www-1.0
X-From4GNATS: "campbell+netbsd@mumble.net via gnats" <gnats-admin@NetBSD.org>

>Number:         60015
>Category:       lib
>Synopsis:       x87 makes testing signalling NaN difficult
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 17 23:25:00 +0000 2026
>Last-Modified:  Tue Feb 17 23:35:01 +0000 2026
>Originator:     Taylor R Campbell
>Release:        current
>Organization:
The NanBSD/i387 Roundation, Inc.
>Environment:
>Description:

	The C23 fpclassify() function and its cousins isnan(),
	isinf(), isnormal(), &c., are required, in implementations
	supporting Annex F (IEC 60559 floating-point arithmetic, more
	popularly known as IEEE 754), _not_ to raise floating-point
	exceptions _even if_ the inputs are signalling NaN:

	> 6. The C classification macros fpclassify, iscanonical,
	> isfinite, isinf, isnan, isnormal, issignaling, issubnormal,
	> iszero, and signbit provide the IEC 60559 operations
	> indicated in the table above provided their arguments are in
	> the format of their semantic type. Then these macros raise no
	> floating-point exceptions, even if an argument is a signaling
	> NaN.  --C23, Annex F, Sec. F.3

	(This language appears to be new in C23; I can't find it in C99
	or C11, though I haven't tracked down the specific change that
	added it in C23.)

	It is tempting to try something like this, as in t_fpclassify.c
	rev. 1.21 for double (simplified for the double-only case):

bool
issignalling(double f)
{
	union { double f; uint64_t i; } u = { .f = f };

	return isnan(f) && (u.i & (DBL_SNANBIT|DBL_QNANBIT)) == DBL_SNANBIT;
}

	Unfortunately, actually using this can prove difficult.  The
	following assertion should be guaranteed not to fire:

		feclearexcept(FE_ALL_EXCEPT);
		x = issignalling(nan);
		assert(fetestexcept(FE_ALL_EXCEPT) == 0);

	But on x87, mere floating-point load instruction (FLDL) to load
	a double (IEEE 754 binary64) into the floating-point register
	stack converts it to long double format (x87 80-bit extended
	precision) which maps signalling NaN to quite NaN and, as a
	side effect, raises FE_INVALID.

	So issignalling might wrongly return false _and_ calling it
	might raise a floating-point exception.

>How-To-Repeat:

	Expected output with the following program:

		issignalling=1 except=0x0

	Actual output on i386:

		issignalling=0 except=0x1

#include <fenv.h>
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#if defined __hppa__ || defined __mips__	/* just, why? */
#  define	QNANBIT	0
#  define	SNANBIT	1
#else
#  define	QNANBIT	1
#  define	SNANBIT	0
#endif

#define	DBL_QNANBIT	(QNANBIT*((uint64_t)1 << (DBL_MANT_DIG - 2)))
#define	DBL_SNANBIT	(SNANBIT*((uint64_t)1 << (DBL_MANT_DIG - 2)))

bool
issignalling(double f)
{
	union { double f; uint64_t i; } u = { .f = f };

	return isnan(f) && (u.i & (DBL_SNANBIT|DBL_QNANBIT)) == DBL_SNANBIT;
}

volatile union {
	double d;
	uint64_t u64;
} u = { .u64 = 0x7ff0000000000001 };

int
main(void)
{
	bool result;
	int except;

	feclearexcept(FE_ALL_EXCEPT);
	result = issignalling(u.d);
	except = fetestexcept(FE_ALL_EXCEPT);

	printf("issignalling=%d except=0x%x\n", result, except);
	fflush(stdout);
	return ferror(stdout);
}

	Relevant excerpt of generated code -- note that the value of
	u.d is loaded with FLDL only to store it on the stack again
	with FSTPL for passing to __isnand, which both raises an
	exception (FE_INVALID) and changes the input to __isnand so
	that it is a quiet NaN:

  16:	dd 05 00 00 00 00    	fldl   0x0
			18: R_386_32	u
  1c:	dd 5c 24 18          	fstpl  0x18(%esp)
  20:	f2 0f 10 44 24 18    	movsd  0x18(%esp),%xmm0
  26:	f2 0f 11 04 24       	movsd  %xmm0,(%esp)
  2b:	e8 fc ff ff ff       	call   2c <main+0x2c>
			2c: R_386_PC32	__isnand
  30:	85 c0                	test   %eax,%eax
  32:	74 50                	je     84 <main+0x84>
  34:	8b 54 24 1c          	mov    0x1c(%esp),%edx
  38:	89 d0                	mov    %edx,%eax
  3a:	c1 e8 13             	shr    $0x13,%eax
  3d:	83 f0 01             	xor    $0x1,%eax
  40:	89 c3                	mov    %eax,%ebx
  42:	83 e3 01             	and    $0x1,%ebx

>Fix:

	Find a flux capacitor and a place to drive 88mph during a
	lightning storm so we can have a word with engineers at Intel
	in 1985.

>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60015 CVS commit: src/tests/lib/libc/gen
Date: Tue, 17 Feb 2026 23:33:05 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Tue Feb 17 23:33:05 UTC 2026

 Modified Files:
 	src/tests/lib/libc/gen: t_fpclassify.c

 Log Message:
 t_fpclassify: Give up on double issignalling on i386 for now.

 PR lib/60015: x87 makes testing signalling NaN difficult


 To generate a diff of this commit:
 cvs rdiff -u -r1.21 -r1.22 src/tests/lib/libc/gen/t_fpclassify.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.