Skip to content

Commit 7bd7231

Browse files
committed
Added hypot3 and header conflict tests
1 parent 32e0569 commit 7bd7231

File tree

8 files changed

+205
-7
lines changed

8 files changed

+205
-7
lines changed

src/libc/header_test.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <alloca.h>
2+
#include <assert.h>
3+
#include <byteswap.h>
4+
#include <cdefs.h>
5+
#include <ctype.h>
6+
#include <errno.h>
7+
#include <fenv.h>
8+
#include <float.h>
9+
#include <inttypes.h>
10+
#include <iso646.h>
11+
#include <limits.h>
12+
#include <math.h>
13+
#include <setjmp.h>
14+
#include <stdalign.h>
15+
#include <stdarg.h>
16+
#include <stdbool.h>
17+
#include <stddef.h>
18+
#include <stdint.h>
19+
#include <stdio.h>
20+
#include <stdlib.h>
21+
#include <stdnoreturn.h>
22+
#include <string.h>
23+
#include <tgmath.h>
24+
#include <time.h>
25+
#include <wchar.h>
26+
27+
/* Tests for conflicts */

src/libc/hypot3f.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
typedef union F32_pun {
5+
float flt;
6+
uint32_t bin;
7+
} F32_pun;
8+
9+
float __hypot3f(float arg_x, float arg_y, float arg_z) {
10+
F32_pun x, y, z;
11+
x.flt = fabsf(arg_x);
12+
y.flt = fabsf(arg_y);
13+
z.flt = fabsf(arg_z);
14+
if (y.bin < z.bin) {
15+
float temp = y.flt;
16+
y.flt = z.flt;
17+
z.flt = temp;
18+
}
19+
if (x.bin < y.bin) {
20+
float temp = x.flt;
21+
x.flt = y.flt;
22+
y.flt = temp;
23+
}
24+
// x >= y && x >= z, or x is NaN
25+
if (isfinite(x.flt)) {
26+
int expon;
27+
// scale the arguments to prevent overflow/underflow
28+
x.flt = frexpf(x.flt, &expon);
29+
y.flt = ldexpf(y.flt, -expon);
30+
z.flt = ldexpf(z.flt, -expon);
31+
// evaluating in this order ensures consistency when arguments are swapped
32+
float ret = sqrtf(x.flt * x.flt + (y.flt * y.flt + z.flt * z.flt));
33+
return ldexpf(ret, expon);
34+
}
35+
if (isinf(y.flt) || isinf(z.flt)) {
36+
// return infinity, even if the other argument is NaN
37+
return HUGE_VALF;
38+
}
39+
// x is infinity/NaN
40+
return x.flt;
41+
}
42+
43+
double __hypot3(double, double, double) __attribute__((alias("__hypot3f")));

src/libc/hypot3l.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
typedef union F64_pun {
5+
long double flt;
6+
uint64_t bin;
7+
} F64_pun;
8+
9+
long double __hypot3l(long double arg_x, long double arg_y, long double arg_z) {
10+
F64_pun x, y, z;
11+
x.flt = fabsl(arg_x);
12+
y.flt = fabsl(arg_y);
13+
z.flt = fabsl(arg_z);
14+
if (y.bin < z.bin) {
15+
long double temp = y.flt;
16+
y.flt = z.flt;
17+
z.flt = temp;
18+
}
19+
if (x.bin < y.bin) {
20+
long double temp = x.flt;
21+
x.flt = y.flt;
22+
y.flt = temp;
23+
}
24+
// x >= y && x >= z, or x is NaN
25+
if (isfinite(x.flt)) {
26+
int expon;
27+
// scale the arguments to prevent overflow/underflow
28+
x.flt = frexpl(x.flt, &expon);
29+
y.flt = ldexpl(y.flt, -expon);
30+
z.flt = ldexpl(z.flt, -expon);
31+
// evaluating in this order ensures consistency when arguments are swapped
32+
long double ret = sqrtl(x.flt * x.flt + (y.flt * y.flt + z.flt * z.flt));
33+
return ldexpl(ret, expon);
34+
}
35+
if (isinf(y.flt) || isinf(z.flt)) {
36+
// return infinity, even if the other argument is NaN
37+
return HUGE_VALL;
38+
}
39+
// x is infinity/NaN
40+
return x.flt;
41+
}

src/libc/include/math.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ double hypot(double, double);
255255
float hypotf(float, float);
256256
long double hypotl(long double, long double);
257257

258+
double __hypot3(double, double, double);
259+
float __hypot3f(float, float, float);
260+
long double __hypot3l(long double, long double, long double);
261+
258262
int ilogb(double);
259263
int ilogbf(float);
260264
int ilogbl(long double);

src/libc/include/tgmath.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <math.h>
1111

12+
1213
#define __tgmath_promote(x) _Generic((x), \
1314
float: ((float)0.f), \
1415
default: ((double)0.), \
@@ -301,12 +302,6 @@
301302
float: fmodf \
302303
)((x), (y))
303304

