diff --git a/emscripten-version.txt b/emscripten-version.txt index 29eea1738741e..dc4e162b4c020 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -"1.36.6" +"1.36.7" diff --git a/emscripten.py b/emscripten.py index 943f535d556eb..265cc9eeea36d 100755 --- a/emscripten.py +++ b/emscripten.py @@ -554,7 +554,7 @@ def make_emulated_param(i): for sig in last_forwarded_json['Functions']['tables']: asm_setup += '\nvar debug_table_' + sig + ' = ' + json.dumps(debug_tables[sig]) + ';' - maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul', 'min', 'clz32']] + maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul', 'min', 'max', 'clz32']] simdfloattypes = [] simdinttypes = [] simdbooltypes = [] diff --git a/src/library.js b/src/library.js index 6970ebfb9a7d3..38f6a05a6e60b 100644 --- a/src/library.js +++ b/src/library.js @@ -1374,6 +1374,14 @@ LibraryManager.library = { llvm_floor_f32: 'Math_floor', llvm_floor_f64: 'Math_floor', + llvm_copysign_f32: function(x, y) { + return y < 0 || (y === 0 && 1/y < 0) ? -Math_abs(x) : Math_abs(x); + }, + + llvm_copysign_f64: function(x, y) { + return y < 0 || (y === 0 && 1/y < 0) ? -Math_abs(x) : Math_abs(x); + }, + round__asm: true, round__sig: 'dd', round: function(d) { @@ -4062,6 +4070,8 @@ LibraryManager.library = { llvm_dbg_value: true, llvm_debugtrap: true, llvm_ctlz_i32: true, + llvm_maxnum_f32: true, + llvm_maxnum_f64: true, emscripten_asm_const: true, emscripten_asm_const_int: true, emscripten_asm_const_double: true, diff --git a/tests/core/test_negative_zero.in b/tests/core/test_negative_zero.in index 395f84ce5ec00..045bd2f709a66 100644 --- a/tests/core/test_negative_zero.in +++ b/tests/core/test_negative_zero.in @@ -1,6 +1,24 @@ #include #include +// test copysign of 0 +int __attribute__((noinline,noclone)) +copysign_bug (double x) +{ + if (x != 0.0 && (x * 0.5 == x)) { + printf("1\n"); + return 1; + } + printf("f: %f\n", x); + if (__builtin_copysign(1.0, x) < 0.0) { + printf("2\n"); + return 2; + } else { + printf("3\n"); + return 3; + } +} + int main() { #define TEST(x, y) printf("%.2f, %.2f ==> %.2f\n", x, y, copysign(x, y)); TEST(5.0f, 5.0f); @@ -23,5 +41,10 @@ int main() { TEST(0.0f, -0.0f); TEST(-0.0f, 0.0f); TEST(-0.0f, -0.0f); + + double x = -0.0; + if (copysign_bug (x) != 2) + __builtin_abort (); + return 0; } diff --git a/tests/core/test_negative_zero.out b/tests/core/test_negative_zero.out index 5d792ffbea992..71ac79b2883a9 100644 --- a/tests/core/test_negative_zero.out +++ b/tests/core/test_negative_zero.out @@ -18,3 +18,5 @@ 0.00, -0.00 ==> -0.00 -0.00, 0.00 ==> 0.00 -0.00, -0.00 ==> -0.00 +f: -0.000000 +2 diff --git a/tests/core/test_struct_varargs.c b/tests/core/test_struct_varargs.c index a1fd3bff7a333..2e2a56247cda4 100644 --- a/tests/core/test_struct_varargs.c +++ b/tests/core/test_struct_varargs.c @@ -1,5 +1,6 @@ #include #include +#include struct A { int x; @@ -21,7 +22,7 @@ void foo(int unused, ...) printf("%f\n", b.x); } -int main() { +void a() { struct A a = { .x = 42, }; @@ -29,6 +30,42 @@ int main() { .x = 42.314, }; foo(0, a, b); - return 0; +} + +struct tiny +{ + short c; +}; + +void f (int n, ...) +{ + struct tiny x; + int i; + va_list ap; + va_start (ap,n); + for (i = 0; i < n; i++) + { + x = va_arg (ap,struct tiny); + printf("%d : %d\n", i, x.c); + if (x.c != i + 10) abort(); + } + va_end (ap); +} + +void b () +{ + struct tiny x[3]; + struct tiny y; + printf("sizeof tiny: %d (3 of them: %d)\n", sizeof(y), sizeof(x)); + x[0].c = 10; + x[1].c = 11; + x[2].c = 12; + f (3, x[0], x[1], x[2]); +} + +int main() { + a(); + b(); + printf("ok.\n"); } diff --git a/tests/core/test_struct_varargs.out b/tests/core/test_struct_varargs.out index 7cd08beb34c25..f6214ba1c9a8e 100644 --- a/tests/core/test_struct_varargs.out +++ b/tests/core/test_struct_varargs.out @@ -1,2 +1,7 @@ 42 42.314000 +sizeof tiny: 2 (3 of them: 6) +0 : 10 +1 : 11 +2 : 12 +ok. diff --git a/tests/test_core.py b/tests/test_core.py index 02b3cf1c0e9a3..01f6c5c685291 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -2424,7 +2424,7 @@ def test_ssr(self): # struct self-ref struct opj_mqc_state *nlps; } opj_mqc_state_t; - static opj_mqc_state_t mqc_states[2] = { + static opj_mqc_state_t mqc_states[4] = { {0x5600, 0, &mqc_states[2], &mqc_states[3]}, {0x5602, 1, &mqc_states[3], &mqc_states[2]}, }; @@ -5344,6 +5344,7 @@ def test_istream(self): @no_wasm def test_fs_base(self): + if self.is_wasm(): return self.skip('wasm libc overlaps js lib, so no INCLUDE_FULL_LIBRARY') Settings.INCLUDE_FULL_LIBRARY = 1 try: addJS = ''' @@ -5970,6 +5971,13 @@ def test_sse1(self): self.emcc_args = orig_args + mode + ['-msse'] self.do_run(open(path_from_root('tests', 'test_sse1.cpp'), 'r').read(), 'Success!') + # ignore nans in some simd tests due to an LLVM regression still being investigated, + # https://github.com/kripken/emscripten/issues/4435 + # https://llvm.org/bugs/show_bug.cgi?id=28510 + @staticmethod + def ignore_nans(out, err = ''): + return '\n'.join(filter(lambda x: 'NaN' not in x, (out + '\n' + err).split('\n'))) + # Tests the full SSE1 API. @SIMD def test_sse1_full(self): @@ -5981,7 +5989,7 @@ def test_sse1_full(self): orig_args = self.emcc_args for mode in [[], ['-s', 'SIMD=1']]: self.emcc_args = orig_args + mode + ['-I' + path_from_root('tests'), '-msse'] - self.do_run(open(path_from_root('tests', 'test_sse1_full.cpp'), 'r').read(), native_result) + self.do_run(open(path_from_root('tests', 'test_sse1_full.cpp'), 'r').read(), self.ignore_nans(native_result), output_nicerizer=self.ignore_nans) # Tests the full SSE2 API. @SIMD @@ -6001,7 +6009,7 @@ def test_sse2_full(self): orig_args = self.emcc_args for mode in [[], ['-s', 'SIMD=1']]: self.emcc_args = orig_args + mode + ['-I' + path_from_root('tests'), '-msse2'] + args - self.do_run(open(path_from_root('tests', 'test_sse2_full.cpp'), 'r').read(), native_result) + self.do_run(open(path_from_root('tests', 'test_sse2_full.cpp'), 'r').read(), self.ignore_nans(native_result), output_nicerizer=self.ignore_nans) # Tests the full SSE3 API. @SIMD @@ -6506,9 +6514,9 @@ def image_compare(output, err): image_mean = 83.265 #print '[image stats:', js_mean, image_mean, true_mean, diff_mean, num, ']' - assert abs(js_mean - image_mean) < 0.01 - assert abs(true_mean - image_mean) < 0.01 - assert diff_mean < 0.01 + assert abs(js_mean - image_mean) < 0.01, [js_mean, image_mean] + assert abs(true_mean - image_mean) < 0.01, [true_mean, image_mean] + assert diff_mean < 0.01, diff_mean return output @@ -6670,6 +6678,7 @@ def test_cases(self): def test_fuzz(self): Building.COMPILER_TEST_OPTS += ['-I' + path_from_root('tests', 'fuzz', 'include'), '-w'] + Settings.BINARYEN_IMPRECISE = 0 # some of these tests - 2.c', '9.c', '19.c', '21.c', '20.cpp' - div or rem i32 by 0, which traps in wasm def run_all(x): print x