llvm / llvm/llvm-project

[clang] [x86_64] __builtin_fpclassify raises FE_INVALID for denormal numbers

Open
#172,533 3 comments 0 reactions 0 assignees View on GitHub
backend:X86 clang:frontend crash-on-valid floating-point
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

On x86_64:

```
$ cat t.c
#include
#include
#include

typedef union
{
long double value;
struct
{
uint32_t lsw;
uint32_t msw;
int sign_exponent:16;
unsigned int empty1:16;
unsigned int empty0:32;
} parts;
} ieee_long_double_shape_type;

static const ieee_long_double_shape_type pseudo_zero = { .parts = { 0x00000000, 0x00000000, 0x0100 } };

int main (int argc, char *argv[])
{
feenableexcept (FE_INVALID);
return __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, pseudo_zero.value);
}
$ clang t.c -o t -D_GNU_SOURCE -lm
$ ./t
Floating point exception
```

The glibc `math.h` adds a `fpclassify` optimization to use the `__builtin_fpclassify`, but it is disabled when -fsignaling-nan is used (GCC [bug 66462](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66462)). It seems always enabled on clang/x86_64 because it does define `__SUPPORT_SNAN__`.

Contributor guide

Open the contributing guide

Research direction

Start by compiling and running the t.c reproducer with clang on x86_64, enabling FE_INVALID as shown. Compare __builtin_fpclassify behavior for the denormal long double with the glibc math.h optimization and the -fsignaling-nan case. Done means classifying the denormal without raising FE_INVALID.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.