304-
#define hypot(x, y) _Generic(__tgmath_promote(x) + __tgmath_promote(y), \
305-
long double: hypotl, \
306-
default: hypot, \
307-
float: hypotf \
308-
)((x), (y))
309-
310305
#define nextafter(x, y) _Generic(__tgmath_promote(x) + __tgmath_promote(y), \
311306
long double: nextafterl, \
312307
default: nextafter, \
@@ -369,6 +364,27 @@
369364
float: scalbnf \
370365
)((x), (y))
371366

367+
/* hypot */
368+
369+
#define __tgmath_hypot2(x, y) _Generic(__tgmath_promote(x) + __tgmath_promote(y), \
370+
long double: hypotl, \
371+
default: hypot, \
372+
float: hypotf \
373+
)((x), (y))
374+
375+
#define __tgmath_hypot3(x, y, z) _Generic(__tgmath_promote(x) + __tgmath_promote(y) + __tgmath_promote(z), \
376+
long double: __hypot3l, \
377+
default: __hypot3, \
378+
float: __hypot3f \
379+
)((x), (y), (z))
380+
381+
#define __tgmath_hypot2(x,y)2
382+
#define __tgmath_hypot3(x,y,z)3
383+
#define __tgmath_hypot_count(_1,_2,_3,count,...)count
384+
#define __tgmath_JOIN2(X,Y)X##Y
385+
#define __tgmath_CONCAT(X,Y)__tgmath_JOIN2(X,Y)
386+
#define hypot(...)__tgmath_CONCAT(__tgmath_hypot,__tgmath_hypot_count(__VA_ARGS__,3,2,))(__VA_ARGS__)
387+
372388
#endif /* __cplusplus */
373389

374390
#endif /* _TGMATH_H */

src/libcxx/header_test.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <__config>
2+
#include <bit>
3+
#include <cassert>
4+
#include <cctype>
5+
#include <cerrno>
6+
#include <cfloat>
7+
#include <cinttypes>
8+
#include <ciso646>
9+
#include <climits>
10+
#include <cmath>
11+
#if __cplusplus >= 201907L
12+
#include <concepts>
13+
#endif // __cplusplus >= 201907L
14+
#include <csetjmp>
15+
#include <cstdalign>
16+
#include <cstdbool>
17+
#include <cstddef>
18+
#include <cstdint>
19+
#include <cstdio>
20+
#include <cstdlib>
21+
#include <cstring>
22+
#include <ctime>
23+
#include <ctgmath>
24+
#include <cxxabi.h>
25+
#include <exception>
26+
#include <initializer_list>
27+
#include <limits>
28+
#include <new>
29+
#include <numbers>
30+
#include <type_traits>
31+
#include <typeinfo>
32+
#include <utility>
33+
#include <version>
34+
35+
#include <alloca.h>
36+
#include <assert.h>
37+
#include <byteswap.h>
38+
#include <cdefs.h>
39+
#include <ctype.h>
40+
#include <errno.h>
41+
#include <fenv.h>
42+
#include <float.h>
43+
#include <inttypes.h>
44+
#include <iso646.h>
45+
#include <limits.h>
46+
#include <math.h>
47+
#include <setjmp.h>
48+
#include <stdalign.h>
49+
#include <stdarg.h>
50+
#include <stdbool.h>
51+
#include <stddef.h>
52+
#include <stdint.h>
53+
#include <stdio.h>
54+
#include <stdlib.h>
55+
#include <stdnoreturn.h>
56+
#include <string.h>
57+
#include <tgmath.h>
58+
#include <time.h>
59+
#include <wchar.h>
60+
61+
// tests for conflicts

src/libcxx/include/cmath

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ template<typename _Tp, typename _Up> inline constexpr enable_if_t<is_integral_v<
238238
is_integral_v<_Up>, double>
239239
hypot(_Tp __x, _Up __y) { return hypot(__x, __y); }
240240

241+
inline float hypot(float __x, float __y, float __z) { return __hypot3f(__x, __y, __z); }
242+
inline long double hypot(long double __x, long double __y, long double __z) { __hypot3l(__x, __y, __z); }
243+
template<typename _Tp, typename _Up, typename _Vp>
244+
inline enable_if_t<is_integral_v<_Tp> && is_integral_v<_Up> && is_integral_v<_Vp>, double>
245+
hypot(_Tp __x, _Up __y, _Vp __z) { return __hypot3(__x, __y, __z); }
246+
241247
using ::ilogb;
242248
using ::ilogbf;
243249
using ::ilogbl;

src/libcxx/include/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
// # define __cpp_lib_gcd_lcm 201606L
5555
// # define __cpp_lib_hardware_interference_size 201703L
5656
// # define __cpp_lib_has_unique_object_representations 201606L
57-
// # define __cpp_lib_hypot 201603L
57+
# define __cpp_lib_hypot 201603L
5858
// # define __cpp_lib_incomplete_container_elements 201505L
5959
// # define __cpp_lib_invoke 201411L
6060
// # define __cpp_lib_is_aggregate 201703L

0 commit comments

Comments
 (0)