aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc13
-rw-r--r--tests/test_other.py2
-rw-r--r--tools/js-optimizer.js18
-rw-r--r--tools/test-js-optimizer-asm-last-output.js2
-rw-r--r--tools/test-js-optimizer-asm-pre-f32.js11
-rw-r--r--tools/test-js-optimizer-asm-pre-output-f32.js11
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js19
-rw-r--r--tools/test-js-optimizer-asm-pre.js22
8 files changed, 88 insertions, 10 deletions
diff --git a/emcc b/emcc
index 3c427677..490e6408 100755
--- a/emcc
+++ b/emcc
@@ -1967,16 +1967,23 @@ try:
if len(js_optimizer_extra_info) == 0:
js_optimizer_extra_info = None
if len(js_optimizer_queue) > 0 and not(not shared.Settings.ASM_JS and len(js_optimizer_queue) == 1 and js_optimizer_queue[0] == 'last'):
- if DEBUG != '2':
+
+ def add_opt_args(args):
if shared.Settings.ASM_JS:
- js_optimizer_queue = ['asm'] + js_optimizer_queue
+ args = ['asm'] + args
+ if shared.Settings.PRECISE_F32:
+ args = ['asmPreciseF32'] + args
+ return args
+
+ if DEBUG != '2':
+ js_optimizer_queue = add_opt_args(js_optimizer_queue)
logging.debug('applying js optimization passes: %s', js_optimizer_queue)
final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache, debug_level >= 4, js_optimizer_extra_info)
js_transform_tempfiles.append(final)
if DEBUG: save_intermediate('js_opts')
else:
for name in js_optimizer_queue:
- passes = [name]
+ passes = add_opt_args([name])
if shared.Settings.ASM_JS:
passes = ['asm'] + passes
logging.debug('applying js optimization pass: %s', passes)
diff --git a/tests/test_other.py b/tests/test_other.py
index bc05826e..47d26416 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -1779,6 +1779,8 @@ f.close()
['asm', 'registerize', 'minifyLocals']),
(path_from_root('tools', 'test-js-optimizer-asm-pre.js'), open(path_from_root('tools', 'test-js-optimizer-asm-pre-output.js')).read(),
['asm', 'simplifyExpressions']),
+ (path_from_root('tools', 'test-js-optimizer-asm-pre-f32.js'), open(path_from_root('tools', 'test-js-optimizer-asm-pre-output-f32.js')).read(),
+ ['asm', 'asmPreciseF32', 'simplifyExpressions']),
(path_from_root('tools', 'test-js-optimizer-asm-last.js'), open(path_from_root('tools', 'test-js-optimizer-asm-last-output.js')).read(),
['asm', 'last']),
(path_from_root('tools', 'test-js-optimizer-asm-relocate.js'), open(path_from_root('tools', 'test-js-optimizer-asm-relocate-output.js')).read(),
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 21d521fd..6724e77f 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -722,14 +722,19 @@ function simplifyExpressions(ast) {
if (correct === 'HEAP32') {
define[3] = ['binary', '|', define[3], ['num', 0]];
} else {
- define[3] = ['unary-prefix', '+', define[3]];
+ define[3] = makeAsmCoercion(define[3], asmPreciseF32 ? ASM_FLOAT : ASM_DOUBLE);
}
// do we want a simplifybitops on the new values here?
});
info.uses.forEach(function(use) {
use[2][1][1] = correct;
});
- asmData.vars[v] = 1 - asmData.vars[v];
+ var correctType;
+ switch(asmData.vars[v]) {
+ case ASM_INT: correctType = asmPreciseF32 ? ASM_FLOAT : ASM_DOUBLE; break;
+ case ASM_FLOAT: case ASM_DOUBLE: correctType = ASM_INT; break;
+ }
+ asmData.vars[v] = correctType;
}
}
denormalizeAsm(ast, asmData);
@@ -1138,7 +1143,9 @@ function optimizeShiftsAggressive(ast) {
// or such. Simplifying these saves space and time.
function simplifyNotCompsDirect(node) {
if (node[0] === 'unary-prefix' && node[1] === '!') {
- if (node[2][0] === 'binary') {
+ // de-morgan's laws do not work on floats, due to nans >:(
+ if (node[2][0] === 'binary' && (!asm || (((node[2][2][0] === 'binary' && node[2][2][1] === '|') || node[2][2][0] === 'num') &&
+ ((node[2][3][0] === 'binary' && node[2][3][1] === '|') || node[2][3][0] === 'num')))) {
switch(node[2][1]) {
case '<': return ['binary', '>=', node[2][2], node[2][3]];
case '>': return ['binary', '<=', node[2][2], node[2][3]];
@@ -1577,7 +1584,7 @@ function makeAsmVarDef(v, type) {
case ASM_INT: return [v, ['num', 0]];
case ASM_DOUBLE: return [v, ['unary-prefix', '+', ['num', 0]]];
case ASM_FLOAT: return [v, ['call', ['name', 'Math_fround'], [['num', 0]]]];
- default: throw 'wha?';
+ default: throw 'wha? ' + JSON.stringify([node, type]) + new Error().stack;
}
}
@@ -5153,7 +5160,7 @@ function asmLastOpts(ast) {
// Passes table
-var minifyWhitespace = false, printMetadata = true, asm = false, last = false;
+var minifyWhitespace = false, printMetadata = true, asm = false, asmPreciseF32 = false, last = false;
var passes = {
// passes
@@ -5182,6 +5189,7 @@ var passes = {
minifyWhitespace: function() { minifyWhitespace = true },
noPrintMetadata: function() { printMetadata = false },
asm: function() { asm = true },
+ asmPreciseF32: function() { asmPreciseF32 = true },
last: function() { last = true },
};
diff --git a/tools/test-js-optimizer-asm-last-output.js b/tools/test-js-optimizer-asm-last-output.js
index f850b18f..1b9ac585 100644
--- a/tools/test-js-optimizer-asm-last-output.js
+++ b/tools/test-js-optimizer-asm-last-output.js
@@ -39,7 +39,7 @@ function looop() {
} while (!condition());
do {
do_it();
- } while (a <= b);
+ } while (!(a > b));
do {
do_it();
} while (x());
diff --git a/tools/test-js-optimizer-asm-pre-f32.js b/tools/test-js-optimizer-asm-pre-f32.js
new file mode 100644
index 00000000..a5604ef9
--- /dev/null
+++ b/tools/test-js-optimizer-asm-pre-f32.js
@@ -0,0 +1,11 @@
+function badf() {
+ var $9 = Math_fround(0);
+ $9 = (HEAP32[tempDoublePtr>>2]=$8,Math_fround(HEAPF32[tempDoublePtr>>2]));
+ HEAPF32[$gep23_asptr>>2] = $9;
+}
+function badf2() {
+ var $9 = 0;
+ $9 = (HEAPF32[tempDoublePtr>>2]=$8,HEAP32[tempDoublePtr>>2]|0);
+ HEAP32[$gep23_asptr>>2] = $9;
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8", "tempDoublePtr", "boxx", "_main", "badf", "badf2"]
diff --git a/tools/test-js-optimizer-asm-pre-output-f32.js b/tools/test-js-optimizer-asm-pre-output-f32.js
new file mode 100644
index 00000000..42343f55
--- /dev/null
+++ b/tools/test-js-optimizer-asm-pre-output-f32.js
@@ -0,0 +1,11 @@
+function badf() {
+ var $9 = 0;
+ $9 = $8 | 0;
+ HEAP32[$gep23_asptr >> 2] = $9;
+}
+function badf2() {
+ var $9 = Math_fround(0);
+ $9 = Math_fround($8);
+ HEAPF32[$gep23_asptr >> 2] = $9;
+}
+
diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js
index 0fa81050..c9746e78 100644
--- a/tools/test-js-optimizer-asm-pre-output.js
+++ b/tools/test-js-optimizer-asm-pre-output.js
@@ -519,4 +519,23 @@ function _main($argc, $argv) {
STACKTOP = __stackBase__;
return $_0 | 0;
}
+function badf() {
+ var $9 = 0;
+ $9 = $8 | 0;
+ HEAP32[$gep23_asptr >> 2] = $9;
+}
+function badf2() {
+ var $9 = +0;
+ $9 = +$8;
+ HEAPF32[$gep23_asptr >> 2] = $9;
+}
+function fcomp() {
+ if (!($y < $x)) return 5;
+ if (!(5 < $x)) return 5;
+ if (!($y < 5)) return 5;
+ if (($a | 0) >= ($b | 0)) return 5;
+ if (($a | 0) >= 5) return 5;
+ if (5 >= ($b | 0)) return 5;
+ if (5 >= 5) return 5;
+}
diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js
index dadeef53..00ebd7d7 100644
--- a/tools/test-js-optimizer-asm-pre.js
+++ b/tools/test-js-optimizer-asm-pre.js
@@ -530,4 +530,24 @@ function _main($argc, $argv) {
STACKTOP = __stackBase__;
return $_0 | 0;
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8", "tempDoublePtr", "boxx", "_main"]
+function badf() {
+ var $9 = Math_fround(0);
+ $9 = (HEAP32[tempDoublePtr>>2]=$8,Math_fround(HEAPF32[tempDoublePtr>>2]));
+ HEAPF32[$gep23_asptr>>2] = $9;
+}
+function badf2() {
+ var $9 = 0;
+ $9 = (HEAPF32[tempDoublePtr>>2]=$8,HEAP32[tempDoublePtr>>2]|0);
+ HEAP32[$gep23_asptr>>2] = $9;
+}
+function fcomp() {
+ // de-morgan's laws are not valid on floats, due to NaNs >:(
+ if (!($y < $x)) return 5;
+ if (!(5 < $x)) return 5;
+ if (!($y < 5)) return 5;
+ if (!(($a|0) < ($b|0))) return 5;
+ if (!(($a|0) < 5)) return 5;
+ if (!(5 < ($b|0))) return 5;
+ if (!(5 < 5)) return 5;
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8", "tempDoublePtr", "boxx", "_main", "badf", "badf2", "fcomp"]