diff --git a/emscripten-version.txt b/emscripten-version.txt index 6a10ff7aa230f..b7825b8d76746 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.28.1 +1.28.2 diff --git a/src/library.js b/src/library.js index 58fb51a4b2755..6a90ec4cfa28a 100644 --- a/src/library.js +++ b/src/library.js @@ -4531,8 +4531,6 @@ LibraryManager.library = { return divt; }, - __fpclassifyd: '__fpclassify', // Needed by tests/python/python.le32.bc - // ========================================================================== // sys/utsname.h // ========================================================================== diff --git a/system/lib/libc.symbols b/system/lib/libc.symbols index e47df094945b7..6254c69e42e11 100644 --- a/system/lib/libc.symbols +++ b/system/lib/libc.symbols @@ -46,6 +46,13 @@ T expm1 T expm1f T expm1l + T feclearexcept + T feraiseexcept + T fetestexcept + T fegetround + T __fesetround + T fegetenv + T fesetenv T fdim T fdimf T fdiml diff --git a/system/lib/libc/musl/src/fenv/fenv.c b/system/lib/libc/musl/src/fenv/fenv.c new file mode 100644 index 0000000000000..5588dad95f428 --- /dev/null +++ b/system/lib/libc/musl/src/fenv/fenv.c @@ -0,0 +1,38 @@ +#include + +/* Dummy functions for archs lacking fenv implementation */ + +int feclearexcept(int mask) +{ + return 0; +} + +int feraiseexcept(int mask) +{ + return 0; +} + +int fetestexcept(int mask) +{ + return 0; +} + +int fegetround(void) +{ + return FE_TONEAREST; +} + +int __fesetround(int r) +{ + return 0; +} + +int fegetenv(fenv_t *envp) +{ + return 0; +} + +int fesetenv(const fenv_t *envp) +{ + return 0; +} diff --git a/system/lib/libc/musl/src/math/__fpclassify.c b/system/lib/libc/musl/src/math/__fpclassify.c index f7c0e2dfac828..13866746f52f2 100644 --- a/system/lib/libc/musl/src/math/__fpclassify.c +++ b/system/lib/libc/musl/src/math/__fpclassify.c @@ -1,6 +1,11 @@ #include #include +#ifdef __EMSCRIPTEN__ +// XXX Emscripten: for weak_alias. +#include "libc.h" +#endif + int __fpclassify(double x) { union {double f; uint64_t i;} u = {x}; @@ -9,3 +14,8 @@ int __fpclassify(double x) if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE; return FP_NORMAL; } + +#ifdef __EMSCRIPTEN__ +// XXX Emscripten: Needed by tests/python/python.le32.bc +weak_alias(__fpclassify, __fpclassifyd); +#endif diff --git a/system/lib/libc/musl/src/math/sincos.c b/system/lib/libc/musl/src/math/sincos.c index 35b2d923968f1..6cfb9950418c0 100644 --- a/system/lib/libc/musl/src/math/sincos.c +++ b/system/lib/libc/musl/src/math/sincos.c @@ -13,6 +13,16 @@ #define _GNU_SOURCE #include "libm.h" +#ifdef __EMSCRIPTEN__ +#include + +// XXX Emscripten: Use the browser-optimized versions of sin and cos, since they are faster. +void sincos(double x, double *s, double *c) +{ + *s = sin(x); + *c = cos(x); +} +#else void sincos(double x, double *sin, double *cos) { double y[2], s, c; @@ -67,3 +77,4 @@ void sincos(double x, double *sin, double *cos) break; } } +#endif diff --git a/system/lib/libc/musl/src/math/sincosf.c b/system/lib/libc/musl/src/math/sincosf.c index f8ca7232cfb37..1d059de5f84bd 100644 --- a/system/lib/libc/musl/src/math/sincosf.c +++ b/system/lib/libc/musl/src/math/sincosf.c @@ -17,6 +17,10 @@ #define _GNU_SOURCE #include "libm.h" +#ifdef __EMSCRIPTEN__ +#include +#endif + /* Small multiples of pi/2 rounded to double precision. */ static const double s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ @@ -26,6 +30,11 @@ s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ void sincosf(float x, float *sin, float *cos) { +#ifdef __EMSCRIPTEN__ +// XXX Emscripten: Use the browser-optimized versions of sin and cos, since they are faster. + *sin = sinf(x); + *cos = cosf(x); +#else double y; float_t s, c; uint32_t ix; @@ -114,4 +123,5 @@ void sincosf(float x, float *sin, float *cos) *cos = s; break; } +#endif } diff --git a/system/lib/libc/musl/src/math/sincosl.c b/system/lib/libc/musl/src/math/sincosl.c index d3ac1c4c8c29e..3113e136cbf03 100644 --- a/system/lib/libc/musl/src/math/sincosl.c +++ b/system/lib/libc/musl/src/math/sincosl.c @@ -1,6 +1,18 @@ #define _GNU_SOURCE #include "libm.h" +#ifdef __EMSCRIPTEN__ +#include + +// XXX Emscripten: Use the browser-optimized versions of sin and cos, since they are faster. +void sincosl(long double x, long double *sin, long double *cos) +{ + *sin = sinl(x); + *cos = cosl(x); +} + +#else + #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 void sincosl(long double x, long double *sin, long double *cos) { @@ -58,3 +70,5 @@ void sincosl(long double x, long double *sin, long double *cos) } } #endif + +#endif diff --git a/tests/runner.py b/tests/runner.py index 61d49d74e5c84..50d2b3369733d 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -50,7 +50,7 @@ def nonfastcomp(test): # Core test runner class, shared between normal tests and benchmarks checked_sanity = False -test_modes = ['default', 'asm1', 'asm2', 'asm3', 'asm2f', 'asm2g', 'asm3i', 'slow2', 'slow2asm'] +test_modes = ['default', 'asm1', 'asm2', 'asm3', 'asm2f', 'asm2g', 'asm3i', 'asm2nn', 'slow2'] test_index = 0 class RunnerCore(unittest.TestCase): diff --git a/tests/test_core.py b/tests/test_core.py index e49c6a737b10c..1c3a0b74163c0 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -7270,8 +7270,8 @@ def setUp(self): asm3i = make_run("asm3i", compiler=CLANG, emcc_args=["-O3", '-s', 'EMTERPRETIFY=1']) # Legacy test modes - +asm2nn = make_run("asm2nn", compiler=CLANG, emcc_args=["-O2"], env={"EMCC_NATIVE_OPTIMIZER": "0"}) slow2 = make_run("slow2", compiler=CLANG, emcc_args=["-O2", "-s", "ASM_JS=0"], env={"EMCC_FAST_COMPILER": "0"}) -slow2asm = make_run("slow2asm", compiler=CLANG, emcc_args=["-O2"], env={"EMCC_FAST_COMPILER": "0"}) del T # T is just a shape for the specific subclasses, we don't test it itself diff --git a/tests/test_other.py b/tests/test_other.py index bd2598a368fdd..3b513d30d8b02 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -1943,16 +1943,41 @@ def test_js_optimizer(self): print ' js' output = Popen(NODE_JS + [path_from_root('tools', 'js-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] - def check_js(js): + def check_js(js, expected): + #print >> sys.stderr, 'chak\n==========================\n', js, '\n===========================\n' + if 'registerizeHarder' in passes: + # registerizeHarder is hard to test, as names vary by chance, nondeterminstically FIXME + def fix(src): + if type(src) is list: + return map(fix, src) + src = '\n'.join(filter(lambda line: 'var ' not in line, src.split('\n'))) # ignore vars + def reorder(func): + def swap(func, stuff): + # emit EYE_ONE always before EYE_TWO, replacing i1,i2 or i2,i1 etc + for i in stuff: + if i not in func: return func + indexes = map(lambda i: [i, func.index(i)], stuff) + indexes.sort(lambda x, y: x[1] - y[1]) + for j in range(len(indexes)): + func = func.replace(indexes[j][0], 'STD_' + str(j)) + return func + func = swap(func, ['i1', 'i2', 'i3']) + func = swap(func, ['i1', 'i2']) + func = swap(func, ['i4', 'i5']) + return func + src = 'function '.join(map(reorder, src.split('function '))) + return src + js = fix(js) + expected = fix(expected) self.assertIdentical(expected, js.replace('\r\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n')) - check_js(output) + check_js(output, expected) if js_optimizer.use_native(passes): # test calling native def check_json(): Popen(listify(NODE_JS) + [path_from_root('tools', 'js-optimizer.js'), output_temp, 'receiveJSON'], stdin=PIPE, stdout=open(output_temp + '.js', 'w')).communicate() output = open(output_temp + '.js').read() - self.assertIdentical(expected, output.replace('\r\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n')) + check_js(output, expected) self.clear() input_temp = 'temp.js' @@ -1976,7 +2001,7 @@ def check_json(): print ' native (emitting JS)' output = Popen([js_optimizer.get_native_optimizer(), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0] - check_js(output) + check_js(output, expected) def test_m_mm(self): open(os.path.join(self.get_dir(), 'foo.c'), 'w').write('''#include ''') @@ -4366,11 +4391,21 @@ def do_log_test(source, expected, func): assert func in pre, pre post = post.split('\n')[0] seen = int(post) - assert expected == seen, ['expect', expected, 'but see', seen] + print ' seen', seen + assert expected == seen or seen in expected, ['expect', expected, 'but see', seen] do_log_test(path_from_root('tests', 'primes.cpp'), 86, 'main') do_log_test(path_from_root('tests', 'fannkuch.cpp'), 234, 'fannkuch_worker') + # test non-native as well, registerizeHarder can be a little more efficient here + old_native = os.environ.get('EMCC_NATIVE_OPTIMIZER') + try: + os.environ['EMCC_NATIVE_OPTIMIZER'] = '0' + do_log_test(path_from_root('tests', 'fannkuch.cpp'), 234, 'fannkuch_worker') + finally: + if old_native: os.environ['EMCC_NATIVE_OPTIMIZER'] = old_native + else: del os.environ['EMCC_NATIVE_OPTIMIZER'] + def test_emterpreter_swap_orig(self): Popen([PYTHON, EMCC, path_from_root('tests', 'fasta.cpp'), '-s', 'EMTERPRETIFY=1', '-s', 'SWAPPABLE_ASM_MODULE=1', '-O2']).communicate() Popen([PYTHON, path_from_root('tools', 'distill_asm.py'), 'a.out.js.orig.js', 'second.js', 'swap-in']).communicate() diff --git a/tests/test_sanity.py b/tests/test_sanity.py index 02c0954bed90d..485a4a4af8b4e 100644 --- a/tests/test_sanity.py +++ b/tests/test_sanity.py @@ -619,7 +619,6 @@ def second_use(): def test_native_optimizer(self): restore() - Cache.erase() def build(): return self.check_working([EMCC, '-O2', 'tests/hello_world.c'], 'running js post-opts') @@ -633,12 +632,13 @@ def test(): # basic usage or lack of usage for native in [None, 0, 1]: print native + Cache.erase() try: if native is not None: os.environ['EMCC_NATIVE_OPTIMIZER'] = str(native) output = build() - assert ('js optimizer using native' in output) == (not not native) + assert ('js optimizer using native' in output) == (not not (native or native is None)) test() - if native: + if native or native is None: # None means use the default, which is to use the native optimizer assert 'building native optimizer' in output # compile again, no rebuild of optimizer output = build() @@ -653,42 +653,36 @@ def test(): Cache.erase() try: - os.environ['EMCC_NATIVE_OPTIMIZER'] = '1' - - try: - # break it - f = path_from_root('tools', 'optimizer', 'optimizer.cpp') - src = open(f).read() - bad = src.replace('main', '!waka waka<') - assert bad != src - open(f, 'w').write(bad) - # first try - output = build() - assert 'failed to build native optimizer' in output, output - assert 'js optimizer using native' not in output - test() # still works, without native optimizer - # second try, see previous failure - output = build() - assert 'failed to build native optimizer' not in output - assert 'seeing that optimizer could not be built' in output - test() # still works, without native optimizer - # clear cache, try again - Cache.erase() - output = build() - assert 'failed to build native optimizer' in output - test() # still works, without native optimizer - finally: - open(f, 'w').write(src) - + # break it + f = path_from_root('tools', 'optimizer', 'optimizer.cpp') + src = open(f).read() + bad = src.replace('main', '!waka waka<') + assert bad != src + open(f, 'w').write(bad) + # first try + output = build() + assert 'failed to build native optimizer' in output, output + assert 'js optimizer using native' not in output + test() # still works, without native optimizer + # second try, see previous failure + output = build() + assert 'failed to build native optimizer' not in output + assert 'seeing that optimizer could not be built' in output + test() # still works, without native optimizer + # clear cache, try again Cache.erase() - - # now it should work again output = build() - assert 'js optimizer using native' in output + assert 'failed to build native optimizer' in output test() # still works, without native optimizer - finally: - os.environ['EMCC_NATIVE_OPTIMIZER'] = '0' + open(f, 'w').write(src) + + Cache.erase() + + # now it should work again + output = build() + assert 'js optimizer using native' in output + test() # still works finally: del os.environ['EMCC_DEBUG'] diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py index e95bc27999274..4f86b90e339da 100644 --- a/tools/js_optimizer.py +++ b/tools/js_optimizer.py @@ -25,14 +25,14 @@ def path_from_root(*pathelems): func_sig_json = re.compile('\["defun", ?"([_\w$]+)",') import_sig = re.compile('var ([_\w$]+) *=[^;]+;') -NATIVE_OPTIMIZER = os.environ.get('EMCC_NATIVE_OPTIMIZER') +NATIVE_OPTIMIZER = os.environ.get('EMCC_NATIVE_OPTIMIZER') or '1' # use native optimizer by default, unless disabled by EMCC_NATIVE_OPTIMIZER=0 in the env def get_native_optimizer(): if os.environ.get('EMCC_FAST_COMPILER') == '0': return None # need fastcomp for native optimizer FAIL_MARKER = shared.Cache.get_path('optimizer.building_failed') if os.path.exists(FAIL_MARKER): - shared.logging.debug('seeing that optimizer could not be built') + shared.logging.debug('seeing that optimizer could not be built (run emcc --clear-cache or erase "optimizer.building_failed" in cache dir to retry)') return None def get_optimizer(name, args): diff --git a/tools/optimizer/optimizer.cpp b/tools/optimizer/optimizer.cpp index 4e3475e37a234..f8d41459ffcf3 100644 --- a/tools/optimizer/optimizer.cpp +++ b/tools/optimizer/optimizer.cpp @@ -516,7 +516,8 @@ Ref makeAsmCoercion(Ref node, AsmType type) { // Checks bool isEmpty(Ref node) { - return node->size() == 2 && node[0] == TOPLEVEL && node[1]->size() == 0; + return (node->size() == 2 && node[0] == TOPLEVEL && node[1]->size() == 0) || + (node->size() > 0 && node[0] == BLOCK && (!node[1] || node[1]->size() == 0)); } bool commable(Ref node) { // TODO: hashing @@ -664,7 +665,6 @@ void clearUselessNodes(Ref arr) { void removeAllEmptySubNodes(Ref ast) { traversePre(ast, [](Ref node) { - int index = -1; if (node[0] == DEFUN) { clearEmptyNodes(node[3]); } else if (node[0] == BLOCK && node->size() > 1 && !!node[1]) { @@ -675,15 +675,31 @@ void removeAllEmptySubNodes(Ref ast) { }); } void removeAllUselessSubNodes(Ref ast) { - traversePre(ast, [](Ref node) { - int index = -1; - if (node[0] == DEFUN) { + traversePrePost(ast, [](Ref node) { + Ref type = node[0]; + if (type == DEFUN) { clearUselessNodes(node[3]); - } else if (node[0] == BLOCK && node->size() > 1 && !!node[1]) { + } else if (type == BLOCK && node->size() > 1 && !!node[1]) { clearUselessNodes(node[1]); - } else if (node[0] == SEQ && isEmpty(node[1])) { + } else if (type == SEQ && isEmpty(node[1])) { safeCopy(node, node[2]); } + }, [](Ref node) { + Ref type = node[0]; + if (type == IF) { + bool empty2 = isEmpty(node[2]), has3 = node->size() == 4 && !!node[3], empty3 = !has3 || isEmpty(node[3]); + if (!empty2 && empty3 && has3) { // empty else clauses + node->setSize(3); + } else if (empty2 && !empty3) { // empty if blocks + safeCopy(node, make2(IF, make2(UNARY_PREFIX, L_NOT, node[1]), node[3])); + } else if (empty2 && empty3) { + if (hasSideEffects(node[1])) { + safeCopy(node, make1(STAT, node[1])); + } else { + safeCopy(node, makeEmpty()); + } + } + } }); } @@ -3329,7 +3345,9 @@ void registerizeHarder(Ref ast) { } std::sort(sortedJunctionVariables.begin(), sortedJunctionVariables.end(), [&](const IString name1, const IString name2) { //return strcmp(name1.str, name2.str) > 0;// XXX junctionVariables[name1].conf.size() > junctionVariables[name2].conf.size(); - return junctionVariables[name1].conf.size() < junctionVariables[name2].conf.size(); + if (junctionVariables[name1].conf.size() < junctionVariables[name2].conf.size()) return true; + if (junctionVariables[name1].conf.size() == junctionVariables[name2].conf.size()) return name1 < name2; + return false; }); // We can now assign a register to each junction variable. diff --git a/tools/optimizer/simple_ast.h b/tools/optimizer/simple_ast.h index 25cd1cc682b8a..b757c1a267d9e 100644 --- a/tools/optimizer/simple_ast.h +++ b/tools/optimizer/simple_ast.h @@ -943,8 +943,10 @@ struct JSPrinter { if (finalize && node[1] == PLUS && (node[2][0] == NUM || (node[2][0] == UNARY_PREFIX && node[2][1] == MINUS && node[2][2][0] == NUM))) { // emit a finalized number - char *curr = buffer + used; + int last = used; print(node[2]); + ensure(1); // we temporarily append a 0 + char *curr = buffer + last; // ensure might invalidate buffer[used] = 0; if (strchr(curr, '.')) return; // already a decimal point, all good char *e = strchr(curr, 'e'); @@ -953,6 +955,7 @@ struct JSPrinter { return; } ensure(3); + curr = buffer + last; // ensure might invalidate char *end = strchr(curr, 0); while (end >= e) { end[2] = end[0]; diff --git a/tools/system_libs.py b/tools/system_libs.py index 2b5e30f193b17..ca2a6d7ed1608 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -98,6 +98,9 @@ def create_libc(): 'isxdigit.c', 'tolower.c', ]], + ['fenv', [ + 'fenv.c' + ]], ['internal', [ 'intscan.c', 'floatscan.c', diff --git a/tools/test-js-optimizer-asm-regs-harder-output2.js b/tools/test-js-optimizer-asm-regs-harder-output2.js index 2b1e102d4b209..f82c7e63abbc3 100644 --- a/tools/test-js-optimizer-asm-regs-harder-output2.js +++ b/tools/test-js-optimizer-asm-regs-harder-output2.js @@ -8,13 +8,13 @@ function asm(d1, i2) { d1 = d1 * 5; return d1; } -function _doit(i3, i2, i1) { - i3 = i3 | 0; - i2 = i2 | 0; +function _doit(i1, i2, i3) { i1 = i1 | 0; - i3 = STACKTOP; - _printf(__str | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[(tempInt & 16777215) >> 2] = i2, HEAP32[(tempInt + 4 & 16777215) >> 2] = i1, tempInt)); - STACKTOP = i3; + i2 = i2 | 0; + i3 = i3 | 0; + i1 = STACKTOP; + _printf(__str | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[(tempInt & 16777215) >> 2] = i2, HEAP32[(tempInt + 4 & 16777215) >> 2] = i3, tempInt)); + STACKTOP = i1; return 0 | 0; } function stackRestore(i1) { @@ -38,20 +38,20 @@ function switchey(d1, i2) { } function switchey2() { var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, d6 = +0, d7 = +0; - i4 = STACKTOP; + i5 = STACKTOP; STACKTOP = STACKTOP + 8 | 0; i3 = 1; while (1) switch (i3 | 0) { case 1: - i5 = i4 | 0; - __ZN6RandomC1Ev(i5); + i4 = i5 | 0; + __ZN6RandomC1Ev(i4); i1 = 0; i2 = 0; i3 = 2; break; case 2: d7 = +__ZN6Random3getEf(8, +1); - d6 = +__ZN6Random3getEf(i5, +1); + d6 = +__ZN6Random3getEf(i4, +1); _printf(24, (tempInt = STACKTOP, STACKTOP = STACKTOP + 16 | 0, HEAPF64[CHECK_ALIGN_8(tempInt | 0) >> 3] = d7, HEAPF64[CHECK_ALIGN_8(tempInt + 8 | 0) >> 3] = d6, tempInt) | 0); i2 = (d7 != d6 & 1) + i2 | 0; i1 = i1 + 1 | 0; @@ -64,26 +64,26 @@ function switchey2() { } case 3: _printf(16, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[CHECK_ALIGN_4(tempInt | 0) >> 2] = i2, tempInt) | 0); - STACKTOP = i4; + STACKTOP = i5; return 0; } return 0; } function iffey() { var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, d6 = +0, d7 = +0; - i4 = STACKTOP; + i5 = STACKTOP; STACKTOP = STACKTOP + 8 | 0; i3 = 1; while (1) { if (i3 | 0) { - i5 = i4 | 0; - __ZN6RandomC1Ev(i5); + i4 = i5 | 0; + __ZN6RandomC1Ev(i4); i1 = 0; i2 = 0; i3 = 2; } else { d7 = +__ZN6Random3getEf(8, +1); - d6 = +__ZN6Random3getEf(i5, +1); + d6 = +__ZN6Random3getEf(i4, +1); _printf(24, (tempInt = STACKTOP, STACKTOP = STACKTOP + 16 | 0, HEAPF64[CHECK_ALIGN_8(tempInt | 0) >> 3] = d7, HEAPF64[CHECK_ALIGN_8(tempInt + 8 | 0) >> 3] = d6, tempInt) | 0); i2 = (d7 != d6 & 1) + i2 | 0; i1 = i1 + 1 | 0; @@ -96,42 +96,42 @@ function iffey() { } return 0; } -function labelledJump(i2) { - i2 = i2 | 0; - var i1 = 0, i3 = 0; - i1 = 2; - if (i2) { +function labelledJump(i1) { + i1 = i1 | 0; + var i2 = 0, i3 = 0; + i2 = 2; + if (i1) { i1 = 17; i3 = 1; } if (i3 == 1) { - i2 = i1 + 1; + i1 = i1 + 1; } else { - i2 = i1 + 1; + i1 = i2 + 1; } - return i2; + return i1; } function linkedVars() { var i1 = 0, i2 = 0; while (1) { - i2 = 9; - i1 = 5; - while (i2 > 0 | i1 > 0) { - if (i2 < i1) { - i2 = i2 - 1; - } else { + i1 = 9; + i2 = 5; + while (i1 > 0 | i2 > 0) { + if (i1 < i2) { i1 = i1 - 1; + } else { + i2 = i2 - 1; } } - if (i2 < i1) { + if (i1 < i2) { break; } } - return i2 + i1; + return i1 + i2; } -function deadCondExpr(i2) { - i2 = i2 | 0; - var i1 = 0; - return i1 | 0; +function deadCondExpr(i1) { + i1 = i1 | 0; + var i2 = 0; + return i2 | 0; } diff --git a/tools/test-js-optimizer-asm-regs-output.js b/tools/test-js-optimizer-asm-regs-output.js index c75bbcf74dab3..ca2f6069f8bd7 100644 --- a/tools/test-js-optimizer-asm-regs-output.js +++ b/tools/test-js-optimizer-asm-regs-output.js @@ -106,5 +106,20 @@ function iffey() { function nops() { var i1 = 0; f(i1); + if (cheez) { + doIt(); + } else { + doIt(); + } + if (cheez) { + doIt(); + } + if (!cheez) { + doIt(); + } + if (!cheez) { + doIt(); + } + doIt(); } diff --git a/tools/test-js-optimizer-asm-regs.js b/tools/test-js-optimizer-asm-regs.js index 9c5b49fd13056..a4d1fb96b2a0f 100644 --- a/tools/test-js-optimizer-asm-regs.js +++ b/tools/test-js-optimizer-asm-regs.js @@ -111,6 +111,23 @@ function nops() { x | 0; ~x; f(x); + // vaccuming + if (cheez) { + doIt(); + } else { + doIt(); + } + if (cheez) { + doIt(); + } else {} + if (cheez) {} else { + doIt(); + } + if (cheez) {} else { + doIt(); + } + if (cheez) {} else {} + if (doIt()) {} else {} } // EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "stackRestore", "switchey", "switchey2", "iffey", "nops"]