Skip to content

Commit 5e5478c

Browse files
ZERICO2005mateoconlechuga
authored andcommitted
float classification routines can now be constant folded in C. Also fixed math_test.cpp and constexpr addressof
1 parent 4af9686 commit 5e5478c

File tree

7 files changed

+1043
-96
lines changed

7 files changed

+1043
-96
lines changed

src/libc/include/math.h

+158-27
Original file line numberDiff line numberDiff line change
@@ -9,64 +9,195 @@
99

1010
#include <__math_def.h>
1111

12+
static inline __attribute__((__always_inline__))
13+
bool __signbitf(float __x) {
14+
if (__builtin_constant_p(__x)) {
15+
return (__builtin_copysign(1.0f, __x) < 0.0f);
16+
}
17+
return _signbitf(__x);
18+
}
19+
static inline __attribute__((__always_inline__))
20+
bool __signbitl(long double __x) {
21+
if (__builtin_constant_p(__x)) {
22+
return (__builtin_copysign(1.0L, __x) < 0.0L);
23+
}
24+
return _signbitl(__x);
25+
}
26+
27+
static inline __attribute__((__always_inline__))
28+
bool __issignalingf(float __x) {
29+
return _issignalingf(__x);
30+
}
31+
static inline __attribute__((__always_inline__))
32+
bool __issignalingl(long double __x) {
33+
return _issignalingl(__x);
34+
}
35+
36+
static inline __attribute__((__always_inline__))
37+
bool __isnanf(float __x) {
38+
if (__builtin_constant_p(__x)) {
39+
return __builtin_isnan(__x);
40+
}
41+
return _isnanf(__x);
42+
}
43+
static inline __attribute__((__always_inline__))
44+
bool __isnanl(long double __x) {
45+
if (__builtin_constant_p(__x)) {
46+
return __builtin_isnan(__x);
47+
}
48+
return _isnanl(__x);
49+
}
50+
51+
static inline __attribute__((__always_inline__))
52+
bool __isinff(float __x) {
53+
if (__builtin_constant_p(__x)) {
54+
return __builtin_isinf(__x);
55+
}
56+
return _isinff(__x);
57+
}
58+
static inline __attribute__((__always_inline__))
59+
bool __isinfl(long double __x) {
60+
if (__builtin_constant_p(__x)) {
61+
return __builtin_isinf(__x);
62+
}
63+
return _isinfl(__x);
64+
}
65+
66+
static inline __attribute__((__always_inline__))
67+
bool __isfinitef(float __x) {
68+
if (__builtin_constant_p(__x)) {
69+
return __builtin_isfinite(__x);
70+
}
71+
return _isfinitef(__x);
72+
}
73+
static inline __attribute__((__always_inline__))
74+
bool __isfinitel(long double __x) {
75+
if (__builtin_constant_p(__x)) {
76+
return __builtin_isfinite(__x);
77+
}
78+
return _isfinitel(__x);
79+
}
80+
81+
static inline __attribute__((__always_inline__))
82+
bool __isnormalf(float __x) {
83+
if (__builtin_constant_p(__x)) {
84+
return __builtin_isnormal(__x);
85+
}
86+
return _isnormalf(__x);
87+
}
88+
static inline __attribute__((__always_inline__))
89+
bool __isnormall(long double __x) {
90+
if (__builtin_constant_p(__x)) {
91+
return __builtin_isnormal(__x);
92+
}
93+
return _isnormall(__x);
94+
}
95+
96+
static inline __attribute__((__always_inline__))
97+
bool __issubnormalf(float __x) {
98+
if (__builtin_constant_p(__x)) {
99+
return (FP_SUBNORMAL == __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x));
100+
}
101+
return _issubnormalf(__x);
102+
}
103+
static inline __attribute__((__always_inline__))
104+
bool __issubnormall(long double __x) {
105+
if (__builtin_constant_p(__x)) {
106+
return (FP_SUBNORMAL == __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x));
107+
}
108+
return _issubnormall(__x);
109+
}
110+
111+
static inline __attribute__((__always_inline__))
112+
bool __iszerof(float __x) {
113+
if (__builtin_constant_p(__x)) {
114+
return (__x == 0.0f);
115+
}
116+
return _iszerof(__x);
117+
}
118+
static inline __attribute__((__always_inline__))
119+
bool __iszerol(long double __x) {
120+
if (__builtin_constant_p(__x)) {
121+
return (__x == 0.0L);
122+
}
123+
return _iszerol(__x);
124+
}
125+
126+
static inline __attribute__((__always_inline__))
127+
int __fpclassifyf(float __x) {
128+
if (__builtin_constant_p(__x)) {
129+
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
130+
} else {
131+
return _fpclassifyf(__x);
132+
}
133+
}
134+
static inline __attribute__((__always_inline__))
135+
int __fpclassifyl(long double __x) {
136+
if (__builtin_constant_p(__x)) {
137+
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
138+
} else {
139+
return _fpclassifyl(__x);
140+
}
141+
}
142+
12143
#define __math_promote(x) _Generic((x), \
13144
float: ((float)0.f), \
14145
default: ((double)0.), \
15146
long double: ((long double)0.L) \
16147
)
17148

