diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-11-15 21:36:33 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-12-07 16:50:04 -1000 |
commit | 98e9e604c7e2e4f928abe8f05691df90cddf09e4 (patch) | |
tree | 9497de28012c109ae0e6e958aca8968e8a3d97cf | |
parent | 49bdfd20094e909fb6f4ea989e2a2cbfe01e8741 (diff) | |
download | binaryen-98e9e604c7e2e4f928abe8f05691df90cddf09e4.tar.gz binaryen-98e9e604c7e2e4f928abe8f05691df90cddf09e4.tar.bz2 binaryen-98e9e604c7e2e4f928abe8f05691df90cddf09e4.zip |
add a RemoveUnusedModuleElements pass, and make LegalizeJSInterface create TempRet0 if needed (otherwise we might remove it before we use it)
29 files changed, 421 insertions, 403 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index f10fb40eb..2565ee24a 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -68,34 +68,6 @@ struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { } }; -// Finds all functions that are reachable via direct calls. - -struct DirectCallGraphAnalyzer : public PostWalker<DirectCallGraphAnalyzer, Visitor<DirectCallGraphAnalyzer>> { - Module *module; - std::vector<Function*> queue; - std::unordered_set<Function*> reachable; - - DirectCallGraphAnalyzer(Module* module, const std::vector<Function*>& root) : module(module) { - for (auto* curr : root) { - queue.push_back(curr); - } - while (queue.size()) { - auto* curr = queue.back(); - queue.pop_back(); - if (reachable.count(curr) == 0) { - reachable.insert(curr); - walk(curr->body); - } - } - } - void visitCall(Call *curr) { - auto* target = module->getFunction(curr->target); - if (reachable.count(target) == 0) { - queue.push_back(target); - } - } -}; - // Look for side effects, including control flow // TODO: optimize diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index e47a7d892..9db1c66ae 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -22,7 +22,7 @@ SET(passes_SOURCES RemoveMemory.cpp RemoveUnusedBrs.cpp RemoveUnusedNames.cpp - RemoveUnusedFunctions.cpp + RemoveUnusedModuleElements.cpp ReorderLocals.cpp ReorderFunctions.cpp SimplifyLocals.cpp diff --git a/src/passes/DuplicateFunctionElimination.cpp b/src/passes/DuplicateFunctionElimination.cpp index cfe2d8565..8e8342729 100644 --- a/src/passes/DuplicateFunctionElimination.cpp +++ b/src/passes/DuplicateFunctionElimination.cpp @@ -127,7 +127,7 @@ struct DuplicateFunctionElimination : public Pass { v.erase(std::remove_if(v.begin(), v.end(), [&](const std::unique_ptr<Function>& curr) { return duplicates.count(curr->name) > 0; }), v.end()); - module->updateFunctionsMap(); + module->updateMaps(); // replace direct calls PassRunner replacerRunner(module); replacerRunner.add<FunctionReplacer>(&replacements); diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index 3819fcf72..33bba2112 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -126,14 +126,11 @@ private: auto index = builder.addVar(legal, Name(), i64); auto* block = builder.makeBlock(); block->list.push_back(builder.makeSetLocal(index, call)); - if (module->checkGlobal(TEMP_RET_0)) { - block->list.push_back(builder.makeSetGlobal( - TEMP_RET_0, - I64Utilities::getI64High(builder, index) - )); - } else { - block->list.push_back(builder.makeUnreachable()); // no way to emit the high bits :( - } + ensureTempRet0(module); + block->list.push_back(builder.makeSetGlobal( + TEMP_RET_0, + I64Utilities::getI64High(builder, index) + )); block->list.push_back(I64Utilities::getI64Low(builder, index)); block->finalize(); legal->body = block; @@ -183,11 +180,8 @@ private: if (im->functionType->result == i64) { call->type = i32; Expression* get; - if (module->checkGlobal(TEMP_RET_0)) { - get = builder.makeGetGlobal(TEMP_RET_0, i32); - } else { - get = builder.makeUnreachable(); // no way to emit the high bits :( - } + ensureTempRet0(module); + get = builder.makeGetGlobal(TEMP_RET_0, i32); func->body = I64Utilities::recreateI64(builder, call, get); type->result = i32; } else { @@ -201,6 +195,17 @@ private: module->addFunctionType(type); return legal; } + + void ensureTempRet0(Module* module) { + if (!module->checkGlobal(TEMP_RET_0)) { + Global* global = new Global; + global->name = TEMP_RET_0; + global->type = i32; + global->init = module->allocator.alloc<Const>()->set(Literal(int32_t(0))); + global->mutable_ = true; + module->addGlobal(global); + } + } }; Pass *createLegalizeJSInterfacePass() { diff --git a/src/passes/RemoveUnusedFunctions.cpp b/src/passes/RemoveUnusedFunctions.cpp deleted file mode 100644 index ec9e271b7..000000000 --- a/src/passes/RemoveUnusedFunctions.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// Removes functions that are never used. -// - - -#include <memory> - -#include "wasm.h" -#include "pass.h" -#include "ast_utils.h" - -namespace wasm { - -struct RemoveUnusedFunctions : public Pass { - void run(PassRunner* runner, Module* module) override { - std::vector<Function*> root; - // Module start is a root. - if (module->start.is()) { - root.push_back(module->getFunction(module->start)); - } - // Exports are roots. - for (auto& curr : module->exports) { - if (curr->kind == ExternalKind::Function) { - root.push_back(module->getFunction(curr->value)); - } - } - // For now, all functions that can be called indirectly are marked as roots. - for (auto& segment : module->table.segments) { - for (auto& curr : segment.data) { - root.push_back(module->getFunction(curr)); - } - } - // Compute function reachability starting from the root set. - DirectCallGraphAnalyzer analyzer(module, root); - // Remove unreachable functions. - auto& v = module->functions; - v.erase(std::remove_if(v.begin(), v.end(), [&](const std::unique_ptr<Function>& curr) { - return analyzer.reachable.count(curr.get()) == 0; - }), v.end()); - assert(module->functions.size() == analyzer.reachable.size()); - module->updateFunctionsMap(); - } -}; - -Pass *createRemoveUnusedFunctionsPass() { - return new RemoveUnusedFunctions(); -} - -} // namespace wasm diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp new file mode 100644 index 000000000..cf9741961 --- /dev/null +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -0,0 +1,155 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Removes module elements that are are never used: functions and globals, +// which may be imported or not. +// + + +#include <memory> + +#include "wasm.h" +#include "pass.h" +#include "ast_utils.h" + +namespace wasm { + +enum class ModuleElementKind { + Function, + Global +}; + +typedef std::pair<ModuleElementKind, Name> ModuleElement; + +// Finds reachabilities + +struct ReachabilityAnalyzer : public PostWalker<ReachabilityAnalyzer, Visitor<ReachabilityAnalyzer>> { + Module* module; + std::vector<ModuleElement> queue; + std::set<ModuleElement> reachable; + + ReachabilityAnalyzer(Module* module, const std::vector<ModuleElement>& roots) : module(module) { + queue = roots; + // Globals used in memory/table init expressions are also roots + for (auto& segment : module->memory.segments) { + walk(segment.offset); + } + for (auto& segment : module->table.segments) { + walk(segment.offset); + } + // main loop + while (queue.size()) { + auto& curr = queue.back(); + queue.pop_back(); + if (reachable.count(curr) == 0) { + reachable.insert(curr); + if (curr.first == ModuleElementKind::Function) { + // if not an import, walk it + auto* func = module->checkFunction(curr.second); + if (func) { + walk(func->body); + } + } else { + // if not imported, it has an init expression we need to walk + auto* glob = module->checkGlobal(curr.second); + if (glob) { + walk(glob->init); + } + } + } + } + } + + void visitCall(Call* curr) { + if (reachable.count(ModuleElement(ModuleElementKind::Function, curr->target)) == 0) { + queue.emplace_back(ModuleElementKind::Function, curr->target); + } + } + void visitCallImport(CallImport* curr) { + if (reachable.count(ModuleElement(ModuleElementKind::Function, curr->target)) == 0) { + queue.emplace_back(ModuleElementKind::Function, curr->target); + } + } + + void visitGetGlobal(GetGlobal* curr) { + if (reachable.count(ModuleElement(ModuleElementKind::Global, curr->name)) == 0) { + queue.emplace_back(ModuleElementKind::Global, curr->name); + } + } + void visitSetGlobal(SetGlobal* curr) { + if (reachable.count(ModuleElement(ModuleElementKind::Global, curr->name)) == 0) { + queue.emplace_back(ModuleElementKind::Global, curr->name); + } + } +}; + +struct RemoveUnusedModuleElements : public Pass { + void run(PassRunner* runner, Module* module) override { + std::vector<ModuleElement> roots; + // Module start is a root. + if (module->start.is()) { + roots.emplace_back(ModuleElementKind::Function, module->start); + } + // Exports are roots. + for (auto& curr : module->exports) { + if (curr->kind == ExternalKind::Function) { + roots.emplace_back(ModuleElementKind::Function, curr->value); + } else if (curr->kind == ExternalKind::Global) { + roots.emplace_back(ModuleElementKind::Global, curr->value); + } + } + // For now, all functions that can be called indirectly are marked as roots. + for (auto& segment : module->table.segments) { + for (auto& curr : segment.data) { + roots.emplace_back(ModuleElementKind::Function, curr); + } + } + // Compute reachability starting from the root set. + ReachabilityAnalyzer analyzer(module, roots); + // Remove unreachable elements. + { + auto& v = module->functions; + v.erase(std::remove_if(v.begin(), v.end(), [&](const std::unique_ptr<Function>& curr) { + return analyzer.reachable.count(ModuleElement(ModuleElementKind::Function, curr->name)) == 0; + }), v.end()); + } + { + auto& v = module->globals; + v.erase(std::remove_if(v.begin(), v.end(), [&](const std::unique_ptr<Global>& curr) { + return analyzer.reachable.count(ModuleElement(ModuleElementKind::Global, curr->name)) == 0; + }), v.end()); + } + { + auto& v = module->imports; + v.erase(std::remove_if(v.begin(), v.end(), [&](const std::unique_ptr<Import>& curr) { + if (curr->kind == ExternalKind::Function) { + return analyzer.reachable.count(ModuleElement(ModuleElementKind::Function, curr->name)) == 0; + } else if (curr->kind == ExternalKind::Global) { + return analyzer.reachable.count(ModuleElement(ModuleElementKind::Global, curr->name)) == 0; + } + return false; + }), v.end()); + } + module->updateMaps(); + } +}; + +Pass* createRemoveUnusedModuleElementsPass() { + return new RemoveUnusedModuleElements(); +} + +} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 20e002f4b..32b596eef 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -86,7 +86,7 @@ void PassRegistry::registerPasses() { registerPass("remove-imports", "removes imports and replaces them with nops", createRemoveImportsPass); registerPass("remove-memory", "removes memory segments", createRemoveMemoryPass); registerPass("remove-unused-brs", "removes breaks from locations that are not needed", createRemoveUnusedBrsPass); - registerPass("remove-unused-functions", "removes unused functions", createRemoveUnusedFunctionsPass); + registerPass("remove-unused-module-elements", "removes unused module elements", createRemoveUnusedModuleElementsPass); registerPass("remove-unused-names", "removes names from locations that are never branched to", createRemoveUnusedNamesPass); registerPass("reorder-functions", "sorts functions by access frequency", createReorderFunctionsPass); registerPass("reorder-locals", "sorts locals by access frequency", createReorderLocalsPass); @@ -103,7 +103,7 @@ void PassRunner::addDefaultOptimizationPasses() { add("duplicate-function-elimination"); addDefaultFunctionOptimizationPasses(); add("duplicate-function-elimination"); // optimizations show more functions as duplicate - add("remove-unused-functions"); + add("remove-unused-module-elements"); add("memory-packing"); } @@ -133,7 +133,7 @@ void PassRunner::addDefaultFunctionOptimizationPasses() { void PassRunner::addDefaultGlobalOptimizationPasses() { add("duplicate-function-elimination"); - add("remove-unused-functions"); + add("remove-unused-module-elements"); add("memory-packing"); } diff --git a/src/passes/passes.h b/src/passes/passes.h index 98f99654e..cbfc48327 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -46,7 +46,7 @@ Pass *createRelooperJumpThreadingPass(); Pass *createRemoveImportsPass(); Pass *createRemoveMemoryPass(); Pass *createRemoveUnusedBrsPass(); -Pass *createRemoveUnusedFunctionsPass(); +Pass *createRemoveUnusedModuleElementsPass(); Pass *createRemoveUnusedNamesPass(); Pass *createReorderFunctionsPass(); Pass *createReorderLocalsPass(); diff --git a/src/wasm.h b/src/wasm.h index c1ef75ea9..75d6a174c 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1609,10 +1609,26 @@ public: } // TODO: remove* for other elements - void updateFunctionsMap() { + void updateMaps() { functionsMap.clear(); - for (auto& func : functions) { - functionsMap[func->name] = func.get(); + for (auto& curr : functions) { + functionsMap[curr->name] = curr.get(); + } + functionTypesMap.clear(); + for (auto& curr : functionTypes) { + functionTypesMap[curr->name] = curr.get(); + } + importsMap.clear(); + for (auto& curr : imports) { + importsMap[curr->name] = curr.get(); + } + exportsMap.clear(); + for (auto& curr : exports) { + exportsMap[curr->name] = curr.get(); + } + globalsMap.clear(); + for (auto& curr : globals) { + globalsMap[curr->name] = curr.get(); } } }; diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm index 2a55e5b8a..4d3147862 100644 --- a/test/emcc_O2_hello_world.fromasm +++ b/test/emcc_O2_hello_world.fromasm @@ -8,10 +8,6 @@ (type $FUNCSIG$vii (func (param i32 i32))) (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) - (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) - (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) - (import "global" "NaN" (global $nan$asm2wasm$import f64)) - (import "global" "Infinity" (global $inf$asm2wasm$import f64)) (import "env" "abort" (func $abort (param i32))) (import "env" "_pthread_cleanup_pop" (func $_pthread_cleanup_pop (param i32))) (import "env" "_pthread_self" (func $_pthread_self (result i32))) @@ -36,34 +32,9 @@ (data (i32.const 1024) "emcc_O2_hello_world.asm.js") (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) - (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) - (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) (global $__THREW__ (mut i32) (i32.const 0)) (global $threwValue (mut i32) (i32.const 0)) - (global $setjmpId (mut i32) (i32.const 0)) - (global $undef (mut i32) (i32.const 0)) - (global $nan (mut f64) (get_global $nan$asm2wasm$import)) - (global $inf (mut f64) (get_global $inf$asm2wasm$import)) - (global $tempInt (mut i32) (i32.const 0)) - (global $tempBigInt (mut i32) (i32.const 0)) - (global $tempBigIntP (mut i32) (i32.const 0)) - (global $tempBigIntS (mut i32) (i32.const 0)) - (global $tempBigIntR (mut f64) (f64.const 0)) - (global $tempBigIntI (mut i32) (i32.const 0)) - (global $tempBigIntD (mut i32) (i32.const 0)) - (global $tempValue (mut i32) (i32.const 0)) - (global $tempDouble (mut f64) (f64.const 0)) (global $tempRet0 (mut i32) (i32.const 0)) - (global $tempRet1 (mut i32) (i32.const 0)) - (global $tempRet2 (mut i32) (i32.const 0)) - (global $tempRet3 (mut i32) (i32.const 0)) - (global $tempRet4 (mut i32) (i32.const 0)) - (global $tempRet5 (mut i32) (i32.const 0)) - (global $tempRet6 (mut i32) (i32.const 0)) - (global $tempRet7 (mut i32) (i32.const 0)) - (global $tempRet8 (mut i32) (i32.const 0)) - (global $tempRet9 (mut i32) (i32.const 0)) - (global $tempFloat (mut f64) (f64.const 0)) (export "_free" (func $_free)) (export "_main" (func $_main)) (export "_memset" (func $_memset)) diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise index 88b92fcef..8ab35a567 100644 --- a/test/emcc_O2_hello_world.fromasm.imprecise +++ b/test/emcc_O2_hello_world.fromasm.imprecise @@ -8,10 +8,6 @@ (type $FUNCSIG$vii (func (param i32 i32))) (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) - (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) - (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) - (import "global" "NaN" (global $nan$asm2wasm$import f64)) - (import "global" "Infinity" (global $inf$asm2wasm$import f64)) (import "env" "abort" (func $abort (param i32))) (import "env" "_pthread_cleanup_pop" (func $_pthread_cleanup_pop (param i32))) (import "env" "_pthread_self" (func $_pthread_self (result i32))) @@ -34,34 +30,9 @@ (elem (get_global $tableBase) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) - (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) - (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) (global $__THREW__ (mut i32) (i32.const 0)) (global $threwValue (mut i32) (i32.const 0)) - (global $setjmpId (mut i32) (i32.const 0)) - (global $undef (mut i32) (i32.const 0)) - (global $nan (mut f64) (get_global $nan$asm2wasm$import)) - (global $inf (mut f64) (get_global $inf$asm2wasm$import)) - (global $tempInt (mut i32) (i32.const 0)) - (global $tempBigInt (mut i32) (i32.const 0)) - (global $tempBigIntP (mut i32) (i32.const 0)) - (global $tempBigIntS (mut i32) (i32.const 0)) - (global $tempBigIntR (mut f64) (f64.const 0)) - (global $tempBigIntI (mut i32) (i32.const 0)) - (global $tempBigIntD (mut i32) (i32.const 0)) - (global $tempValue (mut i32) (i32.const 0)) - (global $tempDouble (mut f64) (f64.const 0)) (global $tempRet0 (mut i32) (i32.const 0)) - (global $tempRet1 (mut i32) (i32.const 0)) - (global $tempRet2 (mut i32) (i32.const 0)) - (global $tempRet3 (mut i32) (i32.const 0)) - (global $tempRet4 (mut i32) (i32.const 0)) - (global $tempRet5 (mut i32) (i32.const 0)) - (global $tempRet6 (mut i32) (i32.const 0)) - (global $tempRet7 (mut i32) (i32.const 0)) - (global $tempRet8 (mut i32) (i32.const 0)) - (global $tempRet9 (mut i32) (i32.const 0)) - (global $tempFloat (mut f64) (f64.const 0)) (export "_free" (func $_free)) (export "_main" (func $_main)) (export "_memset" (func $_memset)) diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index 285bfc334..85d980069 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -10,10 +10,6 @@ (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) - (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) - (import "env" "cttz_i8" (global $cttz_i8$asm2wasm$import i32)) - (import "global" "NaN" (global $nan$asm2wasm$import f64)) - (import "global" "Infinity" (global $inf$asm2wasm$import f64)) (import "env" "abort" (func $abort)) (import "env" "nullFunc_ii" (func $nullFunc_ii (param i32))) (import "env" "nullFunc_iiii" (func $nullFunc_iiii (param i32))) @@ -46,34 +42,9 @@ (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) - (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) - (global $cttz_i8 (mut i32) (get_global $cttz_i8$asm2wasm$import)) (global $__THREW__ (mut i32) (i32.const 0)) (global $threwValue (mut i32) (i32.const 0)) - (global $setjmpId (mut i32) (i32.const 0)) - (global $undef (mut i32) (i32.const 0)) - (global $nan (mut f64) (get_global $nan$asm2wasm$import)) - (global $inf (mut f64) (get_global $inf$asm2wasm$import)) - (global $tempInt (mut i32) (i32.const 0)) - (global $tempBigInt (mut i32) (i32.const 0)) - (global $tempBigIntP (mut i32) (i32.const 0)) - (global $tempBigIntS (mut i32) (i32.const 0)) - (global $tempBigIntR (mut f64) (f64.const 0)) - (global $tempBigIntI (mut i32) (i32.const 0)) - (global $tempBigIntD (mut i32) (i32.const 0)) - (global $tempValue (mut i32) (i32.const 0)) - (global $tempDouble (mut f64) (f64.const 0)) (global $tempRet0 (mut i32) (i32.const 0)) - (global $tempRet1 (mut i32) (i32.const 0)) - (global $tempRet2 (mut i32) (i32.const 0)) - (global $tempRet3 (mut i32) (i32.const 0)) - (global $tempRet4 (mut i32) (i32.const 0)) - (global $tempRet5 (mut i32) (i32.const 0)) - (global $tempRet6 (mut i32) (i32.const 0)) - (global $tempRet7 (mut i32) (i32.const 0)) - (global $tempRet8 (mut i32) (i32.const 0)) - (global $tempRet9 (mut i32) (i32.const 0)) - (global $tempFloat (mut f64) (f64.const 0)) (export "_i64Subtract" (func $_i64Subtract)) (export "_free" (func $_free)) (export "_main" (func $_main)) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index 806735e42..65bd295bc 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -9,10 +9,6 @@ (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) - (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) - (import "env" "cttz_i8" (global $cttz_i8$asm2wasm$import i32)) - (import "global" "NaN" (global $nan$asm2wasm$import f64)) - (import "global" "Infinity" (global $inf$asm2wasm$import f64)) (import "env" "abort" (func $abort)) (import "env" "nullFunc_ii" (func $nullFunc_ii (param i32))) (import "env" "nullFunc_iiii" (func $nullFunc_iiii (param i32))) @@ -39,34 +35,9 @@ (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) - (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) - (global $cttz_i8 (mut i32) (get_global $cttz_i8$asm2wasm$import)) (global $__THREW__ (mut i32) (i32.const 0)) (global $threwValue (mut i32) (i32.const 0)) - (global $setjmpId (mut i32) (i32.const 0)) - (global $undef (mut i32) (i32.const 0)) - (global $nan (mut f64) (get_global $nan$asm2wasm$import)) - (global $inf (mut f64) (get_global $inf$asm2wasm$import)) - (global $tempInt (mut i32) (i32.const 0)) - (global $tempBigInt (mut i32) (i32.const 0)) - (global $tempBigIntP (mut i32) (i32.const 0)) - (global $tempBigIntS (mut i32) (i32.const 0)) - (global $tempBigIntR (mut f64) (f64.const 0)) - (global $tempBigIntI (mut i32) (i32.const 0)) - (global $tempBigIntD (mut i32) (i32.const 0)) - (global $tempValue (mut i32) (i32.const 0)) - (global $tempDouble (mut f64) (f64.const 0)) (global $tempRet0 (mut i32) (i32.const 0)) - (global $tempRet1 (mut i32) (i32.const 0)) - (global $tempRet2 (mut i32) (i32.const 0)) - (global $tempRet3 (mut i32) (i32.const 0)) - (global $tempRet4 (mut i32) (i32.const 0)) - (global $tempRet5 (mut i32) (i32.const 0)) - (global $tempRet6 (mut i32) (i32.const 0)) - (global $tempRet7 (mut i32) (i32.const 0)) - (global $tempRet8 (mut i32) (i32.const 0)) - (global $tempRet9 (mut i32) (i32.const 0)) - (global $tempFloat (mut f64) (f64.const 0)) (export "_i64Subtract" (func $_i64Subtract)) (export "_free" (func $_free)) (export "_main" (func $_main)) diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 1de260b20..4eee5c0c0 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -1028,7 +1028,6 @@ optimized: (type $v (func)) (type $vi (func (param i32))) (type $i (func (result i32))) - (import "module" "check" (func $check (param i32))) (memory $0 0) ) module loaded from binary form: @@ -2886,7 +2885,6 @@ optimized: (type $v (func)) (type $vi (func (param i32))) (type $i (func (result i32))) - (import "module" "check" (func $check (param i32))) (memory $0 0) ) BinaryenModuleDispose(the_module); diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt index 16e4941d3..cbccff232 100644 --- a/test/example/c-api-kitchen-sink.txt.txt +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -1021,6 +1021,5 @@ (type $v (func)) (type $vi (func (param i32))) (type $i (func (result i32))) - (import "module" "check" (func $check (param i32))) (memory $0 0) ) diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm index e9098be75..cfe303d34 100644 --- a/test/memorygrowth.fromasm +++ b/test/memorygrowth.fromasm @@ -7,10 +7,6 @@ (type $FUNCSIG$vii (func (param i32 i32))) (import "env" "STACKTOP" (global $r$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $s$asm2wasm$import i32)) - (import "env" "tempDoublePtr" (global $t$asm2wasm$import i32)) - (import "env" "ABORT" (global $u$asm2wasm$import i32)) - (import "global" "NaN" (global $z$asm2wasm$import f64)) - (import "global" "Infinity" (global $A$asm2wasm$import f64)) (import "env" "abort" (func $ja (param i32))) (import "env" "_pthread_cleanup_pop" (func $oa (param i32))) (import "env" "___lock" (func $pa (param i32))) @@ -32,34 +28,9 @@ (data (get_global $memoryBase) "memorygrowth.asm.js") (global $r (mut i32) (get_global $r$asm2wasm$import)) (global $s (mut i32) (get_global $s$asm2wasm$import)) - (global $t (mut i32) (get_global $t$asm2wasm$import)) - (global $u (mut i32) (get_global $u$asm2wasm$import)) (global $v (mut i32) (i32.const 0)) (global $w (mut i32) (i32.const 0)) - (global $x (mut i32) (i32.const 0)) - (global $y (mut i32) (i32.const 0)) - (global $z (mut f64) (get_global $z$asm2wasm$import)) - (global $A (mut f64) (get_global $A$asm2wasm$import)) - (global $B (mut i32) (i32.const 0)) - (global $C (mut i32) (i32.const 0)) - (global $D (mut i32) (i32.const 0)) - (global $E (mut i32) (i32.const 0)) - (global $F (mut f64) (f64.const 0)) - (global $G (mut i32) (i32.const 0)) - (global $H (mut i32) (i32.const 0)) - (global $I (mut i32) (i32.const 0)) - (global $J (mut f64) (f64.const 0)) (global $K (mut i32) (i32.const 0)) - (global $L (mut i32) (i32.const 0)) - (global $M (mut i32) (i32.const 0)) - (global $N (mut i32) (i32.const 0)) - (global $O (mut i32) (i32.const 0)) - (global $P (mut i32) (i32.const 0)) - (global $Q (mut i32) (i32.const 0)) - (global $R (mut i32) (i32.const 0)) - (global $S (mut i32) (i32.const 0)) - (global $T (mut i32) (i32.const 0)) - (global $za (mut f64) (f64.const 0)) (export "_free" (func $fb)) (export "_main" (func $Na)) (export "_pthread_self" (func $ib)) diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise index 0cd953b5b..c1f308b20 100644 --- a/test/memorygrowth.fromasm.imprecise +++ b/test/memorygrowth.fromasm.imprecise @@ -7,10 +7,6 @@ (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (import "env" "STACKTOP" (global $r$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $s$asm2wasm$import i32)) - (import "env" "tempDoublePtr" (global $t$asm2wasm$import i32)) - (import "env" "ABORT" (global $u$asm2wasm$import i32)) - (import "global" "NaN" (global $z$asm2wasm$import f64)) - (import "global" "Infinity" (global $A$asm2wasm$import f64)) (import "env" "abort" (func $ja (param i32))) (import "env" "_pthread_cleanup_pop" (func $oa (param i32))) (import "env" "___lock" (func $pa (param i32))) @@ -30,34 +26,9 @@ (elem (get_global $tableBase) $nb $Oa $ob $Va $Ua $Ra $pb $Sa) (global $r (mut i32) (get_global $r$asm2wasm$import)) (global $s (mut i32) (get_global $s$asm2wasm$import)) - (global $t (mut i32) (get_global $t$asm2wasm$import)) - (global $u (mut i32) (get_global $u$asm2wasm$import)) (global $v (mut i32) (i32.const 0)) (global $w (mut i32) (i32.const 0)) - (global $x (mut i32) (i32.const 0)) - (global $y (mut i32) (i32.const 0)) - (global $z (mut f64) (get_global $z$asm2wasm$import)) - (global $A (mut f64) (get_global $A$asm2wasm$import)) - (global $B (mut i32) (i32.const 0)) - (global $C (mut i32) (i32.const 0)) - (global $D (mut i32) (i32.const 0)) - (global $E (mut i32) (i32.const 0)) - (global $F (mut f64) (f64.const 0)) - (global $G (mut i32) (i32.const 0)) - (global $H (mut i32) (i32.const 0)) - (global $I (mut i32) (i32.const 0)) - (global $J (mut f64) (f64.const 0)) (global $K (mut i32) (i32.const 0)) - (global $L (mut i32) (i32.const 0)) - (global $M (mut i32) (i32.const 0)) - (global $N (mut i32) (i32.const 0)) - (global $O (mut i32) (i32.const 0)) - (global $P (mut i32) (i32.const 0)) - (global $Q (mut i32) (i32.const 0)) - (global $R (mut i32) (i32.const 0)) - (global $S (mut i32) (i32.const 0)) - (global $T (mut i32) (i32.const 0)) - (global $za (mut f64) (f64.const 0)) (export "_free" (func $fb)) (export "_main" (func $Na)) (export "_pthread_self" (func $ib)) diff --git a/test/min.fromasm b/test/min.fromasm index c54c786a6..76d071ef6 100644 --- a/test/min.fromasm +++ b/test/min.fromasm @@ -1,11 +1,9 @@ (module - (import "env" "tempDoublePtr" (global $tDP$asm2wasm$import i32)) (import "env" "memory" (memory $0 256 256)) (import "env" "table" (table 0 0 anyfunc)) (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) (data (get_global $memoryBase) "min.asm.js") - (global $tDP (mut i32) (get_global $tDP$asm2wasm$import)) (global $M (mut i32) (i32.const 0)) (export "floats" (func $floats)) (export "getTempRet0" (func $ub)) diff --git a/test/min.fromasm.imprecise b/test/min.fromasm.imprecise index d2a09dd4e..9b63300b5 100644 --- a/test/min.fromasm.imprecise +++ b/test/min.fromasm.imprecise @@ -1,10 +1,8 @@ (module - (import "env" "tempDoublePtr" (global $tDP$asm2wasm$import i32)) (import "env" "memory" (memory $0 256 256)) (import "env" "table" (table 0 0 anyfunc)) (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) - (global $tDP (mut i32) (get_global $tDP$asm2wasm$import)) (global $M (mut i32) (i32.const 0)) (export "floats" (func $floats)) (export "getTempRet0" (func $ub)) diff --git a/test/passes/remove-unused-functions.txt b/test/passes/remove-unused-functions.txt deleted file mode 100644 index 6e4a452b3..000000000 --- a/test/passes/remove-unused-functions.txt +++ /dev/null @@ -1,34 +0,0 @@ -(module - (type $0 (func)) - (table 1 1 anyfunc) - (elem (i32.const 0) $called_indirect) - (memory $0 0) - (export "memory" (memory $0)) - (export "exported" (func $exported)) - (start $start) - (func $start (type $0) - (call $called0) - ) - (func $called0 (type $0) - (call $called1) - ) - (func $called1 (type $0) - (nop) - ) - (func $called_indirect (type $0) - (nop) - ) - (func $exported (type $0) - (call $called2) - ) - (func $called2 (type $0) - (call $called2) - (call $called3) - ) - (func $called3 (type $0) - (call $called4) - ) - (func $called4 (type $0) - (call $called3) - ) -) diff --git a/test/passes/remove-unused-functions.wast b/test/passes/remove-unused-functions.wast deleted file mode 100644 index c3d25d021..000000000 --- a/test/passes/remove-unused-functions.wast +++ /dev/null @@ -1,49 +0,0 @@ -(module - (memory 0) - (start $start) - (type $0 (func)) - (export "memory" (memory $0)) - (export "exported" $exported) - (table 1 1 anyfunc) - (elem (i32.const 0) $called_indirect) - (func $start (type $0) - (call $called0) - ) - (func $called0 (type $0) - (call $called1) - ) - (func $called1 (type $0) - (nop) - ) - (func $called_indirect (type $0) - (nop) - ) - (func $exported (type $0) - (call $called2) - ) - (func $called2 (type $0) - (call $called2) - (call $called3) - ) - (func $called3 (type $0) - (call $called4) - ) - (func $called4 (type $0) - (call $called3) - ) - (func $remove0 (type $0) - (call $remove1) - ) - (func $remove1 (type $0) - (nop) - ) - (func $remove2 (type $0) - (call $remove2) - ) - (func $remove3 (type $0) - (call $remove4) - ) - (func $remove4 (type $0) - (call $remove3) - ) -) diff --git a/test/passes/remove-unused-module-elements.txt b/test/passes/remove-unused-module-elements.txt new file mode 100644 index 000000000..8b8fd3601 --- /dev/null +++ b/test/passes/remove-unused-module-elements.txt @@ -0,0 +1,87 @@ +(module + (type $0 (func)) + (table 1 1 anyfunc) + (elem (i32.const 0) $called_indirect) + (memory $0 0) + (export "memory" (memory $0)) + (export "exported" (func $exported)) + (start $start) + (func $start (type $0) + (call $called0) + ) + (func $called0 (type $0) + (call $called1) + ) + (func $called1 (type $0) + (nop) + ) + (func $called_indirect (type $0) + (nop) + ) + (func $exported (type $0) + (call $called2) + ) + (func $called2 (type $0) + (call $called2) + (call $called3) + ) + (func $called3 (type $0) + (call $called4) + ) + (func $called4 (type $0) + (call $called3) + ) +) +(module + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) +) +(module + (type $0 (func)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (elem (get_global $tableBase) $waka) + (data (get_global $memoryBase) "hello, world!") + (func $waka (type $0) + (nop) + ) +) +(module + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $1 (func (result i32))) + (type $2 (func)) + (import "env" "imported" (global $imported i32)) + (import "env" "_puts" (func $_puts (param i32) (result i32))) + (memory $0 0) + (global $int (mut i32) (get_global $imported)) + (global $set (mut i32) (i32.const 100)) + (global $exp_glob i32 (i32.const 600)) + (export "one" (func $one)) + (export "three" (func $three)) + (export "exp_glob" (global $exp_glob)) + (start $starter) + (func $one (type $1) (result i32) + (call $two) + ) + (func $two (type $1) (result i32) + (get_global $int) + ) + (func $three (type $2) + (call $four) + ) + (func $four (type $2) + (set_global $set + (i32.const 200) + ) + (drop + (call $_puts + (i32.const 300) + ) + ) + ) + (func $starter (type $2) + (nop) + ) +) diff --git a/test/passes/remove-unused-module-elements.wast b/test/passes/remove-unused-module-elements.wast new file mode 100644 index 000000000..eb071ee66 --- /dev/null +++ b/test/passes/remove-unused-module-elements.wast @@ -0,0 +1,96 @@ +(module + (memory 0) + (start $start) + (type $0 (func)) + (export "memory" (memory $0)) + (export "exported" $exported) + (table 1 1 anyfunc) + (elem (i32.const 0) $called_indirect) + (func $start (type $0) + (call $called0) + ) + (func $called0 (type $0) + (call $called1) + ) + (func $called1 (type $0) + (nop) + ) + (func $called_indirect (type $0) + (nop) + ) + (func $exported (type $0) + (call $called2) + ) + (func $called2 (type $0) + (call $called2) + (call $called3) + ) + (func $called3 (type $0) + (call $called4) + ) + (func $called4 (type $0) + (call $called3) + ) + (func $remove0 (type $0) + (call $remove1) + ) + (func $remove1 (type $0) + (nop) + ) + (func $remove2 (type $0) + (call $remove2) + ) + (func $remove3 (type $0) + (call $remove4) + ) + (func $remove4 (type $0) + (call $remove3) + ) +) +(module ;; leave the table and memory alone + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) +) +(module + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) ;; used in init + (import "env" "tableBase" (global $tableBase i32)) ;; used in init + (data (get_global $memoryBase) "hello, world!") + (elem (get_global $tableBase) $waka) + (func $waka) ;; used in table +) +(module ;; one is exported, and one->two->int global, whose init->imported + (import "env" "imported" (global $imported i32)) + (import "env" "forgetme" (global $forgetme i32)) + (import "env" "_puts" (func $_puts (param i32) (result i32))) + (import "env" "forget_puts" (func $forget_puts (param i32) (result i32))) + (global $int (mut i32) (get_global $imported)) + (global $set (mut i32) (i32.const 100)) + (global $forget_global (mut i32) (i32.const 500)) + (global $exp_glob i32 (i32.const 600)) + (export "one" (func $one)) + (export "three" (func $three)) + (export "exp_glob" (global $exp_glob)) + (start $starter) + (func $one (result i32) + (call $two) + ) + (func $two (result i32) + (get_global $int) + ) + (func $three + (call $four) + ) + (func $four + (set_global $set (i32.const 200)) + (drop (call $_puts (i32.const 300))) + ) + (func $forget_implemented + (nop) + ) + (func $starter + (nop) + ) +) + diff --git a/test/unit.fromasm b/test/unit.fromasm index 04ea35b7f..fcddb0b4b 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -7,11 +7,7 @@ (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$dd (func (param f64) (result f64))) (type $FUNCSIG$i (func (result i32))) - (import "global" "NaN" (global $t$asm2wasm$import f64)) - (import "global" "Infinity" (global $u$asm2wasm$import f64)) - (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) (import "env" "gb" (global $n$asm2wasm$import i32)) - (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "setTempRet0" (func $setTempRet0 (param i32) (result i32))) (import "env" "abort" (func $abort (param f64) (result f64))) (import "env" "print" (func $print (param i32))) @@ -26,13 +22,9 @@ (import "env" "tableBase" (global $tableBase i32)) (elem (get_global $tableBase) $big_negative $big_negative $big_negative $big_negative $w $w $importedDoubles $w $fr $cneg $fr $fr $fr $fr $fr $fr $vi $vi $vi $vi $vi $vi $vi $vi) (data (get_global $memoryBase) "unit.asm.js") - (global $t (mut f64) (get_global $t$asm2wasm$import)) - (global $u (mut f64) (get_global $u$asm2wasm$import)) (global $Int (mut i32) (i32.const 0)) (global $Double (mut f64) (f64.const 0)) - (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) (global $n (mut i32) (get_global $n$asm2wasm$import)) - (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) (export "big_negative" (func $big_negative)) (export "pick" (func $big_negative)) (export "doubleCompares" (func $doubleCompares)) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index f5a96144f..94f34c03d 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -5,11 +5,7 @@ (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$dd (func (param f64) (result f64))) (type $FUNCSIG$i (func (result i32))) - (import "global" "NaN" (global $t$asm2wasm$import f64)) - (import "global" "Infinity" (global $u$asm2wasm$import f64)) - (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) (import "env" "gb" (global $n$asm2wasm$import i32)) - (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "setTempRet0" (func $setTempRet0 (param i32) (result i32))) (import "env" "abort" (func $abort (param f64) (result f64))) (import "env" "print" (func $print (param i32))) @@ -21,13 +17,9 @@ (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) (elem (get_global $tableBase) $big_negative $big_negative $big_negative $big_negative $w $w $importedDoubles $w $fr $cneg $fr $fr $fr $fr $fr $fr $vi $vi $vi $vi $vi $vi $vi $vi) - (global $t (mut f64) (get_global $t$asm2wasm$import)) - (global $u (mut f64) (get_global $u$asm2wasm$import)) (global $Int (mut i32) (i32.const 0)) (global $Double (mut f64) (f64.const 0)) - (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) (global $n (mut i32) (get_global $n$asm2wasm$import)) - (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) (export "big_negative" (func $big_negative)) (export "pick" (func $big_negative)) (export "doubleCompares" (func $doubleCompares)) diff --git a/test/wasm-only.fromasm b/test/wasm-only.fromasm index adcc66137..1c5030527 100644 --- a/test/wasm-only.fromasm +++ b/test/wasm-only.fromasm @@ -12,6 +12,7 @@ (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) (data (get_global $memoryBase) "wasm-only.asm.js") + (global $tempRet0 (mut i32) (i32.const 0)) (export "test64" (func $test64)) (export "illegalParam" (func $legalstub$illegalParam)) (export "illegalResult" (func $legalstub$result)) @@ -397,7 +398,14 @@ (set_local $0 (call $result) ) - (unreachable) + (set_global $tempRet0 + (i32.wrap/i64 + (i64.shr_u + (get_local $0) + (i64.const 32) + ) + ) + ) (i32.wrap/i64 (get_local $0) ) @@ -424,7 +432,7 @@ ) (i64.shl (i64.extend_u/i32 - (unreachable) + (get_global $tempRet0) ) (i64.const 32) ) diff --git a/test/wasm-only.fromasm.imprecise b/test/wasm-only.fromasm.imprecise index def563598..4b129cdbe 100644 --- a/test/wasm-only.fromasm.imprecise +++ b/test/wasm-only.fromasm.imprecise @@ -11,6 +11,7 @@ (import "env" "table" (table 0 0 anyfunc)) (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) + (global $tempRet0 (mut i32) (i32.const 0)) (export "test64" (func $test64)) (export "illegalParam" (func $legalstub$illegalParam)) (export "illegalResult" (func $legalstub$result)) @@ -325,7 +326,14 @@ (set_local $0 (call $result) ) - (unreachable) + (set_global $tempRet0 + (i32.wrap/i64 + (i64.shr_u + (get_local $0) + (i64.const 32) + ) + ) + ) (i32.wrap/i64 (get_local $0) ) @@ -352,7 +360,7 @@ ) (i64.shl (i64.extend_u/i32 - (unreachable) + (get_global $tempRet0) ) (i64.const 32) ) diff --git a/test/wasm-only.fromasm.imprecise.no-opts b/test/wasm-only.fromasm.imprecise.no-opts index 1e818877c..9830e9b2c 100644 --- a/test/wasm-only.fromasm.imprecise.no-opts +++ b/test/wasm-only.fromasm.imprecise.no-opts @@ -11,6 +11,7 @@ (import "env" "table" (table 0 0 anyfunc)) (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) + (global $tempRet0 (mut i32) (i32.const 0)) (export "test64" (func $test64)) (export "illegalParam" (func $legalstub$illegalParam)) (export "illegalResult" (func $legalstub$illegalResult)) @@ -775,7 +776,14 @@ (set_local $0 (call $illegalResult) ) - (unreachable) + (set_global $tempRet0 + (i32.wrap/i64 + (i64.shr_u + (get_local $0) + (i64.const 32) + ) + ) + ) (i32.wrap/i64 (get_local $0) ) @@ -802,7 +810,7 @@ ) (i64.shl (i64.extend_u/i32 - (unreachable) + (get_global $tempRet0) ) (i64.const 32) ) diff --git a/test/wasm-only.fromasm.no-opts b/test/wasm-only.fromasm.no-opts index 1c3a0bf5c..9ecc9a1df 100644 --- a/test/wasm-only.fromasm.no-opts +++ b/test/wasm-only.fromasm.no-opts @@ -11,6 +11,7 @@ (import "env" "table" (table 0 0 anyfunc)) (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) + (global $tempRet0 (mut i32) (i32.const 0)) (export "test64" (func $test64)) (export "illegalParam" (func $legalstub$illegalParam)) (export "illegalResult" (func $legalstub$illegalResult)) @@ -823,7 +824,14 @@ (set_local $0 (call $illegalResult) ) - (unreachable) + (set_global $tempRet0 + (i32.wrap/i64 + (i64.shr_u + (get_local $0) + (i64.const 32) + ) + ) + ) (i32.wrap/i64 (get_local $0) ) @@ -850,7 +858,7 @@ ) (i64.shl (i64.extend_u/i32 - (unreachable) + (get_global $tempRet0) ) (i64.const 32) ) |