diff options
-rwxr-xr-x | auto_update_tests.py | 2 | ||||
-rwxr-xr-x | check.py | 2 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 11 | ||||
-rw-r--r-- | test/passes/fuzz-exec_O.txt | 25 | ||||
-rw-r--r-- | test/passes/fuzz-exec_O.wast | 23 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 8 |
6 files changed, 63 insertions, 8 deletions
diff --git a/auto_update_tests.py b/auto_update_tests.py index 7e07af3a5..7aab8ea4e 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -93,7 +93,7 @@ for t in sorted(os.listdir(os.path.join('test', 'passes'))): print '..', t binary = '.wasm' in t passname = os.path.basename(t).replace('.wast', '').replace('.wasm', '') - opts = ['-' + passname] if passname.startswith('O') else ['--' + p for p in passname.split('_')] + opts = [('--' + p if not p.startswith('O') else '-' + p) for p in passname.split('_')] t = os.path.join('test', 'passes', t) actual = '' for module, asserts in split_wast(t): @@ -78,7 +78,7 @@ for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'passes'))): print '..', t binary = '.wasm' in t passname = os.path.basename(t).replace('.wast', '').replace('.wasm', '') - opts = ['-' + passname] if passname.startswith('O') else ['--' + p for p in passname.split('_')] + opts = [('--' + p if not p.startswith('O') else '-' + p) for p in passname.split('_')] t = os.path.join(options.binaryen_test, 'passes', t) actual = '' for module, asserts in split_wast(t): diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index de6f96ccc..2930fe9c9 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -908,8 +908,15 @@ private: // it's better to do the opposite for gzip purposes as well as for readability. auto* last = ptr->dynCast<Const>(); if (last) { - last->value = Literal(int32_t(last->value.geti32() + offset)); - offset = 0; + // don't do this if it would wrap the pointer + uint64_t value64 = last->value.geti32(); + uint64_t offset64 = offset; + if (value64 <= std::numeric_limits<int32_t>::max() && + offset64 <= std::numeric_limits<int32_t>::max() && + value64 + offset64 <= std::numeric_limits<int32_t>::max()) { + last->value = Literal(int32_t(value64 + offset64)); + offset = 0; + } } } diff --git a/test/passes/fuzz-exec_O.txt b/test/passes/fuzz-exec_O.txt new file mode 100644 index 000000000..f5f8583a3 --- /dev/null +++ b/test/passes/fuzz-exec_O.txt @@ -0,0 +1,25 @@ +[fuzz-exec] 2 results noted +(module + (type $0 (func (result i64))) + (type $1 (func (result i32))) + (memory $0 1 1) + (export "func_0" (func $func_0)) + (export "func_1" (func $func_1)) + (func $func_0 (type $0) (result i64) + (block $label$0 (result i64) + (br_if $label$0 + (i64.const 1234) + (i32.load16_s offset=22 align=1 + (i32.const -1) + ) + ) + ) + ) + (func $func_1 (type $1) (result i32) + (i32.load16_s offset=22 align=1 + (i32.const -1) + ) + ) +) +[fuzz-exec] 2 results noted +[fuzz-exec] results match diff --git a/test/passes/fuzz-exec_O.wast b/test/passes/fuzz-exec_O.wast new file mode 100644 index 000000000..3d03de714 --- /dev/null +++ b/test/passes/fuzz-exec_O.wast @@ -0,0 +1,23 @@ +(module + (memory $0 1 1) + (export "func_0" (func $func_0)) + (export "func_1" (func $func_1)) + (func $func_0 (result i64) + (block $label$0 (result i64) + (loop $label$1 (result i64) + (br_if $label$0 + (i64.const 1234) + (i32.load16_s offset=22 align=1 + (i32.const -1) + ) + ) + ) + ) + ) + (func $func_1 (result i32) + (i32.load16_s offset=22 align=1 + (i32.const -1) + ) + ) +) + diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt index 604c9c3ea..301a6cfc0 100644 --- a/test/passes/optimize-instructions.txt +++ b/test/passes/optimize-instructions.txt @@ -462,16 +462,16 @@ (i32.const 4) (get_local $0) ) - (i32.store - (i32.const 0) + (i32.store offset=2 + (i32.const -2) (get_local $0) ) (i32.store (i32.const 25) (get_local $0) ) - (i32.store - (i32.const -23) + (i32.store offset=2 + (i32.const -25) (get_local $0) ) (drop |