From b86abc2ecfea9ccbb93cad2fe4e9f8574beb7ed8 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 23 Dec 2013 15:43:01 -0800 Subject: fix bug where close-together tempDoublePtr operations could cross each other --- tests/core/closebitcasts.c | 32 ++++++++++++++++++++++++++ tests/core/closebitcasts.txt | 2 ++ tests/test_core.py | 6 +++++ tools/eliminator/asm-eliminator-test-output.js | 5 ++-- tools/eliminator/eliminator-test-output.js | 11 +++++++++ tools/eliminator/eliminator-test.js | 17 +++++++++++++- tools/js-optimizer.js | 7 +++++- tools/shared.py | 2 +- 8 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 tests/core/closebitcasts.c create mode 100644 tests/core/closebitcasts.txt diff --git a/tests/core/closebitcasts.c b/tests/core/closebitcasts.c new file mode 100644 index 00000000..2c9d5ab5 --- /dev/null +++ b/tests/core/closebitcasts.c @@ -0,0 +1,32 @@ +#include + +int main(int argc, char **argv) { + float x = argc%17, y = (argc+1)*(argc+2)*(argc+3)*(argc+4)*(argc*5); + y *= 1<<30; + y *= -13; + if (argc == 17) { x++; y--; } + int *xi = (int*)&x; + int *yi = (int*)&y; + int z = *xi - *yi; + while (z % 15) { + z++; + } + printf("!%d\n", z); + + double xd = x, yd = y; + yd = yd*yd; + yd = yd*yd; + int *xl = (int*)&xd; + int *xh = &((int*)&xd)[1]; + int *yl = (int*)&yd; + int *yh = &((int*)&yd)[1]; + int l = *xl - *yl; + int h = *xh - *yh; + while (l % 15) { + l++; + h += 3; + } + printf("%d,%d!\n", l, h); + return 0; +} + diff --git a/tests/core/closebitcasts.txt b/tests/core/closebitcasts.txt new file mode 100644 index 00000000..f97366cd --- /dev/null +++ b/tests/core/closebitcasts.txt @@ -0,0 +1,2 @@ +!1787576325 +589815810,-179981561! diff --git a/tests/test_core.py b/tests/test_core.py index 2430aa1c..5a19ef0c 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -771,6 +771,12 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co self.do_run_from_file(src, output) + def test_closebitcasts(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2') + test_path = path_from_root('tests', 'core', 'closebitcasts') + src, output = (test_path + s for s in ('.c', '.txt')) + self.do_run_from_file(src, output) + def test_fast_math(self): if self.emcc_args is None: return self.skip('requires emcc') Building.COMPILER_TEST_OPTS += ['-ffast-math'] diff --git a/tools/eliminator/asm-eliminator-test-output.js b/tools/eliminator/asm-eliminator-test-output.js index 434fbaf9..c71063cb 100644 --- a/tools/eliminator/asm-eliminator-test-output.js +++ b/tools/eliminator/asm-eliminator-test-output.js @@ -280,9 +280,10 @@ function tempDouble2($46, $14, $28, $42, $20, $32, $45) { $20 = $20 | 0; $32 = $32 | 0; $45 = $45 | 0; - var $_sroa_06_0_insert_insert$1 = 0; + var $46 = 0, $_sroa_06_0_insert_insert$1 = 0; + $46 = (HEAPF32[tempDoublePtr >> 2] = ($14 < $28 ? $14 : $28) - $42, HEAP32[tempDoublePtr >> 2] | 0); $_sroa_06_0_insert_insert$1 = (HEAPF32[tempDoublePtr >> 2] = ($20 < $32 ? $20 : $32) - $42, HEAP32[tempDoublePtr >> 2] | 0) | 0; - HEAP32[$45 >> 2] = 0 | (HEAPF32[tempDoublePtr >> 2] = ($14 < $28 ? $14 : $28) - $42, HEAP32[tempDoublePtr >> 2] | 0); + HEAP32[$45 >> 2] = 0 | $46; HEAP32[$45 + 4 >> 2] = $_sroa_06_0_insert_insert$1; HEAP32[$45 + 8 >> 2] = $_sroa_06_0_insert_insert$1; } diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js index 0171e99b..4551fb34 100644 --- a/tools/eliminator/eliminator-test-output.js +++ b/tools/eliminator/eliminator-test-output.js @@ -6122,4 +6122,15 @@ function intoCond() { function math(a, b, c, d) { print(Math_imul(d) + (Math_fround(c) + (a + Math_abs(b)))); } +function td(x, y) { + HEAP32[tempDoublePtr >> 2] = x; + var xf = HEAPF32[tempDoublePtr >> 2]; + HEAP32[tempDoublePtr >> 2] = y; + func(xf, HEAPF32[tempDoublePtr >> 2]); + HEAPF64[tempDoublePtr >> 3] = x; + var xl = HEAP32[tempDoublePtr >> 2]; + var xh = HEAP32[tempDoublePtr >> 2]; + HEAPF64[tempDoublePtr >> 3] = y; + func(xl, xh, HEAP32[tempDoublePtr >> 2], HEAP32[tempDoublePtr >> 2]); +} diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js index ef17b388..e629d9f0 100644 --- a/tools/eliminator/eliminator-test.js +++ b/tools/eliminator/eliminator-test.js @@ -8860,5 +8860,20 @@ function math(a, b, c, d) { w = Math_imul(d); print(x + y + z + w); } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "c", "f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate", "_malloc", "_mallocNoU", "asm", "phi", "intoCond", "math"] +function td(x, y) { // tempDoublePtr should invalidate each other + HEAP32[tempDoublePtr>>2] = x; + var xf = HEAPF32[tempDoublePtr>>2]; + HEAP32[tempDoublePtr>>2] = y; + var yf = HEAPF32[tempDoublePtr>>2]; + func(xf, yf); + // + HEAPF64[tempDoublePtr>>3] = x; + var xl = HEAP32[tempDoublePtr>>2]; + var xh = HEAP32[tempDoublePtr>>2]; + HEAPF64[tempDoublePtr>>3] = y; + var yl = HEAP32[tempDoublePtr>>2]; + var yh = HEAP32[tempDoublePtr>>2]; + func(xl, xh, yl, yh); +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "c", "f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate", "_malloc", "_mallocNoU", "asm", "phi", "intoCond", "math", "td"] diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 9efca25f..6e82451c 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -2427,7 +2427,12 @@ function eliminate(ast, memSafe) { if (allowTracking) track(name, node[3], node); } } else if (target[0] === 'sub') { - if (!isTempDoublePtrAccess(target) && !memoryInvalidated) { + if (isTempDoublePtrAccess(target)) { + if (!globalsInvalidated) { + invalidateGlobals(); + globalsInvalidated = true; + } + } else if (!memoryInvalidated) { invalidateMemory(); memoryInvalidated = true; } diff --git a/tools/shared.py b/tools/shared.py index 443ff4c7..2177a527 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -682,7 +682,7 @@ def line_splitter(data): return out -def limit_size(string, MAX=12000*20): +def limit_size(string, MAX=80*20): if len(string) < MAX: return string return string[0:MAX/2] + '\n[..]\n' + string[-MAX/2:] -- cgit v1.2.3-18-g5258