18149
#define signbit(x) ((int)_Generic(__math_promote(x), \
19-
long double: _signbitl, \
20-
default: _signbitf, \
21-
float: _signbitf \
150+
long double: __signbitl, \
151+
default: __signbitf, \
152+
float: __signbitf \
22153
)(x))
23154

24155
#define issignaling(x) ((int)_Generic(__math_promote(x), \
25-
long double: _issignalingl, \
26-
default: _issignalingf, \
27-
float: _issignalingf \
156+
long double: __issignalingl, \
157+
default: __issignalingf, \
158+
float: __issignalingf \
28159
)(x))
29160

30161
#define isnan(x) ((int)_Generic(__math_promote(x), \
31-
long double: _isnanl, \
32-
default: _isnanf, \
33-
float: _isnanf \
162+
long double: __isnanl, \
163+
default: __isnanf, \
164+
float: __isnanf \
34165
)(x))
35166

36167
#define isinf(x) ((int)_Generic(__math_promote(x), \
37-
long double: _isinfl, \
38-
default: _isinff, \
39-
float: _isinff \
168+
long double: __isinfl, \
169+
default: __isinff, \
170+
float: __isinff \
40171
)(x))
41172

42173
#define isfinite(x) ((int)_Generic(__math_promote(x), \
43-
long double: _isfinitel, \
44-
default: _isfinitef, \
45-
float: _isfinitef \
174+
long double: __isfinitel, \
175+
default: __isfinitef, \
176+
float: __isfinitef \
46177
)(x))
47178

48179
#define isnormal(x) ((int)_Generic(__math_promote(x), \
49-
long double: _isnormall, \
50-
default: _isnormalf, \
51-
float: _isnormalf \
180+
long double: __isnormall, \
181+
default: __isnormalf, \
182+
float: __isnormalf \
52183
)(x))
53184

54185
#define issubnormal(x) ((int)_Generic(__math_promote(x), \
55-
long double: _issubnormall, \
56-
default: _issubnormalf, \
57-
float: _issubnormalf \
186+
long double: __issubnormall, \
187+
default: __issubnormalf, \
188+
float: __issubnormalf \
58189
)(x))
59190

60191
#define iszero(x) ((int)_Generic(__math_promote(x), \
61-
long double: _iszerol, \
62-
default: _iszerof, \
63-
float: _iszerof \
192+
long double: __iszerol, \
193+
default: __iszerof, \
194+
float: __iszerof \
64195
)(x))
65196

66197
#define fpclassify(x) ((int)_Generic(__math_promote(x), \
67-
long double: _fpclassifyl, \
68-
default: _fpclassifyf, \
69-
float: _fpclassifyf \
198+
long double: __fpclassifyl, \
199+
default: __fpclassifyf, \
200+
float: __fpclassifyf \
70201
)(x))
71202

72203
#define isgreater(x, y) __builtin_isgreater(x, y)

