Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions system/lib/libc/musl/src/math/fmax.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ double fmax(double x, double y)
return y;
if (isnan(y))
return x;
// XXX EMSCRIPTEN: use wasm builtins for code size
#ifdef __wasm__
return __builtin_wasm_max_f64(x, y);
#else
/* handle signed zeros, see C99 Annex F.9.9.2 */
if (signbit(x) != signbit(y))
return signbit(x) ? y : x;
return x < y ? y : x;
#endif
}
5 changes: 5 additions & 0 deletions system/lib/libc/musl/src/math/fmaxf.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ float fmaxf(float x, float y)
return y;
if (isnan(y))
return x;
// XXX EMSCRIPTEN: use wasm builtins for code size
#ifdef __wasm__
return __builtin_wasm_max_f32(x, y);
#else
/* handle signed zeroes, see C99 Annex F.9.9.2 */
if (signbit(x) != signbit(y))
return signbit(x) ? y : x;
return x < y ? y : x;
#endif
}
5 changes: 5 additions & 0 deletions system/lib/libc/musl/src/math/fmin.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ double fmin(double x, double y)
return y;
if (isnan(y))
return x;
// XXX EMSCRIPTEN: use wasm builtins for code size
#ifdef __wasm__
return __builtin_wasm_min_f64(x, y);
#else
/* handle signed zeros, see C99 Annex F.9.9.2 */
if (signbit(x) != signbit(y))
return signbit(x) ? x : y;
return x < y ? x : y;
#endif
}
5 changes: 5 additions & 0 deletions system/lib/libc/musl/src/math/fminf.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ float fminf(float x, float y)
return y;
if (isnan(y))
return x;
// XXX EMSCRIPTEN: use wasm builtins for code size
#ifdef __wasm__
return __builtin_wasm_min_f32(x, y);
#else
/* handle signed zeros, see C99 Annex F.9.9.2 */
if (signbit(x) != signbit(y))
return signbit(x) ? x : y;
return x < y ? x : y;
#endif
}
35 changes: 33 additions & 2 deletions tests/core/test_floatvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,45 @@
#include <cfloat>
#include <cmath>

#define TEST(name, x, y) printf(" " #name "(%.2f, %.2f) => %.2f, %.2f\n", x, y, name(x, y), name(y, x));
#define TEST_ABS(name, x, y) printf("abs " #name "(%.2f, %.2f) => %.2f, %.2f\n", x, y, abs(name(x, y)), abs(name(y, x)));

// fmin etc. are not specced to be sensitive to negative zero, and LLVM does
// depend on that for optimizations, so check only the absolute value there
#define TESTS(name) \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yay macros that make things easier to read :)

TEST(name, 0.33, 0.5) \
TEST(name, NAN, 0.5) \
TEST_ABS(name, 0.0, -0.0)

// when calling via a function pointer, the LLVM optimizer isn't involved, and
// the libc implementation does handle negative zero as you'd expect
#define PTR_TESTS(name, ptr) \
puts("ptr " #name); \
ptr = &name; \
TEST(ptr, 0.33, 0.5) \
TEST(ptr, NAN, 0.5) \
TEST(ptr, 0.0, -0.0)

// make it look like these are externally modifiable so the optimizer doesn't
// trivially remove the function pointer
double (*funcd)(double, double);
float (*funcf)(float, float);

int main(int argc, char **argv) {
float x = 1.234, y = 3.5, q = 0.00000001;
y *= 3;
int z = x < y;
printf("*%d,%d,%.1f,%d,%.4f,%.2f*\n", z, int(y), y, (int)x, x, q);

printf("%.2f, %.2f, %.2f, %.2f\n", fmin(0.5, 3.3), fmin(NAN, 3.3),
fmax(0.5, 3.3), fmax(NAN, 3.3));
TESTS(fmin);
TESTS(fmax);
TESTS(fminf);
TESTS(fmaxf);

PTR_TESTS(fmin, funcd);
PTR_TESTS(fmax, funcd);
PTR_TESTS(fminf, funcf);
PTR_TESTS(fmaxf, funcf);

printf("small: %.10f\n", argc * 0.000001);

Expand Down
29 changes: 28 additions & 1 deletion tests/core/test_floatvars.out
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
*1,10,10.5,1,1.2340,0.00*
0.50, 3.30, 3.30, 3.30
fmin(0.33, 0.50) => 0.33, 0.33
fmin(nan, 0.50) => 0.50, 0.50
abs fmin(0.00, -0.00) => 0.00, 0.00
fmax(0.33, 0.50) => 0.50, 0.50
fmax(nan, 0.50) => 0.50, 0.50
abs fmax(0.00, -0.00) => 0.00, 0.00
fminf(0.33, 0.50) => 0.33, 0.33
fminf(nan, 0.50) => 0.50, 0.50
abs fminf(0.00, -0.00) => 0.00, 0.00
fmaxf(0.33, 0.50) => 0.50, 0.50
fmaxf(nan, 0.50) => 0.50, 0.50
abs fmaxf(0.00, -0.00) => 0.00, 0.00
ptr fmin
funcd(0.33, 0.50) => 0.33, 0.33
funcd(nan, 0.50) => 0.50, 0.50
funcd(0.00, -0.00) => -0.00, -0.00
ptr fmax
funcd(0.33, 0.50) => 0.50, 0.50
funcd(nan, 0.50) => 0.50, 0.50
funcd(0.00, -0.00) => 0.00, 0.00
ptr fminf
funcf(0.33, 0.50) => 0.33, 0.33
funcf(nan, 0.50) => 0.50, 0.50
funcf(0.00, -0.00) => -0.00, -0.00
ptr fmaxf
funcf(0.33, 0.50) => 0.50, 0.50
funcf(nan, 0.50) => 0.50, 0.50
funcf(0.00, -0.00) => 0.00, 0.00
small: 0.0000010000
double: 1123456789012345651200.000000