https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127298
Bug ID: 127298
Summary: [alpha] classification built-ins expand to FP
comparisons, which trap or misclassify a subnormal
operand
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: mattst88 at gmail dot com
Target Milestone: ---
Host: alpha-*-*
On Alpha, __builtin_fpclassify, __builtin_isnan, __builtin_isinf,
__builtin_isinf_sign, __builtin_isfinite and __builtin_isnormal expand to
floating-point comparison instructions, which in the default trap mode carry
no software-completion suffix:
$ cat cls.c
#include <stdio.h>
int
main (void)
{
volatile double x = 0x1p-1050;
printf ("%d\n", __builtin_fpclassify (0, 1, 4, 3, 2, x));
return 0;
}
$ alpha-unknown-linux-gnu-gcc -O2 -o cls cls.c
$ ./cls
Floating point exception (core dumped)
A comparison raises a denormal-operand exception for a subnormal operand, and
what follows depends on the FPCR denormal-operand-disable bit:
- with denormal traps enabled, the default on Linux, the trap is delivered
with no completion information and the program dies as above;
- with them disabled, the operand is flushed to zero, so a subnormal is
indistinguishable from a zero. __builtin_fpclassify then returns FP_ZERO
for a subnormal, and __builtin_isnormal is no more trustworthy.
The fpclassify expansion above ends in "cmpteq $f16,$f31,$f10" -- a comparison
against zero, which a flushed subnormal passes.
-mieee gives the right answer, and the program above prints 3, because the
compiler then maintains trap shadows and emits cmptun/su for the kernel to
complete. But -mieee is not the default, and emitting /su ad hoc without it
is not a fix: software completion also needs the trap-shadow rules, which the
compiler only observes at -mfp-trap-mode=su and above.
Classifying by examining the encoding in an integer register needs no
comparison and raises nothing. __builtin_issignaling already does that and is
unaffected.
This also blocks glibc, whose fpclassify, isnan, isinf, isfinite and isnormal
macros are defined in terms of these built-ins and have to call the
out-of-line implementations on Alpha instead. A different failure mode from
PR 66462 -- wrong for signalling NaNs there, wrong for subnormals here -- but
the same consequence.
Patch to follow: the isfinite<mode>2, isinf<mode>2, isnan<mode>2 and
isnormal<mode>2 optabs in the Alpha back end for alpha_fptm < ALPHA_FPTM_SU,
plus a fold_builtin_fpclassify change to build on those built-ins where their
optabs exist rather than always folding to comparisons.