1 /* Test conversions of signaling NaNs to and from long double.  */
2 
3 #include <stdint.h>
4 #include <stdio.h>
5 
6 volatile float f_res;
7 volatile double d_res;
8 volatile long double ld_res;
9 
10 volatile float f_snan = __builtin_nansf("");
11 volatile double d_snan = __builtin_nans("");
12 volatile long double ld_snan = __builtin_nansl("");
13 
issignaling_f(float x)14 int issignaling_f(float x)
15 {
16     union { float f; uint32_t u; } u = { .f = x };
17     return (u.u & 0x7fffffff) > 0x7f800000 && (u.u & 0x400000) == 0;
18 }
19 
issignaling_d(double x)20 int issignaling_d(double x)
21 {
22     union { double d; uint64_t u; } u = { .d = x };
23     return (((u.u & UINT64_C(0x7fffffffffffffff)) >
24             UINT64_C(0x7ff0000000000000)) &&
25             (u.u & UINT64_C(0x8000000000000)) == 0);
26 }
27 
issignaling_ld(long double x)28 int issignaling_ld(long double x)
29 {
30     union {
31         long double ld;
32         struct { uint64_t sig; uint16_t sign_exp; } s;
33     } u = { .ld = x };
34     return ((u.s.sign_exp & 0x7fff) == 0x7fff &&
35             (u.s.sig >> 63) != 0 &&
36             (u.s.sig & UINT64_C(0x4000000000000000)) == 0);
37 }
38 
main(void)39 int main(void)
40 {
41     int ret = 0;
42     ld_res = f_snan;
43     if (issignaling_ld(ld_res)) {
44         printf("FAIL: float -> long double\n");
45         ret = 1;
46     }
47     ld_res = d_snan;
48     if (issignaling_ld(ld_res)) {
49         printf("FAIL: double -> long double\n");
50         ret = 1;
51     }
52     f_res = ld_snan;
53     if (issignaling_d(f_res)) {
54         printf("FAIL: long double -> float\n");
55         ret = 1;
56     }
57     d_res = ld_snan;
58     if (issignaling_d(d_res)) {
59         printf("FAIL: long double -> double\n");
60         ret = 1;
61     }
62     return ret;
63 }
64