Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ lint.ignore = [
"PLW0603",
"PLW1510",
"PLW2901",
"PLC0415",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this supposed to be part of this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i tried to run tests locally and The errors were: W293 and PLC0415 so thats why i include that import.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You are likely using a different version of ruff. You can use pip install -f requireents-dev.txt to install the one we use. Or you can just revert this line an re-upload?

"UP030", # TODO
"UP031", # TODO
"UP032", # TODO
Expand Down
5 changes: 5 additions & 0 deletions src/settings_internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ var ASYNCIFY_IMPORTS_EXCEPT_JS_LIBS = [];

var WARN_DEPRECATED = true;

// Enable fast math optimizations in wasm-opt when -ffast-math is passed.
// This enables aggressive floating-point optimizations that may violate
// IEEE 754 semantics but can improve performance.
var FAST_MATH = 0;

// WebGL 2 provides new garbage-free entry points to call to WebGL. Use
// those always when possible.
// We currently set this to false for certain browser when large memory sizes
Expand Down
47 changes: 47 additions & 0 deletions test/other/test_fast_math.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <math.h>
#include <stdio.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you can delete this file now.


static double mandelbrot_iter(double cx, double cy, int max_iter) {
double x = 0.0, y = 0.0;
for (int i = 0; i < max_iter; i++) {
if (x*x + y*y > 4.0) return (double)i;
double tx = x*x - y*y + cx;
y = 2.0*x*y + cy;
x = tx;
}
return (double)max_iter;
}

static double newton_raphson(double x, int iterations) {
for (int i = 0; i < iterations; i++) {
double fx = x*x*x - x - 1.0;
double fpx = 3.0*x*x - 1.0;
if (fabs(fpx) < 1e-10) break;
x = x - fx / fpx;
}
return x;
}

int main() {
double result = 0.0;

for (int i = 0; i < 100; i++) {
double x = (i - 50) * 0.02;
for (int j = 0; j < 100; j++) {
double y = (j - 50) * 0.02;
result += mandelbrot_iter(x, y, 50);
}
}

for (int i = 0; i < 50; i++) {
result += newton_raphson(1.5 + i * 0.1, 20);
}

for (int i = 0; i < 1000; i++) {
double angle = i * 0.01;
result += sin(angle) * cos(angle) + tan(angle);
}

printf("Result: %f\n", result);
return 0;
}
17 changes: 17 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -15796,3 +15796,20 @@ def has_defined_function(file, func):
self.assertIn('main.cpp', out)
self.assertIn('foo.cpp', out)
self.assertIn('/emsdk/emscripten/system/lib/libc/musl/src/string/strcmp.c', out)

def test_binaryen_fast_math(self):
# Use a simple input; contents don't matter for -v flag inspection
err = self.run_process([EMCC, test_file('hello_world.c'), '-v', '-O2', '-ffast-math'], stderr=PIPE).stderr
self.assertContained('--fast-math', err)

err_no_fast = self.run_process([EMCC, test_file('hello_world.c'), '-v', '-O2'], stderr=PIPE).stderr
self.assertNotContained('--fast-math', err_no_fast)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like a missing newline here


def test_fast_math(self):
self.run_process([EMCC, test_file('other/test_fast_math.c'), '-O2', '-o', 'no_fast.wasm'])
no_fast_size = os.path.getsize('no_fast.wasm')
self.run_process([EMCC, test_file('other/test_fast_math.c'), '-O2', '-ffast-math', '-o', 'with_fast.wasm'])
with_fast_size = os.path.getsize('with_fast.wasm')
print(f'no_fast_size={no_fast_size} with_fast_size={with_fast_size}')

self.assertLessEqual(with_fast_size, no_fast_size)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this need to be assertLess doesn't it? Otherwise there could be no upside and the test would still pass?

7 changes: 4 additions & 3 deletions tools/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,8 @@ def consume_arg_file():
settings.SHRINK_LEVEL = 0
settings.DEBUG_LEVEL = max(settings.DEBUG_LEVEL, 1)
elif requested_level == 'fast':
# TODO(https://github.com/emscripten-core/emscripten/issues/21497):
# If we ever map `-ffast-math` to `wasm-opt --fast-math` then
# then we should enable that too here.
# -Ofast typically includes -ffast-math semantics
settings.FAST_MATH = 1
requested_level = 3
settings.SHRINK_LEVEL = 0
else:
Expand Down Expand Up @@ -545,6 +544,8 @@ def consume_arg_file():
settings.WASM_EXCEPTIONS = 1
elif arg == '-fignore-exceptions':
settings.DISABLE_EXCEPTION_CATCHING = 1
elif arg == '-ffast-math':
settings.FAST_MATH = 1
elif check_arg('--default-obj-ext'):
exit_with_error('--default-obj-ext is no longer supported by emcc')
elif arg.startswith('-fsanitize=cfi'):
Expand Down
2 changes: 2 additions & 0 deletions tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ def get_binaryen_passes():
passes += ['--pass-arg=post-emscripten-side-module']
if optimizing:
passes += [building.opt_level_to_str(settings.OPT_LEVEL, settings.SHRINK_LEVEL)]
if settings.FAST_MATH:
passes += ['--fast-math']
# when optimizing, use the fact that low memory is never used (1024 is a
# hardcoded value in the binaryen pass). we also cannot do it when the stack
# is first, as then the stack is in the low memory that should be unused.
Expand Down