src/libcxx/include/memory

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace std {
88

99
template <class _Tp>
10-
inline _Tp* addressof(_Tp& __x) noexcept {
10+
constexpr inline _Tp* addressof(_Tp& __x) noexcept {
1111
return __builtin_addressof(__x);
1212
}
1313

src/libcxx/math_test.cpp

+68-68
Original file line numberDiff line numberDiff line change
@@ -75,23 +75,23 @@ C((!iszero (std::numeric_limits<long double>::denorm_min())));
7575

7676
/* MIN */
7777

78-
C((!signbit (std::numeric_limits<long double>::min())));
79-
C((!issignaling(std::numeric_limits<long double>::min())));
80-
C((!isnan (std::numeric_limits<long double>::min())));
81-
C((!isinf (std::numeric_limits<long double>::min())));
82-
C(( isfinite (std::numeric_limits<long double>::min())));
83-
C(( isnormal (std::numeric_limits<long double>::min())));
84-
C((!issubnormal(std::numeric_limits<long double>::min())));
85-
C((!iszero (std::numeric_limits<long double>::min())));
86-
87-
C((!signbit (std::numeric_limits<long double>::min())));
88-
C((!issignaling(std::numeric_limits<long double>::min())));
89-
C((!isnan (std::numeric_limits<long double>::min())));
90-
C((!isinf (std::numeric_limits<long double>::min())));
91-
C(( isfinite (std::numeric_limits<long double>::min())));
92-
C(( isnormal (std::numeric_limits<long double>::min())));
93-
C((!issubnormal(std::numeric_limits<long double>::min())));
94-
C((!iszero (std::numeric_limits<long double>::min())));
78+
C((!signbit (std::numeric_limits<float>::min())));
79+
C((!issignaling(std::numeric_limits<float>::min())));
80+
C((!isnan (std::numeric_limits<float>::min())));
81+
C((!isinf (std::numeric_limits<float>::min())));
82+
C(( isfinite (std::numeric_limits<float>::min())));
83+
C(( isnormal (std::numeric_limits<float>::min())));
84+
C((!issubnormal(std::numeric_limits<float>::min())));
85+
C((!iszero (std::numeric_limits<float>::min())));
86+
87+
C((!signbit (std::numeric_limits<double>::min())));
88+
C((!issignaling(std::numeric_limits<double>::min())));
89+
C((!isnan (std::numeric_limits<double>::min())));
90+
C((!isinf (std::numeric_limits<double>::min())));
91+
C(( isfinite (std::numeric_limits<double>::min())));
92+
C(( isnormal (std::numeric_limits<double>::min())));
93+
C((!issubnormal(std::numeric_limits<double>::min())));
94+
C((!iszero (std::numeric_limits<double>::min())));
9595

9696
C((!signbit (std::numeric_limits<long double>::min())));
9797
C((!issignaling(std::numeric_limits<long double>::min())));
@@ -191,23 +191,23 @@ C((!iszero (3.1415926535897932384626433832795L)));
191191

192192
/* MAX */
193193

194-
C((!signbit (std::numeric_limits<long double>::max())));
195-
C((!issignaling(std::numeric_limits<long double>::max())));
196-
C((!isnan (std::numeric_limits<long double>::max())));
197-
C((!isinf (std::numeric_limits<long double>::max())));
198-
C(( isfinite (std::numeric_limits<long double>::max())));
199-
C(( isnormal (std::numeric_limits<long double>::max())));
200-
C((!issubnormal(std::numeric_limits<long double>::max())));
201-
C((!iszero (std::numeric_limits<long double>::max())));
202-
203-
C((!signbit (std::numeric_limits<long double>::max())));
204-
C((!issignaling(std::numeric_limits<long double>::max())));
205-
C((!isnan (std::numeric_limits<long double>::max())));
206-
C((!isinf (std::numeric_limits<long double>::max())));
207-
C(( isfinite (std::numeric_limits<long double>::max())));
208-
C(( isnormal (std::numeric_limits<long double>::max())));
209-
C((!issubnormal(std::numeric_limits<long double>::max())));
210-
C((!iszero (std::numeric_limits<long double>::max())));
194+
C((!signbit (std::numeric_limits<float>::max())));
195+
C((!issignaling(std::numeric_limits<float>::max())));
196+
C((!isnan (std::numeric_limits<float>::max())));
197+
C((!isinf (std::numeric_limits<float>::max())));
198+
C(( isfinite (std::numeric_limits<float>::max())));
199+
C(( isnormal (std::numeric_limits<float>::max())));
200+
C((!issubnormal(std::numeric_limits<float>::max())));
201+
C((!iszero (std::numeric_limits<float>::max())));
202+
203+
C((!signbit (std::numeric_limits<double>::max())));
204+
C((!issignaling(std::numeric_limits<double>::max())));
205+
C((!isnan (std::numeric_limits<double>::max())));
206+
C((!isinf (std::numeric_limits<double>::max())));
207+
C(( isfinite (std::numeric_limits<double>::max())));
208+
C(( isnormal (std::numeric_limits<double>::max())));
209+
C((!issubnormal(std::numeric_limits<double>::max())));
210+
C((!iszero (std::numeric_limits<double>::max())));
211211

212212
C((!signbit (std::numeric_limits<long double>::max())));
213213
C((!issignaling(std::numeric_limits<long double>::max())));
@@ -369,23 +369,23 @@ C((!iszero (-std::numeric_limits<long double>::denorm_min())));
369369

370370
/* MIN */
371371

372-
C(( signbit (-std::numeric_limits<long double>::min())));
373-
C((!issignaling(-std::numeric_limits<long double>::min())));
374-
C((!isnan (-std::numeric_limits<long double>::min())));
375-
C((!isinf (-std::numeric_limits<long double>::min())));
376-
C(( isfinite (-std::numeric_limits<long double>::min())));
377-
C(( isnormal (-std::numeric_limits<long double>::min())));
378-
C((!issubnormal(-std::numeric_limits<long double>::min())));
379-
C((!iszero (-std::numeric_limits<long double>::min())));
380-
381-
C(( signbit (-std::numeric_limits<long double>::min())));
382-
C((!issignaling(-std::numeric_limits<long double>::min())));
383-
C((!isnan (-std::numeric_limits<long double>::min())));
384-
C((!isinf (-std::numeric_limits<long double>::min())));
385-
C(( isfinite (-std::numeric_limits<long double>::min())));
386-
C(( isnormal (-std::numeric_limits<long double>::min())));
387-
C((!issubnormal(-std::numeric_limits<long double>::min())));
388-
C((!iszero (-std::numeric_limits<long double>::min())));
372+
C(( signbit (-std::numeric_limits<float>::min())));
373+
C((!issignaling(-std::numeric_limits<float>::min())));
374+
C((!isnan (-std::numeric_limits<float>::min())));
375+
C((!isinf (-std::numeric_limits<float>::min())));
376+
C(( isfinite (-std::numeric_limits<float>::min())));
377+
C(( isnormal (-std::numeric_limits<float>::min())));
378+
C((!issubnormal(-std::numeric_limits<float>::min())));
379+
C((!iszero (-std::numeric_limits<float>::min())));
380+
381+
C(( signbit (-std::numeric_limits<double>::min())));
382+
C((!issignaling(-std::numeric_limits<double>::min())));
383+
C((!isnan (-std::numeric_limits<double>::min())));
384+
C((!isinf (-std::numeric_limits<double>::min())));
385+
C(( isfinite (-std::numeric_limits<double>::min())));
386+
C(( isnormal (-std::numeric_limits<double>::min())));
387+
C((!issubnormal(-std::numeric_limits<double>::min())));
388+
C((!iszero (-std::numeric_limits<double>::min())));
389389

390390
C(( signbit (-std::numeric_limits<long double>::min())));
391391
C((!issignaling(-std::numeric_limits<long double>::min())));
@@ -485,23 +485,23 @@ C((!iszero (-3.1415926535897932384626433832795L)));
485485

486486
/* MAX */
487487

488-
C(( signbit (-std::numeric_limits<long double>::max())));
489-
C((!issignaling(-std::numeric_limits<long double>::max())));
490-
C((!isnan (-std::numeric_limits<long double>::max())));
491-
C((!isinf (-std::numeric_limits<long double>::max())));
492-
C(( isfinite (-std::numeric_limits<long double>::max())));
493-
C(( isnormal (-std::numeric_limits<long double>::max())));
494-
C((!issubnormal(-std::numeric_limits<long double>::max())));
495-
C((!iszero (-std::numeric_limits<long double>::max())));
496-
497-
C(( signbit (-std::numeric_limits<long double>::max())));
498-
C((!issignaling(-std::numeric_limits<long double>::max())));
499-
C((!isnan (-std::numeric_limits<long double>::max())));
500-
C((!isinf (-std::numeric_limits<long double>::max())));
501-
C(( isfinite (-std::numeric_limits<long double>::max())));
502-
C(( isnormal (-std::numeric_limits<long double>::max())));
503-
C((!issubnormal(-std::numeric_limits<long double>::max())));
504-
C((!iszero (-std::numeric_limits<long double>::max())));
488+
C(( signbit (-std::numeric_limits<float>::max())));
489+
C((!issignaling(-std::numeric_limits<float>::max())));
490+
C((!isnan (-std::numeric_limits<float>::max())));
491+
C((!isinf (-std::numeric_limits<float>::max())));
492+
C(( isfinite (-std::numeric_limits<float>::max())));
493+
C(( isnormal (-std::numeric_limits<float>::max())));
494+
C((!issubnormal(-std::numeric_limits<float>::max())));
495+
C((!iszero (-std::numeric_limits<float>::max())));
496+
497+
C(( signbit (-std::numeric_limits<double>::max())));
498+
C((!issignaling(-std::numeric_limits<double>::max())));
499+
C((!isnan (-std::numeric_limits<double>::max())));
500+
C((!isinf (-std::numeric_limits<double>::max())));
501+
C(( isfinite (-std::numeric_limits<double>::max())));
502+
C(( isnormal (-std::numeric_limits<double>::max())));
503+
C((!issubnormal(-std::numeric_limits<double>::max())));
504+
C((!iszero (-std::numeric_limits<double>::max())));
505505

506506
C(( signbit (-std::numeric_limits<long double>::max())));
507507
C((!issignaling(-std::numeric_limits<long double>::max())));

0 commit comments

Comments
 (0)