From e56aae74bbc8d283c70052b0ea93df42a733eb50 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Sat, 4 Feb 2017 21:45:53 -0800 Subject: [PATCH 01/17] rework handling of block and if types: when they have a type, do not remove it later, as it may be necessary due to wasm rules from the parent (e.g. the function fallthrough may need a block i32 even if the block ends in a return). at the end of asm2wasm, make sure to create the proper types for the function fallthrough, which is special (as asm2wasm doesn't emit other fallthroughs itself, not before optimization). rework how autodrop operates in order to work in this new scheme, by dropping things directly, not looking at higher scopes to see if used --- src/asm2wasm.h | 41 + src/ast_utils.h | 37 +- src/passes/CoalesceLocals.cpp | 2 +- src/passes/MergeBlocks.cpp | 4 +- src/wasm.h | 22 +- src/wasm/wasm.cpp | 6 + test/emcc_hello_world.fromasm | 472 +++---- test/emcc_hello_world.fromasm.imprecise | 472 +++---- ...emcc_hello_world.fromasm.imprecise.no-opts | 1104 ++++++++--------- test/emcc_hello_world.fromasm.no-opts | 1104 ++++++++--------- test/example/c-api-kitchen-sink.txt | 16 +- test/example/c-api-kitchen-sink.txt.txt | 8 +- test/min.fromasm.imprecise.no-opts | 28 +- test/min.fromasm.no-opts | 28 +- test/unit.fromasm | 72 +- test/unit.fromasm.imprecise | 72 +- test/unit.fromasm.imprecise.no-opts | 234 ++-- test/unit.fromasm.no-opts | 234 ++-- test/wasm-only.fromasm.imprecise.no-opts | 12 +- test/wasm-only.fromasm.no-opts | 12 +- 20 files changed, 2018 insertions(+), 1962 deletions(-) diff --git a/src/asm2wasm.h b/src/asm2wasm.h index eaf4f8c18eb..6eb1795bbd6 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -565,6 +565,8 @@ class Asm2WasmBuilder { } Function* processFunction(Ref ast); + + void fixFallthrough(Function* func); }; void Asm2WasmBuilder::processAsm(Ref ast) { @@ -2276,9 +2278,48 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { // cleanups/checks assert(breakStack.size() == 0 && continueStack.size() == 0); assert(parentLabel.isNull()); + // fix up the fallthrough return value. asm2wasm output is structured statements, + // but the wasm toplevel scope is a fallthrough that must have the same type as + // the function return value, if there is one. We must propage that type up + // as far as necessary, replacing unreachable types with concrete ones, e.g. + // + // block + // if + // condition + // return 1 + // return 2 + // + // then naively they all have unreachable type, but if the function returns i32, + // the block *and* the if must be i32 + fixFallthrough(function); return function; } +void Asm2WasmBuilder::fixFallthrough(Function* func) { + if (func->result == none) return; + std::vector work; + work.push_back(func->body); + while (work.size() > 0) { + auto* curr = work.back(); + work.pop_back(); + if (curr->type != unreachable) continue; + if (auto* block = curr->dynCast()) { + block->type = func->result; + if (block->list.size() > 0) { + work.push_back(block->list.back()); + } + } else if (auto* loop = curr->dynCast()) { + loop->type = func->result; + work.push_back(loop->body); + } else if (auto* iff = curr->dynCast()) { + assert(iff->ifFalse); // must be an if-else + iff->type = func->result; + work.push_back(iff->ifTrue); + work.push_back(iff->ifFalse); + } + } +} + } // namespace wasm #endif // wasm_asm2wasm_h diff --git a/src/ast_utils.h b/src/ast_utils.h index 2a151d8f71a..f20143a54c1 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -335,26 +335,6 @@ struct AutoDrop : public WalkerPasstype)) { - expressionStack.push_back(child); - if (!ExpressionAnalyzer::isResultUsed(expressionStack, getFunction()) && !ExpressionAnalyzer::isResultDropped(expressionStack)) { - child = Builder(*getModule()).makeDrop(child); - acted = true; - } - expressionStack.pop_back(); - } - return acted; - } - - void reFinalize() { - for (int i = int(expressionStack.size()) - 1; i >= 0; i--) { - auto* curr = expressionStack[i]; - ReFinalize().visit(curr); - } - } - void visitBlock(Block* curr) { if (curr->list.size() == 0) return; for (Index i = 0; i < curr->list.size() - 1; i++) { @@ -363,21 +343,16 @@ struct AutoDrop : public WalkerPasslist[i] = Builder(*getModule()).makeDrop(child); } } - if (maybeDrop(curr->list.back())) { - reFinalize(); - assert(curr->type == none); - } } void visitIf(If* curr) { - bool acted = false; - if (maybeDrop(curr->ifTrue)) acted = true; - if (curr->ifFalse) { - if (maybeDrop(curr->ifFalse)) acted = true; + if (isConcreteWasmType(curr->type)) return; // ok to return a value, no need to drop + // this is an if without an else, or an if-else with no return value - drop any values + if (isConcreteWasmType(curr->ifTrue->type)) { + curr->ifTrue = Builder(*getModule()).makeDrop(curr->ifTrue); } - if (acted) { - reFinalize(); - assert(curr->type == none); + if (curr->ifFalse && isConcreteWasmType(curr->ifFalse->type)) { + curr->ifFalse = Builder(*getModule()).makeDrop(curr->ifFalse); } } diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp index ce9b2d291c1..943dae04e73 100644 --- a/src/passes/CoalesceLocals.cpp +++ b/src/passes/CoalesceLocals.cpp @@ -632,7 +632,7 @@ static void removeIfCopy(Expression** origin, SetLocal* set, If* iff, Expression if (!iff->ifTrue) { Builder(*module).flip(iff); } - iff->finalize(); + iff->type = none; } } diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index 383837beb26..273b930f74f 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -170,7 +170,7 @@ static void optimizeBlock(Block* curr, Module* module) { // reuse the drop drop->value = child->list.back(); child->list.back() = drop; - child->finalize(); + child->type = none; curr->list[i] = child; more = true; changed = true; @@ -226,7 +226,7 @@ struct MergeBlocks : public WalkerPasslist.back() = curr; - block->finalize(); // last block element was our input, and is now our output, which may differ TODO optimize + block->type = curr->type; // last block element was our input, and is now our output replaceCurrent(block); return block; } else { diff --git a/src/wasm.h b/src/wasm.h index 75d6a174c52..63d9401e8c3 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -959,7 +959,9 @@ class Nop : public SpecificExpression { class Block : public SpecificExpression { public: - Block(MixedArena& allocator) : list(allocator) {} + Block(MixedArena& allocator) : list(allocator) { + type = unreachable; + } Name name; ExpressionList list; @@ -969,13 +971,17 @@ class Block : public SpecificExpression { // this does is to set the type to unreachable in the cases that is needed. void finalize(WasmType type_); - // set the type purely based on its contents. this scans the block, so it is not fast + // set the type purely based on its contents. this scans the block, so it is not fast. + // if the type is already something concrete, we do not alter it, so that if our + // contents to not imply a result but the parent does, then we remain valid void finalize(); }; class If : public SpecificExpression { public: - If() : ifFalse(nullptr) {} + If() : ifFalse(nullptr) { + type = unreachable; + } If(MixedArena& allocator) : If() {} Expression* condition; @@ -988,13 +994,17 @@ class If : public SpecificExpression { void finalize(WasmType type_); // set the type purely based on its contents. + // if the type is already something concrete, we do not alter it, so that if our + // contents to not imply a result but the parent does, then we remain valid void finalize(); }; class Loop : public SpecificExpression { public: - Loop() {} - Loop(MixedArena& allocator) {} + Loop() { + type = unreachable; + } + Loop(MixedArena& allocator) : Loop() {} Name name; Expression* body; @@ -1005,6 +1015,8 @@ class Loop : public SpecificExpression { void finalize(WasmType type_); // set the type purely based on its contents. + // if the type is already something concrete, we do not alter it, so that if our + // contents to not imply a result but the parent does, then we remain valid void finalize(); }; diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index cf58949de1b..eb34c78eda7 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -145,6 +145,8 @@ void Block::finalize(WasmType type_) { } void Block::finalize() { + // if already set to a concrete value, keep it + if (isConcreteWasmType(type)) return; if (!name.is()) { // nothing branches here, so this is easy if (list.size() > 0) { @@ -167,6 +169,8 @@ void If::finalize(WasmType type_) { } void If::finalize() { + // if already set to a concrete value, keep it + if (isConcreteWasmType(type)) return; if (condition->type == unreachable) { type = unreachable; } else if (ifFalse) { @@ -192,6 +196,8 @@ void Loop::finalize(WasmType type_) { } void Loop::finalize() { + // if already set to a concrete value, keep it + if (isConcreteWasmType(type)) return; type = body->type; } diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index 690c869ca4a..044c001eb72 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -6006,16 +6006,16 @@ (block $do-once107 (if (get_local $32) - (block - (br_if $do-once107 - (i32.and - (i32.load - (get_local $0) + (drop + (block i32 + (br_if $do-once107 + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) - ) - (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -6137,217 +6137,217 @@ (i32.const 0) ) ) - (block - (set_local $9 - (select - (get_local $9) - (i32.add - (get_local $12) - (i32.const 4) - ) - (get_local $25) - ) - ) - (if - (i32.gt_s - (get_local $5) - (i32.const -1) - ) - (block - (set_local $17 - (i32.eqz - (get_local $20) + (drop + (block i32 + (set_local $9 + (select + (get_local $9) + (i32.add + (get_local $12) + (i32.const 4) ) + (get_local $25) ) - (set_local $6 - (get_local $12) - ) - (set_local $7 + ) + (if + (i32.gt_s (get_local $5) + (i32.const -1) ) - (loop $while-in114 - (if - (i32.eq - (tee_local $5 - (call $_fmt_u - (i32.load - (get_local $6) - ) - (i32.const 0) - (get_local $30) - ) - ) - (get_local $30) - ) - (block - (i32.store8 - (get_local $35) - (i32.const 48) - ) - (set_local $5 - (get_local $35) - ) + (block + (set_local $17 + (i32.eqz + (get_local $20) ) ) - (block $do-once115 + (set_local $6 + (get_local $12) + ) + (set_local $7 + (get_local $5) + ) + (loop $while-in114 (if (i32.eq - (get_local $6) - (get_local $12) + (tee_local $5 + (call $_fmt_u + (i32.load + (get_local $6) + ) + (i32.const 0) + (get_local $30) + ) + ) + (get_local $30) ) (block - (if - (i32.eqz - (i32.and - (i32.load + (i32.store8 + (get_local $35) + (i32.const 48) + ) + (set_local $5 + (get_local $35) + ) + ) + ) + (block $do-once115 + (if + (i32.eq + (get_local $6) + (get_local $12) + ) + (block + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) + ) + ) + (drop + (call $___fwritex + (get_local $5) + (i32.const 1) (get_local $0) ) - (i32.const 32) ) ) - (drop - (call $___fwritex + (set_local $5 + (i32.add (get_local $5) (i32.const 1) - (get_local $0) ) ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (br_if $do-once115 - (i32.or - (i32.and - (get_local $17) - (i32.lt_s - (get_local $7) - (i32.const 1) + (br_if $do-once115 + (i32.or + (i32.and + (get_local $17) + (i32.lt_s + (get_local $7) + (i32.const 1) + ) ) - ) - (i32.and - (i32.load - (get_local $0) + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) ) - ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $0) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $0) + ) ) ) - ) - (block - (br_if $do-once115 - (i32.le_u - (get_local $5) - (get_local $23) + (block + (br_if $do-once115 + (i32.le_u + (get_local $5) + (get_local $23) + ) ) - ) - (loop $while-in118 - (i32.store8 - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -1) + (loop $while-in118 + (i32.store8 + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -1) + ) ) + (i32.const 48) ) - (i32.const 48) - ) - (br_if $while-in118 - (i32.gt_u - (get_local $5) - (get_local $23) + (br_if $while-in118 + (i32.gt_u + (get_local $5) + (get_local $23) + ) ) ) ) ) ) - ) - (set_local $8 - (i32.sub - (get_local $43) - (get_local $5) + (set_local $8 + (i32.sub + (get_local $43) + (get_local $5) + ) ) - ) - (if - (i32.eqz - (i32.and - (i32.load - (get_local $0) + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) - ) - (drop - (call $___fwritex - (get_local $5) - (select - (get_local $8) - (get_local $7) - (i32.gt_s - (get_local $7) + (drop + (call $___fwritex + (get_local $5) + (select (get_local $8) + (get_local $7) + (i32.gt_s + (get_local $7) + (get_local $8) + ) ) + (get_local $0) ) - (get_local $0) ) ) - ) - (br_if $while-in114 - (i32.and - (i32.lt_u - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 4) + (br_if $while-in114 + (i32.and + (i32.lt_u + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 4) + ) ) + (get_local $9) ) - (get_local $9) - ) - (i32.gt_s - (tee_local $7 - (i32.sub - (get_local $7) - (get_local $8) + (i32.gt_s + (tee_local $7 + (i32.sub + (get_local $7) + (get_local $8) + ) ) + (i32.const -1) ) - (i32.const -1) ) ) - ) - (set_local $5 - (get_local $7) + (set_local $5 + (get_local $7) + ) ) ) ) - ) - (call $_pad - (get_local $0) - (i32.const 48) - (i32.add - (get_local $5) + (call $_pad + (get_local $0) + (i32.const 48) + (i32.add + (get_local $5) + (i32.const 18) + ) (i32.const 18) + (i32.const 0) ) - (i32.const 18) - (i32.const 0) - ) - (br_if $do-once99 - (i32.and - (i32.load - (get_local $0) + (br_if $do-once99 + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) - ) - (drop (call $___fwritex (get_local $18) (i32.sub @@ -7762,77 +7762,93 @@ ) ) ) - (block - (drop - (call $_memset - (get_local $6) - (get_local $1) - (select - (i32.const 256) - (tee_local $5 - (i32.sub - (get_local $2) - (get_local $3) - ) - ) - (i32.gt_u - (get_local $5) + (drop + (block i32 + (drop + (call $_memset + (get_local $6) + (get_local $1) + (select (i32.const 256) + (tee_local $5 + (i32.sub + (get_local $2) + (get_local $3) + ) + ) + (i32.gt_u + (get_local $5) + (i32.const 256) + ) ) ) ) - ) - (set_local $4 - (i32.eqz - (i32.and - (tee_local $1 - (i32.load - (get_local $0) + (set_local $4 + (i32.eqz + (i32.and + (tee_local $1 + (i32.load + (get_local $0) + ) ) + (i32.const 32) ) - (i32.const 32) ) ) - ) - (if - (i32.gt_u - (get_local $5) - (i32.const 255) - ) - (block - (loop $while-in - (if - (get_local $4) - (block - (drop - (call $___fwritex - (get_local $6) - (i32.const 256) - (get_local $0) + (if + (i32.gt_u + (get_local $5) + (i32.const 255) + ) + (block + (loop $while-in + (if + (get_local $4) + (block + (drop + (call $___fwritex + (get_local $6) + (i32.const 256) + (get_local $0) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) ) ) - (set_local $1 - (i32.load - (get_local $0) + ) + (set_local $4 + (i32.eqz + (i32.and + (get_local $1) + (i32.const 32) ) ) ) + (br_if $while-in + (i32.gt_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -256) + ) + ) + (i32.const 255) + ) + ) ) - (set_local $4 + (br_if $do-once (i32.eqz - (i32.and - (get_local $1) - (i32.const 32) - ) + (get_local $4) ) ) - (br_if $while-in - (i32.gt_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -256) - ) + (set_local $5 + (i32.and + (i32.sub + (get_local $2) + (get_local $3) ) (i32.const 255) ) @@ -7843,23 +7859,7 @@ (get_local $4) ) ) - (set_local $5 - (i32.and - (i32.sub - (get_local $2) - (get_local $3) - ) - (i32.const 255) - ) - ) ) - (br_if $do-once - (i32.eqz - (get_local $4) - ) - ) - ) - (drop (call $___fwritex (get_local $6) (get_local $5) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index 2cd23ba1d6d..8ac84a8be7b 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -5992,16 +5992,16 @@ (block $do-once107 (if (get_local $32) - (block - (br_if $do-once107 - (i32.and - (i32.load - (get_local $0) + (drop + (block i32 + (br_if $do-once107 + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) - ) - (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -6123,217 +6123,217 @@ (i32.const 0) ) ) - (block - (set_local $9 - (select - (get_local $9) - (i32.add - (get_local $12) - (i32.const 4) - ) - (get_local $25) - ) - ) - (if - (i32.gt_s - (get_local $5) - (i32.const -1) - ) - (block - (set_local $17 - (i32.eqz - (get_local $20) + (drop + (block i32 + (set_local $9 + (select + (get_local $9) + (i32.add + (get_local $12) + (i32.const 4) ) + (get_local $25) ) - (set_local $6 - (get_local $12) - ) - (set_local $7 + ) + (if + (i32.gt_s (get_local $5) + (i32.const -1) ) - (loop $while-in114 - (if - (i32.eq - (tee_local $5 - (call $_fmt_u - (i32.load - (get_local $6) - ) - (i32.const 0) - (get_local $30) - ) - ) - (get_local $30) - ) - (block - (i32.store8 - (get_local $35) - (i32.const 48) - ) - (set_local $5 - (get_local $35) - ) + (block + (set_local $17 + (i32.eqz + (get_local $20) ) ) - (block $do-once115 + (set_local $6 + (get_local $12) + ) + (set_local $7 + (get_local $5) + ) + (loop $while-in114 (if (i32.eq - (get_local $6) - (get_local $12) + (tee_local $5 + (call $_fmt_u + (i32.load + (get_local $6) + ) + (i32.const 0) + (get_local $30) + ) + ) + (get_local $30) ) (block - (if - (i32.eqz - (i32.and - (i32.load + (i32.store8 + (get_local $35) + (i32.const 48) + ) + (set_local $5 + (get_local $35) + ) + ) + ) + (block $do-once115 + (if + (i32.eq + (get_local $6) + (get_local $12) + ) + (block + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) + ) + ) + (drop + (call $___fwritex + (get_local $5) + (i32.const 1) (get_local $0) ) - (i32.const 32) ) ) - (drop - (call $___fwritex + (set_local $5 + (i32.add (get_local $5) (i32.const 1) - (get_local $0) ) ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (br_if $do-once115 - (i32.or - (i32.and - (get_local $17) - (i32.lt_s - (get_local $7) - (i32.const 1) + (br_if $do-once115 + (i32.or + (i32.and + (get_local $17) + (i32.lt_s + (get_local $7) + (i32.const 1) + ) ) - ) - (i32.and - (i32.load - (get_local $0) + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) ) - ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $0) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $0) + ) ) ) - ) - (block - (br_if $do-once115 - (i32.le_u - (get_local $5) - (get_local $23) + (block + (br_if $do-once115 + (i32.le_u + (get_local $5) + (get_local $23) + ) ) - ) - (loop $while-in118 - (i32.store8 - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -1) + (loop $while-in118 + (i32.store8 + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -1) + ) ) + (i32.const 48) ) - (i32.const 48) - ) - (br_if $while-in118 - (i32.gt_u - (get_local $5) - (get_local $23) + (br_if $while-in118 + (i32.gt_u + (get_local $5) + (get_local $23) + ) ) ) ) ) ) - ) - (set_local $8 - (i32.sub - (get_local $43) - (get_local $5) + (set_local $8 + (i32.sub + (get_local $43) + (get_local $5) + ) ) - ) - (if - (i32.eqz - (i32.and - (i32.load - (get_local $0) + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) - ) - (drop - (call $___fwritex - (get_local $5) - (select - (get_local $8) - (get_local $7) - (i32.gt_s - (get_local $7) + (drop + (call $___fwritex + (get_local $5) + (select (get_local $8) + (get_local $7) + (i32.gt_s + (get_local $7) + (get_local $8) + ) ) + (get_local $0) ) - (get_local $0) ) ) - ) - (br_if $while-in114 - (i32.and - (i32.lt_u - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 4) + (br_if $while-in114 + (i32.and + (i32.lt_u + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 4) + ) ) + (get_local $9) ) - (get_local $9) - ) - (i32.gt_s - (tee_local $7 - (i32.sub - (get_local $7) - (get_local $8) + (i32.gt_s + (tee_local $7 + (i32.sub + (get_local $7) + (get_local $8) + ) ) + (i32.const -1) ) - (i32.const -1) ) ) - ) - (set_local $5 - (get_local $7) + (set_local $5 + (get_local $7) + ) ) ) ) - ) - (call $_pad - (get_local $0) - (i32.const 48) - (i32.add - (get_local $5) + (call $_pad + (get_local $0) + (i32.const 48) + (i32.add + (get_local $5) + (i32.const 18) + ) (i32.const 18) + (i32.const 0) ) - (i32.const 18) - (i32.const 0) - ) - (br_if $do-once99 - (i32.and - (i32.load - (get_local $0) + (br_if $do-once99 + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 32) ) - (i32.const 32) ) - ) - (drop (call $___fwritex (get_local $18) (i32.sub @@ -7748,77 +7748,93 @@ ) ) ) - (block - (drop - (call $_memset - (get_local $6) - (get_local $1) - (select - (i32.const 256) - (tee_local $5 - (i32.sub - (get_local $2) - (get_local $3) - ) - ) - (i32.gt_u - (get_local $5) + (drop + (block i32 + (drop + (call $_memset + (get_local $6) + (get_local $1) + (select (i32.const 256) + (tee_local $5 + (i32.sub + (get_local $2) + (get_local $3) + ) + ) + (i32.gt_u + (get_local $5) + (i32.const 256) + ) ) ) ) - ) - (set_local $4 - (i32.eqz - (i32.and - (tee_local $1 - (i32.load - (get_local $0) + (set_local $4 + (i32.eqz + (i32.and + (tee_local $1 + (i32.load + (get_local $0) + ) ) + (i32.const 32) ) - (i32.const 32) ) ) - ) - (if - (i32.gt_u - (get_local $5) - (i32.const 255) - ) - (block - (loop $while-in - (if - (get_local $4) - (block - (drop - (call $___fwritex - (get_local $6) - (i32.const 256) - (get_local $0) + (if + (i32.gt_u + (get_local $5) + (i32.const 255) + ) + (block + (loop $while-in + (if + (get_local $4) + (block + (drop + (call $___fwritex + (get_local $6) + (i32.const 256) + (get_local $0) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) ) ) - (set_local $1 - (i32.load - (get_local $0) + ) + (set_local $4 + (i32.eqz + (i32.and + (get_local $1) + (i32.const 32) ) ) ) + (br_if $while-in + (i32.gt_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -256) + ) + ) + (i32.const 255) + ) + ) ) - (set_local $4 + (br_if $do-once (i32.eqz - (i32.and - (get_local $1) - (i32.const 32) - ) + (get_local $4) ) ) - (br_if $while-in - (i32.gt_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -256) - ) + (set_local $5 + (i32.and + (i32.sub + (get_local $2) + (get_local $3) ) (i32.const 255) ) @@ -7829,23 +7845,7 @@ (get_local $4) ) ) - (set_local $5 - (i32.and - (i32.sub - (get_local $2) - (get_local $3) - ) - (i32.const 255) - ) - ) ) - (br_if $do-once - (i32.eqz - (get_local $4) - ) - ) - ) - (drop (call $___fwritex (get_local $6) (get_local $5) diff --git a/test/emcc_hello_world.fromasm.imprecise.no-opts b/test/emcc_hello_world.fromasm.imprecise.no-opts index b4dcbcaa3a6..6d719fe01e4 100644 --- a/test/emcc_hello_world.fromasm.imprecise.no-opts +++ b/test/emcc_hello_world.fromasm.imprecise.no-opts @@ -4523,31 +4523,31 @@ ) (if (get_local $$cmp4) - (block - (set_local $$seek - (i32.add - (get_local $$f) - (i32.const 40) + (drop + (block i32 + (set_local $$seek + (i32.add + (get_local $$f) + (i32.const 40) + ) ) - ) - (set_local $$6 - (i32.load - (get_local $$seek) + (set_local $$6 + (i32.load + (get_local $$seek) + ) ) - ) - (set_local $$sub$ptr$lhs$cast - (get_local $$4) - ) - (set_local $$sub$ptr$rhs$cast - (get_local $$5) - ) - (set_local $$sub$ptr$sub - (i32.sub - (get_local $$sub$ptr$lhs$cast) - (get_local $$sub$ptr$rhs$cast) + (set_local $$sub$ptr$lhs$cast + (get_local $$4) + ) + (set_local $$sub$ptr$rhs$cast + (get_local $$5) + ) + (set_local $$sub$ptr$sub + (i32.sub + (get_local $$sub$ptr$lhs$cast) + (get_local $$sub$ptr$rhs$cast) + ) ) - ) - (drop (call_indirect $FUNCSIG$iiii (get_local $$f) (get_local $$sub$ptr$sub) @@ -12250,17 +12250,17 @@ ) (if (get_local $$tobool$i$443$i) - (block - (set_local $$sub$ptr$rhs$cast695$i - (get_local $$s668$1$i) - ) - (set_local $$sub$ptr$sub696$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast695$i) + (drop + (block i32 + (set_local $$sub$ptr$rhs$cast695$i + (get_local $$s668$1$i) + ) + (set_local $$sub$ptr$sub696$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast695$i) + ) ) - ) - (drop (call $___fwritex (get_local $$s668$1$i) (get_local $$sub$ptr$sub696$i) @@ -12307,31 +12307,31 @@ (i32.eqz (get_local $$251) ) - (block - (set_local $$252 - (i32.load - (get_local $$f) + (drop + (block i32 + (set_local $$252 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$and$i$448$i - (i32.and - (get_local $$252) - (i32.const 32) + (set_local $$and$i$448$i + (i32.and + (get_local $$252) + (i32.const 32) + ) ) - ) - (set_local $$tobool$i$449$i - (i32.eq - (get_local $$and$i$448$i) - (i32.const 0) + (set_local $$tobool$i$449$i + (i32.eq + (get_local $$and$i$448$i) + (i32.const 0) + ) ) - ) - (if - (i32.eqz - (get_local $$tobool$i$449$i) + (if + (i32.eqz + (get_local $$tobool$i$449$i) + ) + (br $do-once107) ) - (br $do-once107) - ) - (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -12451,21 +12451,21 @@ ) (if (get_local $$tobool$i$455$i) - (block - (set_local $$cmp727$i - (i32.gt_s - (get_local $$p$addr$4489$i) - (i32.const 9) + (drop + (block i32 + (set_local $$cmp727$i + (i32.gt_s + (get_local $$p$addr$4489$i) + (i32.const 9) + ) ) - ) - (set_local $$cond732$i - (if i32 - (get_local $$cmp727$i) - (i32.const 9) - (get_local $$p$addr$4489$i) + (set_local $$cond732$i + (if i32 + (get_local $$cmp727$i) + (i32.const 9) + (get_local $$p$addr$4489$i) + ) ) - ) - (drop (call $___fwritex (get_local $$s715$0$lcssa$i) (get_local $$cond732$i) @@ -12543,386 +12543,386 @@ (i32.const 0) ) ) - (block - (set_local $$add$ptr742$i - (i32.add - (get_local $$a$9$ph$i) - (i32.const 4) - ) - ) - (set_local $$z$7$add$ptr742$i - (if i32 - (get_local $$cmp450$lcssa$i) - (get_local $$z$7$i$lcssa) - (get_local $$add$ptr742$i) - ) - ) - (set_local $$cmp748$499$i - (i32.gt_s - (get_local $$p$addr$3$i) - (i32.const -1) - ) - ) - (if - (get_local $$cmp748$499$i) - (block - (set_local $$tobool781$i - (i32.eq - (get_local $$and610$pre$phi$iZ2D) - (i32.const 0) - ) - ) - (set_local $$d$7500$i + (drop + (block i32 + (set_local $$add$ptr742$i + (i32.add (get_local $$a$9$ph$i) + (i32.const 4) + ) + ) + (set_local $$z$7$add$ptr742$i + (if i32 + (get_local $$cmp450$lcssa$i) + (get_local $$z$7$i$lcssa) + (get_local $$add$ptr742$i) ) - (set_local $$p$addr$5501$i + ) + (set_local $$cmp748$499$i + (i32.gt_s (get_local $$p$addr$3$i) + (i32.const -1) ) - (loop $while-in114 - (block $while-out113 - (set_local $$258 - (i32.load - (get_local $$d$7500$i) - ) - ) - (set_local $$259 - (call $_fmt_u - (get_local $$258) - (i32.const 0) - (get_local $$add$ptr671$i) - ) - ) - (set_local $$cmp760$i - (i32.eq - (get_local $$259) - (get_local $$add$ptr671$i) - ) + ) + (if + (get_local $$cmp748$499$i) + (block + (set_local $$tobool781$i + (i32.eq + (get_local $$and610$pre$phi$iZ2D) + (i32.const 0) ) - (if - (get_local $$cmp760$i) - (block - (i32.store8 - (get_local $$incdec$ptr689$i) - (i32.const 48) - ) - (set_local $$s753$0$i - (get_local $$incdec$ptr689$i) + ) + (set_local $$d$7500$i + (get_local $$a$9$ph$i) + ) + (set_local $$p$addr$5501$i + (get_local $$p$addr$3$i) + ) + (loop $while-in114 + (block $while-out113 + (set_local $$258 + (i32.load + (get_local $$d$7500$i) ) ) - (set_local $$s753$0$i - (get_local $$259) + (set_local $$259 + (call $_fmt_u + (get_local $$258) + (i32.const 0) + (get_local $$add$ptr671$i) + ) ) - ) - (set_local $$cmp765$i - (i32.eq - (get_local $$d$7500$i) - (get_local $$a$9$ph$i) + (set_local $$cmp760$i + (i32.eq + (get_local $$259) + (get_local $$add$ptr671$i) + ) ) - ) - (block $do-once115 (if - (get_local $$cmp765$i) + (get_local $$cmp760$i) (block - (set_local $$incdec$ptr776$i - (i32.add - (get_local $$s753$0$i) - (i32.const 1) - ) - ) - (set_local $$260 - (i32.load - (get_local $$f) - ) - ) - (set_local $$and$i$460$i - (i32.and - (get_local $$260) - (i32.const 32) - ) + (i32.store8 + (get_local $$incdec$ptr689$i) + (i32.const 48) ) - (set_local $$tobool$i$461$i - (i32.eq - (get_local $$and$i$460$i) - (i32.const 0) - ) + (set_local $$s753$0$i + (get_local $$incdec$ptr689$i) ) - (if - (get_local $$tobool$i$461$i) - (drop - (call $___fwritex + ) + (set_local $$s753$0$i + (get_local $$259) + ) + ) + (set_local $$cmp765$i + (i32.eq + (get_local $$d$7500$i) + (get_local $$a$9$ph$i) + ) + ) + (block $do-once115 + (if + (get_local $$cmp765$i) + (block + (set_local $$incdec$ptr776$i + (i32.add (get_local $$s753$0$i) (i32.const 1) - (get_local $$f) ) ) - ) - (set_local $$cmp777$i - (i32.lt_s - (get_local $$p$addr$5501$i) - (i32.const 1) + (set_local $$260 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$or$cond401$i - (i32.and - (get_local $$tobool781$i) - (get_local $$cmp777$i) + (set_local $$and$i$460$i + (i32.and + (get_local $$260) + (i32.const 32) + ) ) - ) - (if - (get_local $$or$cond401$i) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) + (set_local $$tobool$i$461$i + (i32.eq + (get_local $$and$i$460$i) + (i32.const 0) ) - (br $do-once115) ) - ) - (set_local $$261 - (i32.load - (get_local $$f) + (if + (get_local $$tobool$i$461$i) + (drop + (call $___fwritex + (get_local $$s753$0$i) + (i32.const 1) + (get_local $$f) + ) + ) ) - ) - (set_local $$and$i$466$i - (i32.and - (get_local $$261) - (i32.const 32) + (set_local $$cmp777$i + (i32.lt_s + (get_local $$p$addr$5501$i) + (i32.const 1) + ) ) - ) - (set_local $$tobool$i$467$i - (i32.eq - (get_local $$and$i$466$i) - (i32.const 0) + (set_local $$or$cond401$i + (i32.and + (get_local $$tobool781$i) + (get_local $$cmp777$i) + ) ) - ) - (if - (i32.eqz - (get_local $$tobool$i$467$i) + (if + (get_local $$or$cond401$i) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) + ) + (br $do-once115) + ) ) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) + (set_local $$261 + (i32.load + (get_local $$f) ) - (br $do-once115) ) - ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $$f) + (set_local $$and$i$466$i + (i32.and + (get_local $$261) + (i32.const 32) + ) ) - ) - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) - ) - ) - (block - (set_local $$cmp770$495$i - (i32.gt_u - (get_local $$s753$0$i) - (get_local $$buf$i) + (set_local $$tobool$i$467$i + (i32.eq + (get_local $$and$i$466$i) + (i32.const 0) + ) ) - ) - (if - (get_local $$cmp770$495$i) - (set_local $$s753$1496$i - (get_local $$s753$0$i) + (if + (i32.eqz + (get_local $$tobool$i$467$i) + ) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) + ) + (br $do-once115) + ) ) - (block - (set_local $$s753$2$i - (get_local $$s753$0$i) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $$f) ) - (br $do-once115) + ) + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) ) ) - (loop $while-in118 - (block $while-out117 - (set_local $$incdec$ptr773$i - (i32.add - (get_local $$s753$1496$i) - (i32.const -1) - ) + (block + (set_local $$cmp770$495$i + (i32.gt_u + (get_local $$s753$0$i) + (get_local $$buf$i) ) - (i32.store8 - (get_local $$incdec$ptr773$i) - (i32.const 48) + ) + (if + (get_local $$cmp770$495$i) + (set_local $$s753$1496$i + (get_local $$s753$0$i) ) - (set_local $$cmp770$i - (i32.gt_u - (get_local $$incdec$ptr773$i) - (get_local $$buf$i) + (block + (set_local $$s753$2$i + (get_local $$s753$0$i) ) + (br $do-once115) ) - (if - (get_local $$cmp770$i) - (set_local $$s753$1496$i + ) + (loop $while-in118 + (block $while-out117 + (set_local $$incdec$ptr773$i + (i32.add + (get_local $$s753$1496$i) + (i32.const -1) + ) + ) + (i32.store8 (get_local $$incdec$ptr773$i) + (i32.const 48) ) - (block - (set_local $$s753$2$i + (set_local $$cmp770$i + (i32.gt_u (get_local $$incdec$ptr773$i) + (get_local $$buf$i) ) - (br $while-out117) ) + (if + (get_local $$cmp770$i) + (set_local $$s753$1496$i + (get_local $$incdec$ptr773$i) + ) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr773$i) + ) + (br $while-out117) + ) + ) + (br $while-in118) ) - (br $while-in118) ) ) ) ) - ) - (set_local $$sub$ptr$rhs$cast788$i - (get_local $$s753$2$i) - ) - (set_local $$sub$ptr$sub789$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast788$i) - ) - ) - (set_local $$262 - (i32.load - (get_local $$f) + (set_local $$sub$ptr$rhs$cast788$i + (get_local $$s753$2$i) ) - ) - (set_local $$and$i$472$i - (i32.and - (get_local $$262) - (i32.const 32) + (set_local $$sub$ptr$sub789$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast788$i) + ) ) - ) - (set_local $$tobool$i$473$i - (i32.eq - (get_local $$and$i$472$i) - (i32.const 0) + (set_local $$262 + (i32.load + (get_local $$f) + ) ) - ) - (if - (get_local $$tobool$i$473$i) - (block - (set_local $$cmp790$i - (i32.gt_s - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) + (set_local $$and$i$472$i + (i32.and + (get_local $$262) + (i32.const 32) ) - (set_local $$cond800$i - (if i32 - (get_local $$cmp790$i) - (get_local $$sub$ptr$sub789$i) - (get_local $$p$addr$5501$i) - ) + ) + (set_local $$tobool$i$473$i + (i32.eq + (get_local $$and$i$472$i) + (i32.const 0) ) + ) + (if + (get_local $$tobool$i$473$i) (drop - (call $___fwritex - (get_local $$s753$2$i) - (get_local $$cond800$i) - (get_local $$f) + (block i32 + (set_local $$cmp790$i + (i32.gt_s + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) + ) + ) + (set_local $$cond800$i + (if i32 + (get_local $$cmp790$i) + (get_local $$sub$ptr$sub789$i) + (get_local $$p$addr$5501$i) + ) + ) + (call $___fwritex + (get_local $$s753$2$i) + (get_local $$cond800$i) + (get_local $$f) + ) ) ) ) - ) - (set_local $$sub806$i - (i32.sub - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) - ) - (set_local $$incdec$ptr808$i - (i32.add - (get_local $$d$7500$i) - (i32.const 4) - ) - ) - (set_local $$cmp745$i - (i32.lt_u - (get_local $$incdec$ptr808$i) - (get_local $$z$7$add$ptr742$i) - ) - ) - (set_local $$cmp748$i - (i32.gt_s - (get_local $$sub806$i) - (i32.const -1) + (set_local $$sub806$i + (i32.sub + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) + ) ) - ) - (set_local $$263 - (i32.and - (get_local $$cmp745$i) - (get_local $$cmp748$i) + (set_local $$incdec$ptr808$i + (i32.add + (get_local $$d$7500$i) + (i32.const 4) + ) ) - ) - (if - (get_local $$263) - (block - (set_local $$d$7500$i + (set_local $$cmp745$i + (i32.lt_u (get_local $$incdec$ptr808$i) + (get_local $$z$7$add$ptr742$i) ) - (set_local $$p$addr$5501$i + ) + (set_local $$cmp748$i + (i32.gt_s (get_local $$sub806$i) + (i32.const -1) ) ) - (block - (set_local $$p$addr$5$lcssa$i - (get_local $$sub806$i) + (set_local $$263 + (i32.and + (get_local $$cmp745$i) + (get_local $$cmp748$i) + ) + ) + (if + (get_local $$263) + (block + (set_local $$d$7500$i + (get_local $$incdec$ptr808$i) + ) + (set_local $$p$addr$5501$i + (get_local $$sub806$i) + ) + ) + (block + (set_local $$p$addr$5$lcssa$i + (get_local $$sub806$i) + ) + (br $while-out113) ) - (br $while-out113) ) + (br $while-in114) ) - (br $while-in114) ) ) + (set_local $$p$addr$5$lcssa$i + (get_local $$p$addr$3$i) + ) ) - (set_local $$p$addr$5$lcssa$i - (get_local $$p$addr$3$i) + (set_local $$add810$i + (i32.add + (get_local $$p$addr$5$lcssa$i) + (i32.const 18) + ) ) - ) - (set_local $$add810$i - (i32.add - (get_local $$p$addr$5$lcssa$i) + (call $_pad + (get_local $$f) + (i32.const 48) + (get_local $$add810$i) (i32.const 18) + (i32.const 0) ) - ) - (call $_pad - (get_local $$f) - (i32.const 48) - (get_local $$add810$i) - (i32.const 18) - (i32.const 0) - ) - (set_local $$264 - (i32.load - (get_local $$f) + (set_local $$264 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$and$i$i - (i32.and - (get_local $$264) - (i32.const 32) + (set_local $$and$i$i + (i32.and + (get_local $$264) + (i32.const 32) + ) ) - ) - (set_local $$tobool$i$i - (i32.eq - (get_local $$and$i$i) - (i32.const 0) + (set_local $$tobool$i$i + (i32.eq + (get_local $$and$i$i) + (i32.const 0) + ) ) - ) - (if - (i32.eqz - (get_local $$tobool$i$i) + (if + (i32.eqz + (get_local $$tobool$i$i) + ) + (br $do-once99) ) - (br $do-once99) - ) - (set_local $$sub$ptr$rhs$cast812$i - (get_local $$estr$2$i) - ) - (set_local $$sub$ptr$sub813$i - (i32.sub - (get_local $$sub$ptr$lhs$cast160$i) - (get_local $$sub$ptr$rhs$cast812$i) + (set_local $$sub$ptr$rhs$cast812$i + (get_local $$estr$2$i) + ) + (set_local $$sub$ptr$sub813$i + (i32.sub + (get_local $$sub$ptr$lhs$cast160$i) + (get_local $$sub$ptr$rhs$cast812$i) + ) ) - ) - (drop (call $___fwritex (get_local $$estr$2$i) (get_local $$sub$ptr$sub813$i) @@ -16111,164 +16111,164 @@ (block $do-once (if (get_local $$or$cond) - (block - (set_local $$sub - (i32.sub - (get_local $$w) - (get_local $$l) - ) - ) - (set_local $$cmp1 - (i32.gt_u - (get_local $$sub) - (i32.const 256) - ) - ) - (set_local $$cond - (if i32 - (get_local $$cmp1) - (i32.const 256) - (get_local $$sub) - ) - ) - (drop - (call $_memset - (get_local $$pad) - (get_local $$c) - (get_local $$cond) + (drop + (block i32 + (set_local $$sub + (i32.sub + (get_local $$w) + (get_local $$l) + ) ) - ) - (set_local $$cmp3$14 - (i32.gt_u - (get_local $$sub) - (i32.const 255) + (set_local $$cmp1 + (i32.gt_u + (get_local $$sub) + (i32.const 256) + ) ) - ) - (set_local $$0 - (i32.load - (get_local $$f) + (set_local $$cond + (if i32 + (get_local $$cmp1) + (i32.const 256) + (get_local $$sub) + ) ) - ) - (set_local $$and$i$15 - (i32.and - (get_local $$0) - (i32.const 32) + (drop + (call $_memset + (get_local $$pad) + (get_local $$c) + (get_local $$cond) + ) ) - ) - (set_local $$tobool$i$16 - (i32.eq - (get_local $$and$i$15) - (i32.const 0) + (set_local $$cmp3$14 + (i32.gt_u + (get_local $$sub) + (i32.const 255) + ) ) - ) - (if - (get_local $$cmp3$14) - (block - (set_local $$1 - (i32.sub - (get_local $$w) - (get_local $$l) - ) + (set_local $$0 + (i32.load + (get_local $$f) ) - (set_local $$4 + ) + (set_local $$and$i$15 + (i32.and (get_local $$0) + (i32.const 32) ) - (set_local $$l$addr$017 - (get_local $$sub) - ) - (set_local $$tobool$i18 - (get_local $$tobool$i$16) + ) + (set_local $$tobool$i$16 + (i32.eq + (get_local $$and$i$15) + (i32.const 0) ) - (loop $while-in - (block $while-out - (if - (get_local $$tobool$i18) - (block - (drop - (call $___fwritex - (get_local $$pad) - (i32.const 256) - (get_local $$f) + ) + (if + (get_local $$cmp3$14) + (block + (set_local $$1 + (i32.sub + (get_local $$w) + (get_local $$l) + ) + ) + (set_local $$4 + (get_local $$0) + ) + (set_local $$l$addr$017 + (get_local $$sub) + ) + (set_local $$tobool$i18 + (get_local $$tobool$i$16) + ) + (loop $while-in + (block $while-out + (if + (get_local $$tobool$i18) + (block + (drop + (call $___fwritex + (get_local $$pad) + (i32.const 256) + (get_local $$f) + ) ) - ) - (set_local $$$pre - (i32.load - (get_local $$f) + (set_local $$$pre + (i32.load + (get_local $$f) + ) + ) + (set_local $$2 + (get_local $$$pre) ) ) (set_local $$2 - (get_local $$$pre) + (get_local $$4) ) ) - (set_local $$2 - (get_local $$4) - ) - ) - (set_local $$sub5 - (i32.add - (get_local $$l$addr$017) - (i32.const -256) - ) - ) - (set_local $$cmp3 - (i32.gt_u - (get_local $$sub5) - (i32.const 255) - ) - ) - (set_local $$and$i - (i32.and - (get_local $$2) - (i32.const 32) + (set_local $$sub5 + (i32.add + (get_local $$l$addr$017) + (i32.const -256) + ) ) - ) - (set_local $$tobool$i - (i32.eq - (get_local $$and$i) - (i32.const 0) + (set_local $$cmp3 + (i32.gt_u + (get_local $$sub5) + (i32.const 255) + ) ) - ) - (if - (get_local $$cmp3) - (block - (set_local $$4 + (set_local $$and$i + (i32.and (get_local $$2) + (i32.const 32) ) - (set_local $$l$addr$017 - (get_local $$sub5) + ) + (set_local $$tobool$i + (i32.eq + (get_local $$and$i) + (i32.const 0) ) - (set_local $$tobool$i18 - (get_local $$tobool$i) + ) + (if + (get_local $$cmp3) + (block + (set_local $$4 + (get_local $$2) + ) + (set_local $$l$addr$017 + (get_local $$sub5) + ) + (set_local $$tobool$i18 + (get_local $$tobool$i) + ) ) + (br $while-out) ) - (br $while-out) + (br $while-in) ) - (br $while-in) ) - ) - (set_local $$3 - (i32.and - (get_local $$1) - (i32.const 255) + (set_local $$3 + (i32.and + (get_local $$1) + (i32.const 255) + ) + ) + (if + (get_local $$tobool$i) + (set_local $$l$addr$0$lcssa21 + (get_local $$3) + ) + (br $do-once) ) ) (if - (get_local $$tobool$i) + (get_local $$tobool$i$16) (set_local $$l$addr$0$lcssa21 - (get_local $$3) + (get_local $$sub) ) (br $do-once) ) ) - (if - (get_local $$tobool$i$16) - (set_local $$l$addr$0$lcssa21 - (get_local $$sub) - ) - (br $do-once) - ) - ) - (drop (call $___fwritex (get_local $$pad) (get_local $$l$addr$0$lcssa21) @@ -30271,11 +30271,11 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (get_local $h) - ) - (drop + (drop + (block i32 + (set_global $tempRet0 + (get_local $h) + ) (get_global $tempRet0) ) ) @@ -30306,11 +30306,11 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (get_local $h) - ) - (drop + (drop + (block i32 + (set_global $tempRet0 + (get_local $h) + ) (get_global $tempRet0) ) ) @@ -30882,32 +30882,32 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (i32.add + (drop + (block i32 + (set_global $tempRet0 (i32.add - (i32.shr_u - (get_local $$8) - (i32.const 16) - ) - (i32.mul - (get_local $$11) - (get_local $$6) - ) - ) - (i32.shr_u (i32.add - (i32.and + (i32.shr_u (get_local $$8) - (i32.const 65535) + (i32.const 16) + ) + (i32.mul + (get_local $$11) + (get_local $$6) ) - (get_local $$12) ) - (i32.const 16) + (i32.shr_u + (i32.add + (i32.and + (get_local $$8) + (i32.const 65535) + ) + (get_local $$12) + ) + (i32.const 16) + ) ) ) - ) - (drop (get_global $tempRet0) ) ) @@ -31285,11 +31285,11 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (get_local $$10$1) - ) - (drop + (drop + (block i32 + (set_global $tempRet0 + (get_local $$10$1) + ) (get_global $tempRet0) ) ) @@ -31326,26 +31326,26 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (i32.or - (i32.add + (drop + (block i32 + (set_global $tempRet0 + (i32.or (i32.add - (i32.mul - (get_local $$b$1) - (get_local $$x_sroa_0_0_extract_trunc) + (i32.add + (i32.mul + (get_local $$b$1) + (get_local $$x_sroa_0_0_extract_trunc) + ) + (get_local $$2) ) - (get_local $$2) + (get_local $$1$1) + ) + (i32.and + (get_local $$1$1) + (i32.const 0) ) - (get_local $$1$1) - ) - (i32.and - (get_local $$1$1) - (i32.const 0) ) ) - ) - (drop (get_global $tempRet0) ) ) @@ -31403,16 +31403,16 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (i32.load - (i32.add - (get_local $$rem) - (i32.const 4) + (drop + (block i32 + (set_global $tempRet0 + (i32.load + (i32.add + (get_local $$rem) + (i32.const 4) + ) ) ) - ) - (drop (get_global $tempRet0) ) ) diff --git a/test/emcc_hello_world.fromasm.no-opts b/test/emcc_hello_world.fromasm.no-opts index 10cae59e8f6..8b59cb29bdb 100644 --- a/test/emcc_hello_world.fromasm.no-opts +++ b/test/emcc_hello_world.fromasm.no-opts @@ -4529,31 +4529,31 @@ ) (if (get_local $$cmp4) - (block - (set_local $$seek - (i32.add - (get_local $$f) - (i32.const 40) + (drop + (block i32 + (set_local $$seek + (i32.add + (get_local $$f) + (i32.const 40) + ) ) - ) - (set_local $$6 - (i32.load - (get_local $$seek) + (set_local $$6 + (i32.load + (get_local $$seek) + ) ) - ) - (set_local $$sub$ptr$lhs$cast - (get_local $$4) - ) - (set_local $$sub$ptr$rhs$cast - (get_local $$5) - ) - (set_local $$sub$ptr$sub - (i32.sub - (get_local $$sub$ptr$lhs$cast) - (get_local $$sub$ptr$rhs$cast) + (set_local $$sub$ptr$lhs$cast + (get_local $$4) + ) + (set_local $$sub$ptr$rhs$cast + (get_local $$5) + ) + (set_local $$sub$ptr$sub + (i32.sub + (get_local $$sub$ptr$lhs$cast) + (get_local $$sub$ptr$rhs$cast) + ) ) - ) - (drop (call_indirect $FUNCSIG$iiii (get_local $$f) (get_local $$sub$ptr$sub) @@ -12256,17 +12256,17 @@ ) (if (get_local $$tobool$i$443$i) - (block - (set_local $$sub$ptr$rhs$cast695$i - (get_local $$s668$1$i) - ) - (set_local $$sub$ptr$sub696$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast695$i) + (drop + (block i32 + (set_local $$sub$ptr$rhs$cast695$i + (get_local $$s668$1$i) + ) + (set_local $$sub$ptr$sub696$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast695$i) + ) ) - ) - (drop (call $___fwritex (get_local $$s668$1$i) (get_local $$sub$ptr$sub696$i) @@ -12313,31 +12313,31 @@ (i32.eqz (get_local $$251) ) - (block - (set_local $$252 - (i32.load - (get_local $$f) + (drop + (block i32 + (set_local $$252 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$and$i$448$i - (i32.and - (get_local $$252) - (i32.const 32) + (set_local $$and$i$448$i + (i32.and + (get_local $$252) + (i32.const 32) + ) ) - ) - (set_local $$tobool$i$449$i - (i32.eq - (get_local $$and$i$448$i) - (i32.const 0) + (set_local $$tobool$i$449$i + (i32.eq + (get_local $$and$i$448$i) + (i32.const 0) + ) ) - ) - (if - (i32.eqz - (get_local $$tobool$i$449$i) + (if + (i32.eqz + (get_local $$tobool$i$449$i) + ) + (br $do-once107) ) - (br $do-once107) - ) - (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -12457,21 +12457,21 @@ ) (if (get_local $$tobool$i$455$i) - (block - (set_local $$cmp727$i - (i32.gt_s - (get_local $$p$addr$4489$i) - (i32.const 9) + (drop + (block i32 + (set_local $$cmp727$i + (i32.gt_s + (get_local $$p$addr$4489$i) + (i32.const 9) + ) ) - ) - (set_local $$cond732$i - (if i32 - (get_local $$cmp727$i) - (i32.const 9) - (get_local $$p$addr$4489$i) + (set_local $$cond732$i + (if i32 + (get_local $$cmp727$i) + (i32.const 9) + (get_local $$p$addr$4489$i) + ) ) - ) - (drop (call $___fwritex (get_local $$s715$0$lcssa$i) (get_local $$cond732$i) @@ -12549,386 +12549,386 @@ (i32.const 0) ) ) - (block - (set_local $$add$ptr742$i - (i32.add - (get_local $$a$9$ph$i) - (i32.const 4) - ) - ) - (set_local $$z$7$add$ptr742$i - (if i32 - (get_local $$cmp450$lcssa$i) - (get_local $$z$7$i$lcssa) - (get_local $$add$ptr742$i) - ) - ) - (set_local $$cmp748$499$i - (i32.gt_s - (get_local $$p$addr$3$i) - (i32.const -1) - ) - ) - (if - (get_local $$cmp748$499$i) - (block - (set_local $$tobool781$i - (i32.eq - (get_local $$and610$pre$phi$iZ2D) - (i32.const 0) - ) - ) - (set_local $$d$7500$i + (drop + (block i32 + (set_local $$add$ptr742$i + (i32.add (get_local $$a$9$ph$i) + (i32.const 4) + ) + ) + (set_local $$z$7$add$ptr742$i + (if i32 + (get_local $$cmp450$lcssa$i) + (get_local $$z$7$i$lcssa) + (get_local $$add$ptr742$i) ) - (set_local $$p$addr$5501$i + ) + (set_local $$cmp748$499$i + (i32.gt_s (get_local $$p$addr$3$i) + (i32.const -1) ) - (loop $while-in114 - (block $while-out113 - (set_local $$258 - (i32.load - (get_local $$d$7500$i) - ) - ) - (set_local $$259 - (call $_fmt_u - (get_local $$258) - (i32.const 0) - (get_local $$add$ptr671$i) - ) - ) - (set_local $$cmp760$i - (i32.eq - (get_local $$259) - (get_local $$add$ptr671$i) - ) + ) + (if + (get_local $$cmp748$499$i) + (block + (set_local $$tobool781$i + (i32.eq + (get_local $$and610$pre$phi$iZ2D) + (i32.const 0) ) - (if - (get_local $$cmp760$i) - (block - (i32.store8 - (get_local $$incdec$ptr689$i) - (i32.const 48) - ) - (set_local $$s753$0$i - (get_local $$incdec$ptr689$i) + ) + (set_local $$d$7500$i + (get_local $$a$9$ph$i) + ) + (set_local $$p$addr$5501$i + (get_local $$p$addr$3$i) + ) + (loop $while-in114 + (block $while-out113 + (set_local $$258 + (i32.load + (get_local $$d$7500$i) ) ) - (set_local $$s753$0$i - (get_local $$259) + (set_local $$259 + (call $_fmt_u + (get_local $$258) + (i32.const 0) + (get_local $$add$ptr671$i) + ) ) - ) - (set_local $$cmp765$i - (i32.eq - (get_local $$d$7500$i) - (get_local $$a$9$ph$i) + (set_local $$cmp760$i + (i32.eq + (get_local $$259) + (get_local $$add$ptr671$i) + ) ) - ) - (block $do-once115 (if - (get_local $$cmp765$i) + (get_local $$cmp760$i) (block - (set_local $$incdec$ptr776$i - (i32.add - (get_local $$s753$0$i) - (i32.const 1) - ) - ) - (set_local $$260 - (i32.load - (get_local $$f) - ) - ) - (set_local $$and$i$460$i - (i32.and - (get_local $$260) - (i32.const 32) - ) + (i32.store8 + (get_local $$incdec$ptr689$i) + (i32.const 48) ) - (set_local $$tobool$i$461$i - (i32.eq - (get_local $$and$i$460$i) - (i32.const 0) - ) + (set_local $$s753$0$i + (get_local $$incdec$ptr689$i) ) - (if - (get_local $$tobool$i$461$i) - (drop - (call $___fwritex + ) + (set_local $$s753$0$i + (get_local $$259) + ) + ) + (set_local $$cmp765$i + (i32.eq + (get_local $$d$7500$i) + (get_local $$a$9$ph$i) + ) + ) + (block $do-once115 + (if + (get_local $$cmp765$i) + (block + (set_local $$incdec$ptr776$i + (i32.add (get_local $$s753$0$i) (i32.const 1) - (get_local $$f) ) ) - ) - (set_local $$cmp777$i - (i32.lt_s - (get_local $$p$addr$5501$i) - (i32.const 1) + (set_local $$260 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$or$cond401$i - (i32.and - (get_local $$tobool781$i) - (get_local $$cmp777$i) + (set_local $$and$i$460$i + (i32.and + (get_local $$260) + (i32.const 32) + ) ) - ) - (if - (get_local $$or$cond401$i) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) + (set_local $$tobool$i$461$i + (i32.eq + (get_local $$and$i$460$i) + (i32.const 0) ) - (br $do-once115) ) - ) - (set_local $$261 - (i32.load - (get_local $$f) + (if + (get_local $$tobool$i$461$i) + (drop + (call $___fwritex + (get_local $$s753$0$i) + (i32.const 1) + (get_local $$f) + ) + ) ) - ) - (set_local $$and$i$466$i - (i32.and - (get_local $$261) - (i32.const 32) + (set_local $$cmp777$i + (i32.lt_s + (get_local $$p$addr$5501$i) + (i32.const 1) + ) ) - ) - (set_local $$tobool$i$467$i - (i32.eq - (get_local $$and$i$466$i) - (i32.const 0) + (set_local $$or$cond401$i + (i32.and + (get_local $$tobool781$i) + (get_local $$cmp777$i) + ) ) - ) - (if - (i32.eqz - (get_local $$tobool$i$467$i) + (if + (get_local $$or$cond401$i) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) + ) + (br $do-once115) + ) ) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) + (set_local $$261 + (i32.load + (get_local $$f) ) - (br $do-once115) ) - ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $$f) + (set_local $$and$i$466$i + (i32.and + (get_local $$261) + (i32.const 32) + ) ) - ) - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) - ) - ) - (block - (set_local $$cmp770$495$i - (i32.gt_u - (get_local $$s753$0$i) - (get_local $$buf$i) + (set_local $$tobool$i$467$i + (i32.eq + (get_local $$and$i$466$i) + (i32.const 0) + ) ) - ) - (if - (get_local $$cmp770$495$i) - (set_local $$s753$1496$i - (get_local $$s753$0$i) + (if + (i32.eqz + (get_local $$tobool$i$467$i) + ) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) + ) + (br $do-once115) + ) ) - (block - (set_local $$s753$2$i - (get_local $$s753$0$i) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $$f) ) - (br $do-once115) + ) + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) ) ) - (loop $while-in118 - (block $while-out117 - (set_local $$incdec$ptr773$i - (i32.add - (get_local $$s753$1496$i) - (i32.const -1) - ) + (block + (set_local $$cmp770$495$i + (i32.gt_u + (get_local $$s753$0$i) + (get_local $$buf$i) ) - (i32.store8 - (get_local $$incdec$ptr773$i) - (i32.const 48) + ) + (if + (get_local $$cmp770$495$i) + (set_local $$s753$1496$i + (get_local $$s753$0$i) ) - (set_local $$cmp770$i - (i32.gt_u - (get_local $$incdec$ptr773$i) - (get_local $$buf$i) + (block + (set_local $$s753$2$i + (get_local $$s753$0$i) ) + (br $do-once115) ) - (if - (get_local $$cmp770$i) - (set_local $$s753$1496$i + ) + (loop $while-in118 + (block $while-out117 + (set_local $$incdec$ptr773$i + (i32.add + (get_local $$s753$1496$i) + (i32.const -1) + ) + ) + (i32.store8 (get_local $$incdec$ptr773$i) + (i32.const 48) ) - (block - (set_local $$s753$2$i + (set_local $$cmp770$i + (i32.gt_u (get_local $$incdec$ptr773$i) + (get_local $$buf$i) ) - (br $while-out117) ) + (if + (get_local $$cmp770$i) + (set_local $$s753$1496$i + (get_local $$incdec$ptr773$i) + ) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr773$i) + ) + (br $while-out117) + ) + ) + (br $while-in118) ) - (br $while-in118) ) ) ) ) - ) - (set_local $$sub$ptr$rhs$cast788$i - (get_local $$s753$2$i) - ) - (set_local $$sub$ptr$sub789$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast788$i) - ) - ) - (set_local $$262 - (i32.load - (get_local $$f) + (set_local $$sub$ptr$rhs$cast788$i + (get_local $$s753$2$i) ) - ) - (set_local $$and$i$472$i - (i32.and - (get_local $$262) - (i32.const 32) + (set_local $$sub$ptr$sub789$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast788$i) + ) ) - ) - (set_local $$tobool$i$473$i - (i32.eq - (get_local $$and$i$472$i) - (i32.const 0) + (set_local $$262 + (i32.load + (get_local $$f) + ) ) - ) - (if - (get_local $$tobool$i$473$i) - (block - (set_local $$cmp790$i - (i32.gt_s - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) + (set_local $$and$i$472$i + (i32.and + (get_local $$262) + (i32.const 32) ) - (set_local $$cond800$i - (if i32 - (get_local $$cmp790$i) - (get_local $$sub$ptr$sub789$i) - (get_local $$p$addr$5501$i) - ) + ) + (set_local $$tobool$i$473$i + (i32.eq + (get_local $$and$i$472$i) + (i32.const 0) ) + ) + (if + (get_local $$tobool$i$473$i) (drop - (call $___fwritex - (get_local $$s753$2$i) - (get_local $$cond800$i) - (get_local $$f) + (block i32 + (set_local $$cmp790$i + (i32.gt_s + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) + ) + ) + (set_local $$cond800$i + (if i32 + (get_local $$cmp790$i) + (get_local $$sub$ptr$sub789$i) + (get_local $$p$addr$5501$i) + ) + ) + (call $___fwritex + (get_local $$s753$2$i) + (get_local $$cond800$i) + (get_local $$f) + ) ) ) ) - ) - (set_local $$sub806$i - (i32.sub - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) - ) - (set_local $$incdec$ptr808$i - (i32.add - (get_local $$d$7500$i) - (i32.const 4) - ) - ) - (set_local $$cmp745$i - (i32.lt_u - (get_local $$incdec$ptr808$i) - (get_local $$z$7$add$ptr742$i) - ) - ) - (set_local $$cmp748$i - (i32.gt_s - (get_local $$sub806$i) - (i32.const -1) + (set_local $$sub806$i + (i32.sub + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) + ) ) - ) - (set_local $$263 - (i32.and - (get_local $$cmp745$i) - (get_local $$cmp748$i) + (set_local $$incdec$ptr808$i + (i32.add + (get_local $$d$7500$i) + (i32.const 4) + ) ) - ) - (if - (get_local $$263) - (block - (set_local $$d$7500$i + (set_local $$cmp745$i + (i32.lt_u (get_local $$incdec$ptr808$i) + (get_local $$z$7$add$ptr742$i) ) - (set_local $$p$addr$5501$i + ) + (set_local $$cmp748$i + (i32.gt_s (get_local $$sub806$i) + (i32.const -1) ) ) - (block - (set_local $$p$addr$5$lcssa$i - (get_local $$sub806$i) + (set_local $$263 + (i32.and + (get_local $$cmp745$i) + (get_local $$cmp748$i) + ) + ) + (if + (get_local $$263) + (block + (set_local $$d$7500$i + (get_local $$incdec$ptr808$i) + ) + (set_local $$p$addr$5501$i + (get_local $$sub806$i) + ) + ) + (block + (set_local $$p$addr$5$lcssa$i + (get_local $$sub806$i) + ) + (br $while-out113) ) - (br $while-out113) ) + (br $while-in114) ) - (br $while-in114) ) ) + (set_local $$p$addr$5$lcssa$i + (get_local $$p$addr$3$i) + ) ) - (set_local $$p$addr$5$lcssa$i - (get_local $$p$addr$3$i) + (set_local $$add810$i + (i32.add + (get_local $$p$addr$5$lcssa$i) + (i32.const 18) + ) ) - ) - (set_local $$add810$i - (i32.add - (get_local $$p$addr$5$lcssa$i) + (call $_pad + (get_local $$f) + (i32.const 48) + (get_local $$add810$i) (i32.const 18) + (i32.const 0) ) - ) - (call $_pad - (get_local $$f) - (i32.const 48) - (get_local $$add810$i) - (i32.const 18) - (i32.const 0) - ) - (set_local $$264 - (i32.load - (get_local $$f) + (set_local $$264 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$and$i$i - (i32.and - (get_local $$264) - (i32.const 32) + (set_local $$and$i$i + (i32.and + (get_local $$264) + (i32.const 32) + ) ) - ) - (set_local $$tobool$i$i - (i32.eq - (get_local $$and$i$i) - (i32.const 0) + (set_local $$tobool$i$i + (i32.eq + (get_local $$and$i$i) + (i32.const 0) + ) ) - ) - (if - (i32.eqz - (get_local $$tobool$i$i) + (if + (i32.eqz + (get_local $$tobool$i$i) + ) + (br $do-once99) ) - (br $do-once99) - ) - (set_local $$sub$ptr$rhs$cast812$i - (get_local $$estr$2$i) - ) - (set_local $$sub$ptr$sub813$i - (i32.sub - (get_local $$sub$ptr$lhs$cast160$i) - (get_local $$sub$ptr$rhs$cast812$i) + (set_local $$sub$ptr$rhs$cast812$i + (get_local $$estr$2$i) + ) + (set_local $$sub$ptr$sub813$i + (i32.sub + (get_local $$sub$ptr$lhs$cast160$i) + (get_local $$sub$ptr$rhs$cast812$i) + ) ) - ) - (drop (call $___fwritex (get_local $$estr$2$i) (get_local $$sub$ptr$sub813$i) @@ -16117,164 +16117,164 @@ (block $do-once (if (get_local $$or$cond) - (block - (set_local $$sub - (i32.sub - (get_local $$w) - (get_local $$l) - ) - ) - (set_local $$cmp1 - (i32.gt_u - (get_local $$sub) - (i32.const 256) - ) - ) - (set_local $$cond - (if i32 - (get_local $$cmp1) - (i32.const 256) - (get_local $$sub) - ) - ) - (drop - (call $_memset - (get_local $$pad) - (get_local $$c) - (get_local $$cond) + (drop + (block i32 + (set_local $$sub + (i32.sub + (get_local $$w) + (get_local $$l) + ) ) - ) - (set_local $$cmp3$14 - (i32.gt_u - (get_local $$sub) - (i32.const 255) + (set_local $$cmp1 + (i32.gt_u + (get_local $$sub) + (i32.const 256) + ) ) - ) - (set_local $$0 - (i32.load - (get_local $$f) + (set_local $$cond + (if i32 + (get_local $$cmp1) + (i32.const 256) + (get_local $$sub) + ) ) - ) - (set_local $$and$i$15 - (i32.and - (get_local $$0) - (i32.const 32) + (drop + (call $_memset + (get_local $$pad) + (get_local $$c) + (get_local $$cond) + ) ) - ) - (set_local $$tobool$i$16 - (i32.eq - (get_local $$and$i$15) - (i32.const 0) + (set_local $$cmp3$14 + (i32.gt_u + (get_local $$sub) + (i32.const 255) + ) ) - ) - (if - (get_local $$cmp3$14) - (block - (set_local $$1 - (i32.sub - (get_local $$w) - (get_local $$l) - ) + (set_local $$0 + (i32.load + (get_local $$f) ) - (set_local $$4 + ) + (set_local $$and$i$15 + (i32.and (get_local $$0) + (i32.const 32) ) - (set_local $$l$addr$017 - (get_local $$sub) - ) - (set_local $$tobool$i18 - (get_local $$tobool$i$16) + ) + (set_local $$tobool$i$16 + (i32.eq + (get_local $$and$i$15) + (i32.const 0) ) - (loop $while-in - (block $while-out - (if - (get_local $$tobool$i18) - (block - (drop - (call $___fwritex - (get_local $$pad) - (i32.const 256) - (get_local $$f) + ) + (if + (get_local $$cmp3$14) + (block + (set_local $$1 + (i32.sub + (get_local $$w) + (get_local $$l) + ) + ) + (set_local $$4 + (get_local $$0) + ) + (set_local $$l$addr$017 + (get_local $$sub) + ) + (set_local $$tobool$i18 + (get_local $$tobool$i$16) + ) + (loop $while-in + (block $while-out + (if + (get_local $$tobool$i18) + (block + (drop + (call $___fwritex + (get_local $$pad) + (i32.const 256) + (get_local $$f) + ) ) - ) - (set_local $$$pre - (i32.load - (get_local $$f) + (set_local $$$pre + (i32.load + (get_local $$f) + ) + ) + (set_local $$2 + (get_local $$$pre) ) ) (set_local $$2 - (get_local $$$pre) + (get_local $$4) ) ) - (set_local $$2 - (get_local $$4) - ) - ) - (set_local $$sub5 - (i32.add - (get_local $$l$addr$017) - (i32.const -256) - ) - ) - (set_local $$cmp3 - (i32.gt_u - (get_local $$sub5) - (i32.const 255) - ) - ) - (set_local $$and$i - (i32.and - (get_local $$2) - (i32.const 32) + (set_local $$sub5 + (i32.add + (get_local $$l$addr$017) + (i32.const -256) + ) ) - ) - (set_local $$tobool$i - (i32.eq - (get_local $$and$i) - (i32.const 0) + (set_local $$cmp3 + (i32.gt_u + (get_local $$sub5) + (i32.const 255) + ) ) - ) - (if - (get_local $$cmp3) - (block - (set_local $$4 + (set_local $$and$i + (i32.and (get_local $$2) + (i32.const 32) ) - (set_local $$l$addr$017 - (get_local $$sub5) + ) + (set_local $$tobool$i + (i32.eq + (get_local $$and$i) + (i32.const 0) ) - (set_local $$tobool$i18 - (get_local $$tobool$i) + ) + (if + (get_local $$cmp3) + (block + (set_local $$4 + (get_local $$2) + ) + (set_local $$l$addr$017 + (get_local $$sub5) + ) + (set_local $$tobool$i18 + (get_local $$tobool$i) + ) ) + (br $while-out) ) - (br $while-out) + (br $while-in) ) - (br $while-in) ) - ) - (set_local $$3 - (i32.and - (get_local $$1) - (i32.const 255) + (set_local $$3 + (i32.and + (get_local $$1) + (i32.const 255) + ) + ) + (if + (get_local $$tobool$i) + (set_local $$l$addr$0$lcssa21 + (get_local $$3) + ) + (br $do-once) ) ) (if - (get_local $$tobool$i) + (get_local $$tobool$i$16) (set_local $$l$addr$0$lcssa21 - (get_local $$3) + (get_local $$sub) ) (br $do-once) ) ) - (if - (get_local $$tobool$i$16) - (set_local $$l$addr$0$lcssa21 - (get_local $$sub) - ) - (br $do-once) - ) - ) - (drop (call $___fwritex (get_local $$pad) (get_local $$l$addr$0$lcssa21) @@ -30277,11 +30277,11 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (get_local $h) - ) - (drop + (drop + (block i32 + (set_global $tempRet0 + (get_local $h) + ) (get_global $tempRet0) ) ) @@ -30312,11 +30312,11 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (get_local $h) - ) - (drop + (drop + (block i32 + (set_global $tempRet0 + (get_local $h) + ) (get_global $tempRet0) ) ) @@ -30888,32 +30888,32 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (i32.add + (drop + (block i32 + (set_global $tempRet0 (i32.add - (i32.shr_u - (get_local $$8) - (i32.const 16) - ) - (i32.mul - (get_local $$11) - (get_local $$6) - ) - ) - (i32.shr_u (i32.add - (i32.and + (i32.shr_u (get_local $$8) - (i32.const 65535) + (i32.const 16) + ) + (i32.mul + (get_local $$11) + (get_local $$6) ) - (get_local $$12) ) - (i32.const 16) + (i32.shr_u + (i32.add + (i32.and + (get_local $$8) + (i32.const 65535) + ) + (get_local $$12) + ) + (i32.const 16) + ) ) ) - ) - (drop (get_global $tempRet0) ) ) @@ -31291,11 +31291,11 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (get_local $$10$1) - ) - (drop + (drop + (block i32 + (set_global $tempRet0 + (get_local $$10$1) + ) (get_global $tempRet0) ) ) @@ -31332,26 +31332,26 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (i32.or - (i32.add + (drop + (block i32 + (set_global $tempRet0 + (i32.or (i32.add - (i32.mul - (get_local $$b$1) - (get_local $$x_sroa_0_0_extract_trunc) + (i32.add + (i32.mul + (get_local $$b$1) + (get_local $$x_sroa_0_0_extract_trunc) + ) + (get_local $$2) ) - (get_local $$2) + (get_local $$1$1) + ) + (i32.and + (get_local $$1$1) + (i32.const 0) ) - (get_local $$1$1) - ) - (i32.and - (get_local $$1$1) - (i32.const 0) ) ) - ) - (drop (get_global $tempRet0) ) ) @@ -31409,16 +31409,16 @@ ) (return (block i32 - (block - (set_global $tempRet0 - (i32.load - (i32.add - (get_local $$rem) - (i32.const 4) + (drop + (block i32 + (set_global $tempRet0 + (i32.load + (i32.add + (get_local $$rem) + (i32.const 4) + ) ) ) - ) - (drop (get_global $tempRet0) ) ) diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 4eee5c0c01a..760ae2571ce 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -399,12 +399,10 @@ BinaryenFloat64: 4 ) (block ) - (if - (i32.const 1) - (drop + (drop + (if i32 + (i32.const 1) (i32.const 2) - ) - (drop (i32.const 3) ) ) @@ -1792,12 +1790,10 @@ int main() { ) (block ) - (if - (i32.const 1) - (drop + (drop + (if i32 + (i32.const 1) (i32.const 2) - ) - (drop (i32.const 3) ) ) diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt index cbccff23264..934c7e62051 100644 --- a/test/example/c-api-kitchen-sink.txt.txt +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -394,12 +394,10 @@ ) (block ) - (if - (i32.const 1) - (drop + (drop + (if i32 + (i32.const 1) (i32.const 2) - ) - (drop (i32.const 3) ) ) diff --git a/test/min.fromasm.imprecise.no-opts b/test/min.fromasm.imprecise.no-opts index 6e8a1c9ead7..69d292ff616 100644 --- a/test/min.fromasm.imprecise.no-opts +++ b/test/min.fromasm.imprecise.no-opts @@ -41,20 +41,22 @@ ) (func $bitcasts (param $i i32) (param $f f32) (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) + (block i32 + (drop + (f32.reinterpret/i32 + (get_local $i) + ) + ) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) + ) + ) + ) + (i32.reinterpret/f32 + (get_local $f) ) - ) - ) - (drop - (i32.reinterpret/f32 - (get_local $f) ) ) ) diff --git a/test/min.fromasm.no-opts b/test/min.fromasm.no-opts index 6e8a1c9ead7..69d292ff616 100644 --- a/test/min.fromasm.no-opts +++ b/test/min.fromasm.no-opts @@ -41,20 +41,22 @@ ) (func $bitcasts (param $i i32) (param $f f32) (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) + (block i32 + (drop + (f32.reinterpret/i32 + (get_local $i) + ) + ) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) + ) + ) + ) + (i32.reinterpret/f32 + (get_local $f) ) - ) - ) - (drop - (i32.reinterpret/f32 - (get_local $f) ) ) ) diff --git a/test/unit.fromasm b/test/unit.fromasm index 4f7b2c6a99f..5ba4b35b59d 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -354,30 +354,32 @@ ) (func $aborts (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.convert_s/i32 - (i32.const 55) + (block f64 + (drop + (call $abort + (f64.const 0) + ) + ) + (drop + (call $abort + (f64.convert_s/i32 + (i32.const 55) + ) + ) + ) + (drop + (call $abort + (f64.const 0) + ) + ) + (drop + (call $abort + (f64.const 12.34) + ) + ) + (call $abort + (f64.const 56.779998779296875) ) - ) - ) - (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.const 12.34) - ) - ) - (drop - (call $abort - (f64.const 56.779998779296875) ) ) ) @@ -541,11 +543,13 @@ ) ) (func $smallIf - (if - (call $return_int) - (drop - (call $lb - (i32.const 3) + (block $do-once + (if + (call $return_int) + (drop + (call $lb + (i32.const 3) + ) ) ) ) @@ -1102,11 +1106,13 @@ (call $return_int) ) (func $dropIgnoredImportInIf (param $0 i32) (param $1 i32) (param $2 i32) - (if - (get_local $0) - (drop - (call $lb - (get_local $2) + (block $do-once + (if + (get_local $0) + (drop + (call $lb + (get_local $2) + ) ) ) ) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index caa8e4f3355..6ccfb5b2087 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -330,30 +330,32 @@ ) (func $aborts (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.convert_s/i32 - (i32.const 55) + (block f64 + (drop + (call $abort + (f64.const 0) + ) + ) + (drop + (call $abort + (f64.convert_s/i32 + (i32.const 55) + ) + ) + ) + (drop + (call $abort + (f64.const 0) + ) + ) + (drop + (call $abort + (f64.const 12.34) + ) + ) + (call $abort + (f64.const 56.779998779296875) ) - ) - ) - (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.const 12.34) - ) - ) - (drop - (call $abort - (f64.const 56.779998779296875) ) ) ) @@ -517,11 +519,13 @@ ) ) (func $smallIf - (if - (call $return_int) - (drop - (call $lb - (i32.const 3) + (block $do-once + (if + (call $return_int) + (drop + (call $lb + (i32.const 3) + ) ) ) ) @@ -1078,11 +1082,13 @@ (call $return_int) ) (func $dropIgnoredImportInIf (param $0 i32) (param $1 i32) (param $2 i32) - (if - (get_local $0) - (drop - (call $lb - (get_local $2) + (block $do-once + (if + (get_local $0) + (drop + (call $lb + (get_local $2) + ) ) ) ) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index eafbb32f707..d98bc45e5d3 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -392,25 +392,27 @@ (local $y f32) (local $z f64) (drop - (f32.demote/f64 - (get_local $z) + (block f32 + (drop + (f32.demote/f64 + (get_local $z) + ) + ) + (drop + (get_local $y) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + (drop + (f32.const 5) + ) + (f32.const 0) ) ) - (drop - (get_local $y) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) ) (func $negZero (result f64) (return @@ -614,31 +616,33 @@ ) (func $aborts (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.convert_s/i32 - (i32.const 55) + (block f64 + (drop + (call $abort + (f64.const 0) + ) ) - ) - ) - (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.const 12.34) - ) - ) - (drop - (call $abort - (f64.promote/f32 - (f32.const 56.779998779296875) + (drop + (call $abort + (f64.convert_s/i32 + (i32.const 55) + ) + ) + ) + (drop + (call $abort + (f64.const 0) + ) + ) + (drop + (call $abort + (f64.const 12.34) + ) + ) + (call $abort + (f64.promote/f32 + (f32.const 56.779998779296875) + ) ) ) ) @@ -670,26 +674,28 @@ (func $bitcasts (param $i i32) (param $f f32) (local $d f64) (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) + (block i32 + (drop + (f32.reinterpret/i32 + (get_local $i) + ) ) - ) - ) - (drop - (i32.reinterpret/f32 - (get_local $f) - ) - ) - (drop - (i32.reinterpret/f32 - (f32.demote/f64 - (get_local $d) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) + ) + ) + ) + (drop + (i32.reinterpret/f32 + (get_local $f) + ) + ) + (i32.reinterpret/f32 + (f32.demote/f64 + (get_local $d) + ) ) ) ) @@ -714,16 +720,16 @@ ) ) (block i32 - (block - (block - (drop - (i32.const 4) - ) + (drop + (block i32 (drop - (i32.const 5) + (block i32 + (drop + (i32.const 4) + ) + (i32.const 5) + ) ) - ) - (drop (i32.const 6) ) ) @@ -778,20 +784,20 @@ ) ) (block i32 - (block - (block - (drop - (call $lb - (i32.const 4) - ) - ) + (drop + (block i32 (drop - (call $lb - (i32.const 5) + (block i32 + (drop + (call $lb + (i32.const 4) + ) + ) + (call $lb + (i32.const 5) + ) ) ) - ) - (drop (call $lb (i32.const 6) ) @@ -920,14 +926,14 @@ ) (func $smallIf (block $do-once - (if - (call $return_int) - (drop + (drop + (if i32 + (call $return_int) (call $lb (i32.const 3) ) + (br $do-once) ) - (br $do-once) ) (nop) ) @@ -980,11 +986,11 @@ (func $usesSetGlobal2 (result i32) (return (block i32 - (block - (set_global $Int - (i32.const 40) - ) - (drop + (drop + (block i32 + (set_global $Int + (i32.const 40) + ) (get_global $Int) ) ) @@ -994,23 +1000,23 @@ ) (func $breakThroughMany (param $$s i32) (block $label$break$L1 - (if - (get_local $$s) - (loop $while-in - (block $while-out - (if - (i32.eqz - (get_local $$s) + (drop + (if i32 + (get_local $$s) + (loop $while-in + (block $while-out + (if + (i32.eqz + (get_local $$s) + ) + (br $label$break$L1) ) - (br $label$break$L1) - ) - (call $zeroInit - (i32.const 0) + (call $zeroInit + (i32.const 0) + ) + (br $while-in) ) - (br $while-in) ) - ) - (drop (i32.const 1337) ) ) @@ -1762,19 +1768,19 @@ ) (func $dropIgnoredImportInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (if - (get_local $$0) - (block - (set_local $$0 - (i32.const 1) - ) - (drop + (drop + (if i32 + (get_local $$0) + (block i32 + (set_local $$0 + (i32.const 1) + ) (call $lb (get_local $$2) ) ) + (br $do-once) ) - (br $do-once) ) (nop) ) @@ -1787,14 +1793,12 @@ ) (func $dropIgnoredImportsInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (if - (get_local $$0) - (drop + (drop + (if i32 + (get_local $$0) (call $lb (get_local $$1) ) - ) - (drop (call $lb (get_local $$2) ) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index 29fede80c71..e7fc1bb7121 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -398,25 +398,27 @@ (local $y f32) (local $z f64) (drop - (f32.demote/f64 - (get_local $z) + (block f32 + (drop + (f32.demote/f64 + (get_local $z) + ) + ) + (drop + (get_local $y) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + (drop + (f32.const 5) + ) + (f32.const 0) ) ) - (drop - (get_local $y) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) ) (func $negZero (result f64) (return @@ -620,31 +622,33 @@ ) (func $aborts (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.convert_s/i32 - (i32.const 55) + (block f64 + (drop + (call $abort + (f64.const 0) + ) ) - ) - ) - (drop - (call $abort - (f64.const 0) - ) - ) - (drop - (call $abort - (f64.const 12.34) - ) - ) - (drop - (call $abort - (f64.promote/f32 - (f32.const 56.779998779296875) + (drop + (call $abort + (f64.convert_s/i32 + (i32.const 55) + ) + ) + ) + (drop + (call $abort + (f64.const 0) + ) + ) + (drop + (call $abort + (f64.const 12.34) + ) + ) + (call $abort + (f64.promote/f32 + (f32.const 56.779998779296875) + ) ) ) ) @@ -676,26 +680,28 @@ (func $bitcasts (param $i i32) (param $f f32) (local $d f64) (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) + (block i32 + (drop + (f32.reinterpret/i32 + (get_local $i) + ) ) - ) - ) - (drop - (i32.reinterpret/f32 - (get_local $f) - ) - ) - (drop - (i32.reinterpret/f32 - (f32.demote/f64 - (get_local $d) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) + ) + ) + ) + (drop + (i32.reinterpret/f32 + (get_local $f) + ) + ) + (i32.reinterpret/f32 + (f32.demote/f64 + (get_local $d) + ) ) ) ) @@ -720,16 +726,16 @@ ) ) (block i32 - (block - (block - (drop - (i32.const 4) - ) + (drop + (block i32 (drop - (i32.const 5) + (block i32 + (drop + (i32.const 4) + ) + (i32.const 5) + ) ) - ) - (drop (i32.const 6) ) ) @@ -784,20 +790,20 @@ ) ) (block i32 - (block - (block - (drop - (call $lb - (i32.const 4) - ) - ) + (drop + (block i32 (drop - (call $lb - (i32.const 5) + (block i32 + (drop + (call $lb + (i32.const 4) + ) + ) + (call $lb + (i32.const 5) + ) ) ) - ) - (drop (call $lb (i32.const 6) ) @@ -926,14 +932,14 @@ ) (func $smallIf (block $do-once - (if - (call $return_int) - (drop + (drop + (if i32 + (call $return_int) (call $lb (i32.const 3) ) + (br $do-once) ) - (br $do-once) ) (nop) ) @@ -986,11 +992,11 @@ (func $usesSetGlobal2 (result i32) (return (block i32 - (block - (set_global $Int - (i32.const 40) - ) - (drop + (drop + (block i32 + (set_global $Int + (i32.const 40) + ) (get_global $Int) ) ) @@ -1000,23 +1006,23 @@ ) (func $breakThroughMany (param $$s i32) (block $label$break$L1 - (if - (get_local $$s) - (loop $while-in - (block $while-out - (if - (i32.eqz - (get_local $$s) + (drop + (if i32 + (get_local $$s) + (loop $while-in + (block $while-out + (if + (i32.eqz + (get_local $$s) + ) + (br $label$break$L1) ) - (br $label$break$L1) - ) - (call $zeroInit - (i32.const 0) + (call $zeroInit + (i32.const 0) + ) + (br $while-in) ) - (br $while-in) ) - ) - (drop (i32.const 1337) ) ) @@ -1768,19 +1774,19 @@ ) (func $dropIgnoredImportInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (if - (get_local $$0) - (block - (set_local $$0 - (i32.const 1) - ) - (drop + (drop + (if i32 + (get_local $$0) + (block i32 + (set_local $$0 + (i32.const 1) + ) (call $lb (get_local $$2) ) ) + (br $do-once) ) - (br $do-once) ) (nop) ) @@ -1793,14 +1799,12 @@ ) (func $dropIgnoredImportsInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (if - (get_local $$0) - (drop + (drop + (if i32 + (get_local $$0) (call $lb (get_local $$1) ) - ) - (drop (call $lb (get_local $$2) ) diff --git a/test/wasm-only.fromasm.imprecise.no-opts b/test/wasm-only.fromasm.imprecise.no-opts index 4e05d6bd354..58710c8728a 100644 --- a/test/wasm-only.fromasm.imprecise.no-opts +++ b/test/wasm-only.fromasm.imprecise.no-opts @@ -934,13 +934,15 @@ ) (func $__emscripten_dceable_type_decls (drop - (call $legalfunc$_fabsf - (f32.const 0) + (block i64 + (drop + (call $legalfunc$_fabsf + (f32.const 0) + ) + ) + (call $legalfunc$do_i64) ) ) - (drop - (call $legalfunc$do_i64) - ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.no-opts b/test/wasm-only.fromasm.no-opts index eae9c459724..307040ae13b 100644 --- a/test/wasm-only.fromasm.no-opts +++ b/test/wasm-only.fromasm.no-opts @@ -982,13 +982,15 @@ ) (func $__emscripten_dceable_type_decls (drop - (call $legalfunc$_fabsf - (f32.const 0) + (block i64 + (drop + (call $legalfunc$_fabsf + (f32.const 0) + ) + ) + (call $legalfunc$do_i64) ) ) - (drop - (call $legalfunc$do_i64) - ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam From 6a5a94e36bbf7be46c2fb997019e32ae238ba12f Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Sat, 4 Feb 2017 21:53:57 -0800 Subject: [PATCH 02/17] make finalize(type) methods apply the type to children as well, allowing us to propagate a type necessary from the bottom up --- src/asm2wasm.h | 24 +---- src/passes/CoalesceLocals.cpp | 2 +- src/passes/DeadCodeElimination.cpp | 9 +- src/passes/MergeBlocks.cpp | 4 +- src/wasm.h | 9 +- src/wasm/wasm.cpp | 34 +++++++ test/two_sides.fromasm.imprecise.no-opts | 6 +- test/two_sides.fromasm.no-opts | 6 +- test/wasm-only.asm.js | 20 ++++ test/wasm-only.fromasm | 95 +++++++++++-------- test/wasm-only.fromasm.imprecise | 95 +++++++++++-------- test/wasm-only.fromasm.imprecise.no-opts | 112 ++++++++++++++++------- test/wasm-only.fromasm.no-opts | 112 ++++++++++++++++------- 13 files changed, 341 insertions(+), 187 deletions(-) diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 6eb1795bbd6..7919ca184f6 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -2297,27 +2297,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { void Asm2WasmBuilder::fixFallthrough(Function* func) { if (func->result == none) return; - std::vector work; - work.push_back(func->body); - while (work.size() > 0) { - auto* curr = work.back(); - work.pop_back(); - if (curr->type != unreachable) continue; - if (auto* block = curr->dynCast()) { - block->type = func->result; - if (block->list.size() > 0) { - work.push_back(block->list.back()); - } - } else if (auto* loop = curr->dynCast()) { - loop->type = func->result; - work.push_back(loop->body); - } else if (auto* iff = curr->dynCast()) { - assert(iff->ifFalse); // must be an if-else - iff->type = func->result; - work.push_back(iff->ifTrue); - work.push_back(iff->ifFalse); - } - } + Block* block = builder.blockify(func->body); + block->finalize(func->result); + func->body = block; } } // namespace wasm diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp index 943dae04e73..2a5bd5730e3 100644 --- a/src/passes/CoalesceLocals.cpp +++ b/src/passes/CoalesceLocals.cpp @@ -632,7 +632,7 @@ static void removeIfCopy(Expression** origin, SetLocal* set, If* iff, Expression if (!iff->ifTrue) { Builder(*module).flip(iff); } - iff->type = none; + iff->finalize(none); } } diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp index 1099cc6f87e..38627354b34 100644 --- a/src/passes/DeadCodeElimination.cpp +++ b/src/passes/DeadCodeElimination.cpp @@ -122,10 +122,11 @@ struct DeadCodeElimination : public WalkerPasstype) && block->list[i]->type == none)) { block->list.resize(i + 1); - // note that we do *not* finalize here. it is incorrect to re-finalize a block - // after removing elements, as it may no longer have branches to it that would - // determine its type, so re-finalizing would just wipe out an existing type - // that it had. + if (isConcreteWasmType(block->type)) { + // the last element may be unreachable, and we may need to propagate our + // concrete type to it + block->finalize(block->type); + } } } } diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index 273b930f74f..eb992512d53 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -170,7 +170,7 @@ static void optimizeBlock(Block* curr, Module* module) { // reuse the drop drop->value = child->list.back(); child->list.back() = drop; - child->type = none; + child->finalize(none); curr->list[i] = child; more = true; changed = true; @@ -226,7 +226,7 @@ struct MergeBlocks : public WalkerPasslist.back() = curr; - block->type = curr->type; // last block element was our input, and is now our output + block->finalize(curr->type); // last block element was our input, and is now our output replaceCurrent(block); return block; } else { diff --git a/src/wasm.h b/src/wasm.h index 63d9401e8c3..117ca3c45f6 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -968,7 +968,8 @@ class Block : public SpecificExpression { // set the type given you know its type, which is the case when parsing // s-expression or binary, as explicit types are given. the only additional work - // this does is to set the type to unreachable in the cases that is needed. + // this does is to set the type to unreachable in the cases that is needed, and + // to propage a new concrete type to children as needed. void finalize(WasmType type_); // set the type purely based on its contents. this scans the block, so it is not fast. @@ -990,7 +991,8 @@ class If : public SpecificExpression { // set the type given you know its type, which is the case when parsing // s-expression or binary, as explicit types are given. the only additional work - // this does is to set the type to unreachable in the cases that is needed. + // this does is to set the type to unreachable in the cases that is needed, and + // to propage a new concrete type to children as needed. void finalize(WasmType type_); // set the type purely based on its contents. @@ -1011,7 +1013,8 @@ class Loop : public SpecificExpression { // set the type given you know its type, which is the case when parsing // s-expression or binary, as explicit types are given. the only additional work - // this does is to set the type to unreachable in the cases that is needed. + // this does is to set the type to unreachable in the cases that is needed, and + // to propage a new concrete type to children as needed. void finalize(WasmType type_); // set the type purely based on its contents. diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index eb34c78eda7..a087c9a99ee 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -133,6 +133,31 @@ static WasmType mergeTypes(std::vector& types) { return type; } +// when a block is changed none=>i32, then its last element may need to be changed as well, etc. +static void propagateConcreteTypeToChildren(Expression* start, WasmType type) { + std::vector work; + work.push_back(start); + while (work.size() > 0) { + auto* curr = work.back(); + work.pop_back(); + if (curr != start && curr->type != unreachable) continue; + if (auto* block = curr->dynCast()) { + block->type = type; + if (block->list.size() > 0) { + work.push_back(block->list.back()); + } + } else if (auto* loop = curr->dynCast()) { + loop->type = type; + work.push_back(loop->body); + } else if (auto* iff = curr->dynCast()) { + assert(iff->ifFalse); // must be an if-else + iff->type = type; + work.push_back(iff->ifTrue); + work.push_back(iff->ifFalse); + } + } +} + void Block::finalize(WasmType type_) { type = type_; if (type == none && list.size() > 0) { @@ -142,6 +167,9 @@ void Block::finalize(WasmType type_) { } } } + if (isConcreteWasmType(type)) { + propagateConcreteTypeToChildren(this, type); + } } void Block::finalize() { @@ -166,6 +194,9 @@ void If::finalize(WasmType type_) { if (type == none && (condition->type == unreachable || (ifTrue->type == unreachable && (!ifFalse || ifFalse->type == unreachable)))) { type = unreachable; } + if (isConcreteWasmType(type)) { + propagateConcreteTypeToChildren(this, type); + } } void If::finalize() { @@ -193,6 +224,9 @@ void Loop::finalize(WasmType type_) { if (type == none && body->type == unreachable) { type = unreachable; } + if (isConcreteWasmType(type)) { + propagateConcreteTypeToChildren(this, type); + } } void Loop::finalize() { diff --git a/test/two_sides.fromasm.imprecise.no-opts b/test/two_sides.fromasm.imprecise.no-opts index 94bca724540..61789b79205 100644 --- a/test/two_sides.fromasm.imprecise.no-opts +++ b/test/two_sides.fromasm.imprecise.no-opts @@ -6,11 +6,11 @@ (export "_test" (func $_test)) (func $_test (param $i1 i32) (param $i2 i32) (param $i3 i32) (param $i4 i32) (param $i5 i32) (result i32) (local $d6 f64) - (if + (if i32 (i32.eqz (get_local $i5) ) - (block + (block i32 (set_local $d6 (f64.convert_s/i32 (i32.mul @@ -44,7 +44,7 @@ (get_local $i5) ) ) - (block + (block i32 (set_local $d6 (f64.convert_s/i32 (i32.mul diff --git a/test/two_sides.fromasm.no-opts b/test/two_sides.fromasm.no-opts index 0976e4c906b..d1bd24b27db 100644 --- a/test/two_sides.fromasm.no-opts +++ b/test/two_sides.fromasm.no-opts @@ -8,11 +8,11 @@ (export "_test" (func $_test)) (func $_test (param $i1 i32) (param $i2 i32) (param $i3 i32) (param $i4 i32) (param $i5 i32) (result i32) (local $d6 f64) - (if + (if i32 (i32.eqz (get_local $i5) ) - (block + (block i32 (set_local $d6 (f64.convert_s/i32 (i32.mul @@ -46,7 +46,7 @@ (get_local $i5) ) ) - (block + (block i32 (set_local $d6 (f64.convert_s/i32 (i32.mul diff --git a/test/wasm-only.asm.js b/test/wasm-only.asm.js index 37119717356..35ce30dc43e 100644 --- a/test/wasm-only.asm.js +++ b/test/wasm-only.asm.js @@ -284,6 +284,25 @@ function asm(global, env, buffer) { } return 44; } + + function propagateFallthrough() { + var x = 0; + x = 1; + x = x + 2 | 0; + x = x * 3 | 0; + while (1) { + if (1) { + if (x) { + return x | 0; + } else { + return 0; + } + } else { + return 1; + } + } + } + function keepAlive() { loads(); stores(); @@ -297,6 +316,7 @@ function asm(global, env, buffer) { ifValue32(0, 0) | 0; switch64(i64(0)) | 0; unreachable_leftovers(0, 0, 0); + propagateFallthrough() | 0; } function __emscripten_dceable_type_decls() { // dce-able, but this defines the type of fabsf which has no other use diff --git a/test/wasm-only.fromasm b/test/wasm-only.fromasm index 1a50a4385a1..3fd5bc8946a 100644 --- a/test/wasm-only.fromasm +++ b/test/wasm-only.fromasm @@ -367,51 +367,66 @@ ) ) ) - (func $keepAlive - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) - ) - (drop - (call $call2 - (i64.const 0) - ) - ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) - ) - ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (func $propagateFallthrough (result i32) + (local $0 i32) + (select + (tee_local $0 + (i32.const 9) ) + (i32.const 0) + (get_local $0) ) + ) + (func $keepAlive (drop - (call $switch64 - (i64.const 0) + (block i32 + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (call $propagateFallthrough) ) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.imprecise b/test/wasm-only.fromasm.imprecise index b7994d6894a..4a6b456edb8 100644 --- a/test/wasm-only.fromasm.imprecise +++ b/test/wasm-only.fromasm.imprecise @@ -295,51 +295,66 @@ ) ) ) - (func $keepAlive - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) - ) - (drop - (call $call2 - (i64.const 0) - ) - ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) - ) - ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (func $propagateFallthrough (result i32) + (local $0 i32) + (select + (tee_local $0 + (i32.const 9) ) + (i32.const 0) + (get_local $0) ) + ) + (func $keepAlive (drop - (call $switch64 - (i64.const 0) + (block i32 + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (call $propagateFallthrough) ) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.imprecise.no-opts b/test/wasm-only.fromasm.imprecise.no-opts index 58710c8728a..5f991dc94c7 100644 --- a/test/wasm-only.fromasm.imprecise.no-opts +++ b/test/wasm-only.fromasm.imprecise.no-opts @@ -886,51 +886,93 @@ (i32.const 44) ) ) - (func $keepAlive - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) + (func $propagateFallthrough (result i32) + (local $x i32) + (set_local $x + (i32.const 1) ) - (drop - (call $call2 - (i64.const 0) + (set_local $x + (i32.add + (get_local $x) + (i32.const 2) ) ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) + (set_local $x + (i32.mul + (get_local $x) + (i32.const 3) ) ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (loop $while-in i32 + (block $while-out i32 + (if i32 + (i32.const 1) + (if i32 + (get_local $x) + (return + (get_local $x) + ) + (return + (i32.const 0) + ) + ) + (return + (i32.const 1) + ) + ) ) ) + ) + (func $keepAlive (drop - (call $switch64 - (i64.const 0) + (block i32 + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (call $propagateFallthrough) ) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) ) (func $__emscripten_dceable_type_decls (drop diff --git a/test/wasm-only.fromasm.no-opts b/test/wasm-only.fromasm.no-opts index 307040ae13b..0b81307a02e 100644 --- a/test/wasm-only.fromasm.no-opts +++ b/test/wasm-only.fromasm.no-opts @@ -934,51 +934,93 @@ (i32.const 44) ) ) - (func $keepAlive - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) + (func $propagateFallthrough (result i32) + (local $x i32) + (set_local $x + (i32.const 1) ) - (drop - (call $call2 - (i64.const 0) + (set_local $x + (i32.add + (get_local $x) + (i32.const 2) ) ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) + (set_local $x + (i32.mul + (get_local $x) + (i32.const 3) ) ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (loop $while-in i32 + (block $while-out i32 + (if i32 + (i32.const 1) + (if i32 + (get_local $x) + (return + (get_local $x) + ) + (return + (i32.const 0) + ) + ) + (return + (i32.const 1) + ) + ) ) ) + ) + (func $keepAlive (drop - (call $switch64 - (i64.const 0) + (block i32 + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (call $propagateFallthrough) ) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) ) (func $__emscripten_dceable_type_decls (drop From 117d648797b9cbd0c4bf63eb6ef8af45db1967bb Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Sun, 5 Feb 2017 12:19:27 -0800 Subject: [PATCH 03/17] drop last block elements early in asm2wasm, as we know they cannot be used, and it can make the block have a value, which is wrong --- src/asm2wasm.h | 4 + test/emcc_hello_world.fromasm | 472 ++++----- test/emcc_hello_world.fromasm.imprecise | 472 ++++----- ...emcc_hello_world.fromasm.imprecise.no-opts | 992 +++++++++--------- test/emcc_hello_world.fromasm.no-opts | 992 +++++++++--------- test/min.fromasm.imprecise.no-opts | 28 +- test/min.fromasm.no-opts | 28 +- test/unit.fromasm | 12 +- test/unit.fromasm.imprecise | 12 +- test/unit.fromasm.imprecise.no-opts | 93 +- test/unit.fromasm.no-opts | 93 +- test/wasm-only.asm.js | 25 + test/wasm-only.fromasm | 121 ++- test/wasm-only.fromasm.imprecise | 121 ++- test/wasm-only.fromasm.imprecise.no-opts | 150 ++- test/wasm-only.fromasm.no-opts | 150 ++- 16 files changed, 1983 insertions(+), 1782 deletions(-) diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 7919ca184f6..0eb7bd251ec 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -2270,6 +2270,10 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { for (unsigned i = from; i < ast->size(); i++) { block->list.push_back(process(ast[i])); } + // if the last element has a value, we must drop it - a list of statements never falls through in asm.js + if (isConcreteWasmType(block->list.back()->type)) { + block->list.back() = builder.makeDrop(block->list.back()); + } block->finalize(); return block; }; diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index 044c001eb72..690c869ca4a 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -6006,16 +6006,16 @@ (block $do-once107 (if (get_local $32) - (drop - (block i32 - (br_if $do-once107 - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + (block + (br_if $do-once107 + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) + ) + (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -6137,217 +6137,217 @@ (i32.const 0) ) ) - (drop - (block i32 - (set_local $9 - (select - (get_local $9) - (i32.add - (get_local $12) - (i32.const 4) - ) - (get_local $25) + (block + (set_local $9 + (select + (get_local $9) + (i32.add + (get_local $12) + (i32.const 4) ) + (get_local $25) ) - (if - (i32.gt_s + ) + (if + (i32.gt_s + (get_local $5) + (i32.const -1) + ) + (block + (set_local $17 + (i32.eqz + (get_local $20) + ) + ) + (set_local $6 + (get_local $12) + ) + (set_local $7 (get_local $5) - (i32.const -1) ) - (block - (set_local $17 - (i32.eqz - (get_local $20) + (loop $while-in114 + (if + (i32.eq + (tee_local $5 + (call $_fmt_u + (i32.load + (get_local $6) + ) + (i32.const 0) + (get_local $30) + ) + ) + (get_local $30) + ) + (block + (i32.store8 + (get_local $35) + (i32.const 48) + ) + (set_local $5 + (get_local $35) + ) ) ) - (set_local $6 - (get_local $12) - ) - (set_local $7 - (get_local $5) - ) - (loop $while-in114 + (block $do-once115 (if (i32.eq - (tee_local $5 - (call $_fmt_u - (i32.load - (get_local $6) - ) - (i32.const 0) - (get_local $30) - ) - ) - (get_local $30) + (get_local $6) + (get_local $12) ) (block - (i32.store8 - (get_local $35) - (i32.const 48) - ) - (set_local $5 - (get_local $35) - ) - ) - ) - (block $do-once115 - (if - (i32.eq - (get_local $6) - (get_local $12) - ) - (block - (if - (i32.eqz - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (get_local $5) - (i32.const 1) + (if + (i32.eqz + (i32.and + (i32.load (get_local $0) ) + (i32.const 32) ) ) - (set_local $5 - (i32.add + (drop + (call $___fwritex (get_local $5) (i32.const 1) + (get_local $0) ) ) - (br_if $do-once115 - (i32.or - (i32.and - (get_local $17) - (i32.lt_s - (get_local $7) - (i32.const 1) - ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (br_if $do-once115 + (i32.or + (i32.and + (get_local $17) + (i32.lt_s + (get_local $7) + (i32.const 1) ) - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + ) + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $0) - ) + ) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $0) ) ) - (block - (br_if $do-once115 - (i32.le_u - (get_local $5) - (get_local $23) - ) + ) + (block + (br_if $do-once115 + (i32.le_u + (get_local $5) + (get_local $23) ) - (loop $while-in118 - (i32.store8 - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -1) - ) - ) - (i32.const 48) - ) - (br_if $while-in118 - (i32.gt_u + ) + (loop $while-in118 + (i32.store8 + (tee_local $5 + (i32.add (get_local $5) - (get_local $23) + (i32.const -1) ) ) + (i32.const 48) + ) + (br_if $while-in118 + (i32.gt_u + (get_local $5) + (get_local $23) + ) ) ) ) ) - (set_local $8 - (i32.sub - (get_local $43) - (get_local $5) - ) + ) + (set_local $8 + (i32.sub + (get_local $43) + (get_local $5) ) - (if - (i32.eqz - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + ) + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) - (drop - (call $___fwritex - (get_local $5) - (select - (get_local $8) + ) + (drop + (call $___fwritex + (get_local $5) + (select + (get_local $8) + (get_local $7) + (i32.gt_s (get_local $7) - (i32.gt_s - (get_local $7) - (get_local $8) - ) + (get_local $8) ) - (get_local $0) ) + (get_local $0) ) ) - (br_if $while-in114 - (i32.and - (i32.lt_u - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 4) - ) + ) + (br_if $while-in114 + (i32.and + (i32.lt_u + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 4) ) - (get_local $9) ) - (i32.gt_s - (tee_local $7 - (i32.sub - (get_local $7) - (get_local $8) - ) + (get_local $9) + ) + (i32.gt_s + (tee_local $7 + (i32.sub + (get_local $7) + (get_local $8) ) - (i32.const -1) ) + (i32.const -1) ) ) - (set_local $5 - (get_local $7) - ) + ) + (set_local $5 + (get_local $7) ) ) ) - (call $_pad - (get_local $0) - (i32.const 48) - (i32.add - (get_local $5) - (i32.const 18) - ) + ) + (call $_pad + (get_local $0) + (i32.const 48) + (i32.add + (get_local $5) (i32.const 18) - (i32.const 0) ) - (br_if $do-once99 - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + (i32.const 18) + (i32.const 0) + ) + (br_if $do-once99 + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) + ) + (drop (call $___fwritex (get_local $18) (i32.sub @@ -7762,93 +7762,77 @@ ) ) ) - (drop - (block i32 - (drop - (call $_memset - (get_local $6) - (get_local $1) - (select - (i32.const 256) - (tee_local $5 - (i32.sub - (get_local $2) - (get_local $3) - ) - ) - (i32.gt_u - (get_local $5) - (i32.const 256) + (block + (drop + (call $_memset + (get_local $6) + (get_local $1) + (select + (i32.const 256) + (tee_local $5 + (i32.sub + (get_local $2) + (get_local $3) ) ) + (i32.gt_u + (get_local $5) + (i32.const 256) + ) ) ) - (set_local $4 - (i32.eqz - (i32.and - (tee_local $1 - (i32.load - (get_local $0) - ) + ) + (set_local $4 + (i32.eqz + (i32.and + (tee_local $1 + (i32.load + (get_local $0) ) - (i32.const 32) ) + (i32.const 32) ) ) - (if - (i32.gt_u - (get_local $5) - (i32.const 255) - ) - (block - (loop $while-in - (if - (get_local $4) - (block - (drop - (call $___fwritex - (get_local $6) - (i32.const 256) - (get_local $0) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $4 - (i32.eqz - (i32.and - (get_local $1) - (i32.const 32) + ) + (if + (i32.gt_u + (get_local $5) + (i32.const 255) + ) + (block + (loop $while-in + (if + (get_local $4) + (block + (drop + (call $___fwritex + (get_local $6) + (i32.const 256) + (get_local $0) ) ) - ) - (br_if $while-in - (i32.gt_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -256) - ) + (set_local $1 + (i32.load + (get_local $0) ) - (i32.const 255) ) ) ) - (br_if $do-once + (set_local $4 (i32.eqz - (get_local $4) + (i32.and + (get_local $1) + (i32.const 32) + ) ) ) - (set_local $5 - (i32.and - (i32.sub - (get_local $2) - (get_local $3) + (br_if $while-in + (i32.gt_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -256) + ) ) (i32.const 255) ) @@ -7859,7 +7843,23 @@ (get_local $4) ) ) + (set_local $5 + (i32.and + (i32.sub + (get_local $2) + (get_local $3) + ) + (i32.const 255) + ) + ) ) + (br_if $do-once + (i32.eqz + (get_local $4) + ) + ) + ) + (drop (call $___fwritex (get_local $6) (get_local $5) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index 8ac84a8be7b..2cd23ba1d6d 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -5992,16 +5992,16 @@ (block $do-once107 (if (get_local $32) - (drop - (block i32 - (br_if $do-once107 - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + (block + (br_if $do-once107 + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) + ) + (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -6123,217 +6123,217 @@ (i32.const 0) ) ) - (drop - (block i32 - (set_local $9 - (select - (get_local $9) - (i32.add - (get_local $12) - (i32.const 4) - ) - (get_local $25) + (block + (set_local $9 + (select + (get_local $9) + (i32.add + (get_local $12) + (i32.const 4) ) + (get_local $25) ) - (if - (i32.gt_s + ) + (if + (i32.gt_s + (get_local $5) + (i32.const -1) + ) + (block + (set_local $17 + (i32.eqz + (get_local $20) + ) + ) + (set_local $6 + (get_local $12) + ) + (set_local $7 (get_local $5) - (i32.const -1) ) - (block - (set_local $17 - (i32.eqz - (get_local $20) + (loop $while-in114 + (if + (i32.eq + (tee_local $5 + (call $_fmt_u + (i32.load + (get_local $6) + ) + (i32.const 0) + (get_local $30) + ) + ) + (get_local $30) + ) + (block + (i32.store8 + (get_local $35) + (i32.const 48) + ) + (set_local $5 + (get_local $35) + ) ) ) - (set_local $6 - (get_local $12) - ) - (set_local $7 - (get_local $5) - ) - (loop $while-in114 + (block $do-once115 (if (i32.eq - (tee_local $5 - (call $_fmt_u - (i32.load - (get_local $6) - ) - (i32.const 0) - (get_local $30) - ) - ) - (get_local $30) + (get_local $6) + (get_local $12) ) (block - (i32.store8 - (get_local $35) - (i32.const 48) - ) - (set_local $5 - (get_local $35) - ) - ) - ) - (block $do-once115 - (if - (i32.eq - (get_local $6) - (get_local $12) - ) - (block - (if - (i32.eqz - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) - ) - ) - (drop - (call $___fwritex - (get_local $5) - (i32.const 1) + (if + (i32.eqz + (i32.and + (i32.load (get_local $0) ) + (i32.const 32) ) ) - (set_local $5 - (i32.add + (drop + (call $___fwritex (get_local $5) (i32.const 1) + (get_local $0) ) ) - (br_if $do-once115 - (i32.or - (i32.and - (get_local $17) - (i32.lt_s - (get_local $7) - (i32.const 1) - ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (br_if $do-once115 + (i32.or + (i32.and + (get_local $17) + (i32.lt_s + (get_local $7) + (i32.const 1) ) - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + ) + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $0) - ) + ) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $0) ) ) - (block - (br_if $do-once115 - (i32.le_u - (get_local $5) - (get_local $23) - ) + ) + (block + (br_if $do-once115 + (i32.le_u + (get_local $5) + (get_local $23) ) - (loop $while-in118 - (i32.store8 - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -1) - ) - ) - (i32.const 48) - ) - (br_if $while-in118 - (i32.gt_u + ) + (loop $while-in118 + (i32.store8 + (tee_local $5 + (i32.add (get_local $5) - (get_local $23) + (i32.const -1) ) ) + (i32.const 48) + ) + (br_if $while-in118 + (i32.gt_u + (get_local $5) + (get_local $23) + ) ) ) ) ) - (set_local $8 - (i32.sub - (get_local $43) - (get_local $5) - ) + ) + (set_local $8 + (i32.sub + (get_local $43) + (get_local $5) ) - (if - (i32.eqz - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + ) + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) - (drop - (call $___fwritex - (get_local $5) - (select - (get_local $8) + ) + (drop + (call $___fwritex + (get_local $5) + (select + (get_local $8) + (get_local $7) + (i32.gt_s (get_local $7) - (i32.gt_s - (get_local $7) - (get_local $8) - ) + (get_local $8) ) - (get_local $0) ) + (get_local $0) ) ) - (br_if $while-in114 - (i32.and - (i32.lt_u - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 4) - ) + ) + (br_if $while-in114 + (i32.and + (i32.lt_u + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 4) ) - (get_local $9) ) - (i32.gt_s - (tee_local $7 - (i32.sub - (get_local $7) - (get_local $8) - ) + (get_local $9) + ) + (i32.gt_s + (tee_local $7 + (i32.sub + (get_local $7) + (get_local $8) ) - (i32.const -1) ) + (i32.const -1) ) ) - (set_local $5 - (get_local $7) - ) + ) + (set_local $5 + (get_local $7) ) ) ) - (call $_pad - (get_local $0) - (i32.const 48) - (i32.add - (get_local $5) - (i32.const 18) - ) + ) + (call $_pad + (get_local $0) + (i32.const 48) + (i32.add + (get_local $5) (i32.const 18) - (i32.const 0) ) - (br_if $do-once99 - (i32.and - (i32.load - (get_local $0) - ) - (i32.const 32) + (i32.const 18) + (i32.const 0) + ) + (br_if $do-once99 + (i32.and + (i32.load + (get_local $0) ) + (i32.const 32) ) + ) + (drop (call $___fwritex (get_local $18) (i32.sub @@ -7748,93 +7748,77 @@ ) ) ) - (drop - (block i32 - (drop - (call $_memset - (get_local $6) - (get_local $1) - (select - (i32.const 256) - (tee_local $5 - (i32.sub - (get_local $2) - (get_local $3) - ) - ) - (i32.gt_u - (get_local $5) - (i32.const 256) + (block + (drop + (call $_memset + (get_local $6) + (get_local $1) + (select + (i32.const 256) + (tee_local $5 + (i32.sub + (get_local $2) + (get_local $3) ) ) + (i32.gt_u + (get_local $5) + (i32.const 256) + ) ) ) - (set_local $4 - (i32.eqz - (i32.and - (tee_local $1 - (i32.load - (get_local $0) - ) + ) + (set_local $4 + (i32.eqz + (i32.and + (tee_local $1 + (i32.load + (get_local $0) ) - (i32.const 32) ) + (i32.const 32) ) ) - (if - (i32.gt_u - (get_local $5) - (i32.const 255) - ) - (block - (loop $while-in - (if - (get_local $4) - (block - (drop - (call $___fwritex - (get_local $6) - (i32.const 256) - (get_local $0) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $4 - (i32.eqz - (i32.and - (get_local $1) - (i32.const 32) + ) + (if + (i32.gt_u + (get_local $5) + (i32.const 255) + ) + (block + (loop $while-in + (if + (get_local $4) + (block + (drop + (call $___fwritex + (get_local $6) + (i32.const 256) + (get_local $0) ) ) - ) - (br_if $while-in - (i32.gt_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -256) - ) + (set_local $1 + (i32.load + (get_local $0) ) - (i32.const 255) ) ) ) - (br_if $do-once + (set_local $4 (i32.eqz - (get_local $4) + (i32.and + (get_local $1) + (i32.const 32) + ) ) ) - (set_local $5 - (i32.and - (i32.sub - (get_local $2) - (get_local $3) + (br_if $while-in + (i32.gt_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -256) + ) ) (i32.const 255) ) @@ -7845,7 +7829,23 @@ (get_local $4) ) ) + (set_local $5 + (i32.and + (i32.sub + (get_local $2) + (get_local $3) + ) + (i32.const 255) + ) + ) ) + (br_if $do-once + (i32.eqz + (get_local $4) + ) + ) + ) + (drop (call $___fwritex (get_local $6) (get_local $5) diff --git a/test/emcc_hello_world.fromasm.imprecise.no-opts b/test/emcc_hello_world.fromasm.imprecise.no-opts index 6d719fe01e4..637233bfafd 100644 --- a/test/emcc_hello_world.fromasm.imprecise.no-opts +++ b/test/emcc_hello_world.fromasm.imprecise.no-opts @@ -4523,31 +4523,31 @@ ) (if (get_local $$cmp4) - (drop - (block i32 - (set_local $$seek - (i32.add - (get_local $$f) - (i32.const 40) - ) - ) - (set_local $$6 - (i32.load - (get_local $$seek) - ) - ) - (set_local $$sub$ptr$lhs$cast - (get_local $$4) + (block + (set_local $$seek + (i32.add + (get_local $$f) + (i32.const 40) ) - (set_local $$sub$ptr$rhs$cast - (get_local $$5) + ) + (set_local $$6 + (i32.load + (get_local $$seek) ) - (set_local $$sub$ptr$sub - (i32.sub - (get_local $$sub$ptr$lhs$cast) - (get_local $$sub$ptr$rhs$cast) - ) + ) + (set_local $$sub$ptr$lhs$cast + (get_local $$4) + ) + (set_local $$sub$ptr$rhs$cast + (get_local $$5) + ) + (set_local $$sub$ptr$sub + (i32.sub + (get_local $$sub$ptr$lhs$cast) + (get_local $$sub$ptr$rhs$cast) ) + ) + (drop (call_indirect $FUNCSIG$iiii (get_local $$f) (get_local $$sub$ptr$sub) @@ -12250,17 +12250,17 @@ ) (if (get_local $$tobool$i$443$i) - (drop - (block i32 - (set_local $$sub$ptr$rhs$cast695$i - (get_local $$s668$1$i) - ) - (set_local $$sub$ptr$sub696$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast695$i) - ) + (block + (set_local $$sub$ptr$rhs$cast695$i + (get_local $$s668$1$i) + ) + (set_local $$sub$ptr$sub696$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast695$i) ) + ) + (drop (call $___fwritex (get_local $$s668$1$i) (get_local $$sub$ptr$sub696$i) @@ -12307,31 +12307,31 @@ (i32.eqz (get_local $$251) ) - (drop - (block i32 - (set_local $$252 - (i32.load - (get_local $$f) - ) + (block + (set_local $$252 + (i32.load + (get_local $$f) ) - (set_local $$and$i$448$i - (i32.and - (get_local $$252) - (i32.const 32) - ) + ) + (set_local $$and$i$448$i + (i32.and + (get_local $$252) + (i32.const 32) ) - (set_local $$tobool$i$449$i - (i32.eq - (get_local $$and$i$448$i) - (i32.const 0) - ) + ) + (set_local $$tobool$i$449$i + (i32.eq + (get_local $$and$i$448$i) + (i32.const 0) ) - (if - (i32.eqz - (get_local $$tobool$i$449$i) - ) - (br $do-once107) + ) + (if + (i32.eqz + (get_local $$tobool$i$449$i) ) + (br $do-once107) + ) + (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -12451,21 +12451,21 @@ ) (if (get_local $$tobool$i$455$i) - (drop - (block i32 - (set_local $$cmp727$i - (i32.gt_s - (get_local $$p$addr$4489$i) - (i32.const 9) - ) + (block + (set_local $$cmp727$i + (i32.gt_s + (get_local $$p$addr$4489$i) + (i32.const 9) ) - (set_local $$cond732$i - (if i32 - (get_local $$cmp727$i) - (i32.const 9) - (get_local $$p$addr$4489$i) - ) + ) + (set_local $$cond732$i + (if i32 + (get_local $$cmp727$i) + (i32.const 9) + (get_local $$p$addr$4489$i) ) + ) + (drop (call $___fwritex (get_local $$s715$0$lcssa$i) (get_local $$cond732$i) @@ -12543,386 +12543,386 @@ (i32.const 0) ) ) - (drop - (block i32 - (set_local $$add$ptr742$i - (i32.add - (get_local $$a$9$ph$i) - (i32.const 4) - ) + (block + (set_local $$add$ptr742$i + (i32.add + (get_local $$a$9$ph$i) + (i32.const 4) ) - (set_local $$z$7$add$ptr742$i - (if i32 - (get_local $$cmp450$lcssa$i) - (get_local $$z$7$i$lcssa) - (get_local $$add$ptr742$i) - ) + ) + (set_local $$z$7$add$ptr742$i + (if i32 + (get_local $$cmp450$lcssa$i) + (get_local $$z$7$i$lcssa) + (get_local $$add$ptr742$i) ) - (set_local $$cmp748$499$i - (i32.gt_s + ) + (set_local $$cmp748$499$i + (i32.gt_s + (get_local $$p$addr$3$i) + (i32.const -1) + ) + ) + (if + (get_local $$cmp748$499$i) + (block + (set_local $$tobool781$i + (i32.eq + (get_local $$and610$pre$phi$iZ2D) + (i32.const 0) + ) + ) + (set_local $$d$7500$i + (get_local $$a$9$ph$i) + ) + (set_local $$p$addr$5501$i (get_local $$p$addr$3$i) - (i32.const -1) ) - ) - (if - (get_local $$cmp748$499$i) - (block - (set_local $$tobool781$i - (i32.eq - (get_local $$and610$pre$phi$iZ2D) - (i32.const 0) + (loop $while-in114 + (block $while-out113 + (set_local $$258 + (i32.load + (get_local $$d$7500$i) + ) ) - ) - (set_local $$d$7500$i - (get_local $$a$9$ph$i) - ) - (set_local $$p$addr$5501$i - (get_local $$p$addr$3$i) - ) - (loop $while-in114 - (block $while-out113 - (set_local $$258 - (i32.load - (get_local $$d$7500$i) - ) + (set_local $$259 + (call $_fmt_u + (get_local $$258) + (i32.const 0) + (get_local $$add$ptr671$i) ) - (set_local $$259 - (call $_fmt_u - (get_local $$258) - (i32.const 0) - (get_local $$add$ptr671$i) - ) + ) + (set_local $$cmp760$i + (i32.eq + (get_local $$259) + (get_local $$add$ptr671$i) ) - (set_local $$cmp760$i - (i32.eq - (get_local $$259) - (get_local $$add$ptr671$i) + ) + (if + (get_local $$cmp760$i) + (block + (i32.store8 + (get_local $$incdec$ptr689$i) + (i32.const 48) + ) + (set_local $$s753$0$i + (get_local $$incdec$ptr689$i) ) ) + (set_local $$s753$0$i + (get_local $$259) + ) + ) + (set_local $$cmp765$i + (i32.eq + (get_local $$d$7500$i) + (get_local $$a$9$ph$i) + ) + ) + (block $do-once115 (if - (get_local $$cmp760$i) + (get_local $$cmp765$i) (block - (i32.store8 - (get_local $$incdec$ptr689$i) - (i32.const 48) + (set_local $$incdec$ptr776$i + (i32.add + (get_local $$s753$0$i) + (i32.const 1) + ) ) - (set_local $$s753$0$i - (get_local $$incdec$ptr689$i) + (set_local $$260 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$s753$0$i - (get_local $$259) - ) - ) - (set_local $$cmp765$i - (i32.eq - (get_local $$d$7500$i) - (get_local $$a$9$ph$i) - ) - ) - (block $do-once115 - (if - (get_local $$cmp765$i) - (block - (set_local $$incdec$ptr776$i - (i32.add + (set_local $$and$i$460$i + (i32.and + (get_local $$260) + (i32.const 32) + ) + ) + (set_local $$tobool$i$461$i + (i32.eq + (get_local $$and$i$460$i) + (i32.const 0) + ) + ) + (if + (get_local $$tobool$i$461$i) + (drop + (call $___fwritex (get_local $$s753$0$i) (i32.const 1) - ) - ) - (set_local $$260 - (i32.load (get_local $$f) ) ) - (set_local $$and$i$460$i - (i32.and - (get_local $$260) - (i32.const 32) - ) - ) - (set_local $$tobool$i$461$i - (i32.eq - (get_local $$and$i$460$i) - (i32.const 0) - ) - ) - (if - (get_local $$tobool$i$461$i) - (drop - (call $___fwritex - (get_local $$s753$0$i) - (i32.const 1) - (get_local $$f) - ) - ) + ) + (set_local $$cmp777$i + (i32.lt_s + (get_local $$p$addr$5501$i) + (i32.const 1) ) - (set_local $$cmp777$i - (i32.lt_s - (get_local $$p$addr$5501$i) - (i32.const 1) - ) + ) + (set_local $$or$cond401$i + (i32.and + (get_local $$tobool781$i) + (get_local $$cmp777$i) ) - (set_local $$or$cond401$i - (i32.and - (get_local $$tobool781$i) - (get_local $$cmp777$i) + ) + (if + (get_local $$or$cond401$i) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) ) + (br $do-once115) ) - (if - (get_local $$or$cond401$i) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) - ) - (br $do-once115) - ) + ) + (set_local $$261 + (i32.load + (get_local $$f) ) - (set_local $$261 - (i32.load - (get_local $$f) - ) + ) + (set_local $$and$i$466$i + (i32.and + (get_local $$261) + (i32.const 32) ) - (set_local $$and$i$466$i - (i32.and - (get_local $$261) - (i32.const 32) - ) + ) + (set_local $$tobool$i$467$i + (i32.eq + (get_local $$and$i$466$i) + (i32.const 0) ) - (set_local $$tobool$i$467$i - (i32.eq - (get_local $$and$i$466$i) - (i32.const 0) - ) + ) + (if + (i32.eqz + (get_local $$tobool$i$467$i) ) - (if - (i32.eqz - (get_local $$tobool$i$467$i) - ) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) - ) - (br $do-once115) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) ) + (br $do-once115) ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $$f) - ) + ) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $$f) ) - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) + ) + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) + ) + ) + (block + (set_local $$cmp770$495$i + (i32.gt_u + (get_local $$s753$0$i) + (get_local $$buf$i) ) ) - (block - (set_local $$cmp770$495$i - (i32.gt_u - (get_local $$s753$0$i) - (get_local $$buf$i) - ) + (if + (get_local $$cmp770$495$i) + (set_local $$s753$1496$i + (get_local $$s753$0$i) ) - (if - (get_local $$cmp770$495$i) - (set_local $$s753$1496$i + (block + (set_local $$s753$2$i (get_local $$s753$0$i) ) - (block - (set_local $$s753$2$i - (get_local $$s753$0$i) - ) - (br $do-once115) - ) + (br $do-once115) ) - (loop $while-in118 - (block $while-out117 - (set_local $$incdec$ptr773$i - (i32.add - (get_local $$s753$1496$i) - (i32.const -1) - ) + ) + (loop $while-in118 + (block $while-out117 + (set_local $$incdec$ptr773$i + (i32.add + (get_local $$s753$1496$i) + (i32.const -1) ) - (i32.store8 + ) + (i32.store8 + (get_local $$incdec$ptr773$i) + (i32.const 48) + ) + (set_local $$cmp770$i + (i32.gt_u (get_local $$incdec$ptr773$i) - (i32.const 48) + (get_local $$buf$i) ) - (set_local $$cmp770$i - (i32.gt_u - (get_local $$incdec$ptr773$i) - (get_local $$buf$i) - ) + ) + (if + (get_local $$cmp770$i) + (set_local $$s753$1496$i + (get_local $$incdec$ptr773$i) ) - (if - (get_local $$cmp770$i) - (set_local $$s753$1496$i + (block + (set_local $$s753$2$i (get_local $$incdec$ptr773$i) ) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr773$i) - ) - (br $while-out117) - ) + (br $while-out117) ) - (br $while-in118) ) + (br $while-in118) ) ) ) ) - (set_local $$sub$ptr$rhs$cast788$i - (get_local $$s753$2$i) - ) - (set_local $$sub$ptr$sub789$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast788$i) - ) + ) + (set_local $$sub$ptr$rhs$cast788$i + (get_local $$s753$2$i) + ) + (set_local $$sub$ptr$sub789$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast788$i) ) - (set_local $$262 - (i32.load - (get_local $$f) - ) + ) + (set_local $$262 + (i32.load + (get_local $$f) ) - (set_local $$and$i$472$i - (i32.and - (get_local $$262) - (i32.const 32) - ) + ) + (set_local $$and$i$472$i + (i32.and + (get_local $$262) + (i32.const 32) ) - (set_local $$tobool$i$473$i - (i32.eq - (get_local $$and$i$472$i) - (i32.const 0) - ) + ) + (set_local $$tobool$i$473$i + (i32.eq + (get_local $$and$i$472$i) + (i32.const 0) ) - (if - (get_local $$tobool$i$473$i) + ) + (if + (get_local $$tobool$i$473$i) + (block + (set_local $$cmp790$i + (i32.gt_s + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) + ) + ) + (set_local $$cond800$i + (if i32 + (get_local $$cmp790$i) + (get_local $$sub$ptr$sub789$i) + (get_local $$p$addr$5501$i) + ) + ) (drop - (block i32 - (set_local $$cmp790$i - (i32.gt_s - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) - ) - (set_local $$cond800$i - (if i32 - (get_local $$cmp790$i) - (get_local $$sub$ptr$sub789$i) - (get_local $$p$addr$5501$i) - ) - ) - (call $___fwritex - (get_local $$s753$2$i) - (get_local $$cond800$i) - (get_local $$f) - ) + (call $___fwritex + (get_local $$s753$2$i) + (get_local $$cond800$i) + (get_local $$f) ) ) ) - (set_local $$sub806$i - (i32.sub - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) + ) + (set_local $$sub806$i + (i32.sub + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) ) - (set_local $$incdec$ptr808$i - (i32.add - (get_local $$d$7500$i) - (i32.const 4) - ) + ) + (set_local $$incdec$ptr808$i + (i32.add + (get_local $$d$7500$i) + (i32.const 4) ) - (set_local $$cmp745$i - (i32.lt_u + ) + (set_local $$cmp745$i + (i32.lt_u + (get_local $$incdec$ptr808$i) + (get_local $$z$7$add$ptr742$i) + ) + ) + (set_local $$cmp748$i + (i32.gt_s + (get_local $$sub806$i) + (i32.const -1) + ) + ) + (set_local $$263 + (i32.and + (get_local $$cmp745$i) + (get_local $$cmp748$i) + ) + ) + (if + (get_local $$263) + (block + (set_local $$d$7500$i (get_local $$incdec$ptr808$i) - (get_local $$z$7$add$ptr742$i) ) - ) - (set_local $$cmp748$i - (i32.gt_s + (set_local $$p$addr$5501$i (get_local $$sub806$i) - (i32.const -1) - ) - ) - (set_local $$263 - (i32.and - (get_local $$cmp745$i) - (get_local $$cmp748$i) ) ) - (if - (get_local $$263) - (block - (set_local $$d$7500$i - (get_local $$incdec$ptr808$i) - ) - (set_local $$p$addr$5501$i - (get_local $$sub806$i) - ) - ) - (block - (set_local $$p$addr$5$lcssa$i - (get_local $$sub806$i) - ) - (br $while-out113) + (block + (set_local $$p$addr$5$lcssa$i + (get_local $$sub806$i) ) + (br $while-out113) ) - (br $while-in114) ) + (br $while-in114) ) ) - (set_local $$p$addr$5$lcssa$i - (get_local $$p$addr$3$i) - ) ) - (set_local $$add810$i - (i32.add - (get_local $$p$addr$5$lcssa$i) - (i32.const 18) - ) + (set_local $$p$addr$5$lcssa$i + (get_local $$p$addr$3$i) ) - (call $_pad - (get_local $$f) - (i32.const 48) - (get_local $$add810$i) + ) + (set_local $$add810$i + (i32.add + (get_local $$p$addr$5$lcssa$i) (i32.const 18) - (i32.const 0) - ) - (set_local $$264 - (i32.load - (get_local $$f) - ) ) - (set_local $$and$i$i - (i32.and - (get_local $$264) - (i32.const 32) - ) + ) + (call $_pad + (get_local $$f) + (i32.const 48) + (get_local $$add810$i) + (i32.const 18) + (i32.const 0) + ) + (set_local $$264 + (i32.load + (get_local $$f) ) - (set_local $$tobool$i$i - (i32.eq - (get_local $$and$i$i) - (i32.const 0) - ) + ) + (set_local $$and$i$i + (i32.and + (get_local $$264) + (i32.const 32) ) - (if - (i32.eqz - (get_local $$tobool$i$i) - ) - (br $do-once99) + ) + (set_local $$tobool$i$i + (i32.eq + (get_local $$and$i$i) + (i32.const 0) ) - (set_local $$sub$ptr$rhs$cast812$i - (get_local $$estr$2$i) + ) + (if + (i32.eqz + (get_local $$tobool$i$i) ) - (set_local $$sub$ptr$sub813$i - (i32.sub - (get_local $$sub$ptr$lhs$cast160$i) - (get_local $$sub$ptr$rhs$cast812$i) - ) + (br $do-once99) + ) + (set_local $$sub$ptr$rhs$cast812$i + (get_local $$estr$2$i) + ) + (set_local $$sub$ptr$sub813$i + (i32.sub + (get_local $$sub$ptr$lhs$cast160$i) + (get_local $$sub$ptr$rhs$cast812$i) ) + ) + (drop (call $___fwritex (get_local $$estr$2$i) (get_local $$sub$ptr$sub813$i) @@ -16111,164 +16111,164 @@ (block $do-once (if (get_local $$or$cond) - (drop - (block i32 - (set_local $$sub - (i32.sub - (get_local $$w) - (get_local $$l) - ) + (block + (set_local $$sub + (i32.sub + (get_local $$w) + (get_local $$l) ) - (set_local $$cmp1 - (i32.gt_u - (get_local $$sub) - (i32.const 256) - ) + ) + (set_local $$cmp1 + (i32.gt_u + (get_local $$sub) + (i32.const 256) ) - (set_local $$cond - (if i32 - (get_local $$cmp1) - (i32.const 256) - (get_local $$sub) - ) + ) + (set_local $$cond + (if i32 + (get_local $$cmp1) + (i32.const 256) + (get_local $$sub) ) - (drop - (call $_memset - (get_local $$pad) - (get_local $$c) - (get_local $$cond) - ) + ) + (drop + (call $_memset + (get_local $$pad) + (get_local $$c) + (get_local $$cond) ) - (set_local $$cmp3$14 - (i32.gt_u - (get_local $$sub) - (i32.const 255) - ) + ) + (set_local $$cmp3$14 + (i32.gt_u + (get_local $$sub) + (i32.const 255) ) - (set_local $$0 - (i32.load - (get_local $$f) - ) + ) + (set_local $$0 + (i32.load + (get_local $$f) ) - (set_local $$and$i$15 - (i32.and - (get_local $$0) - (i32.const 32) - ) + ) + (set_local $$and$i$15 + (i32.and + (get_local $$0) + (i32.const 32) ) - (set_local $$tobool$i$16 - (i32.eq - (get_local $$and$i$15) - (i32.const 0) - ) + ) + (set_local $$tobool$i$16 + (i32.eq + (get_local $$and$i$15) + (i32.const 0) ) - (if - (get_local $$cmp3$14) - (block - (set_local $$1 - (i32.sub - (get_local $$w) - (get_local $$l) - ) - ) - (set_local $$4 - (get_local $$0) - ) - (set_local $$l$addr$017 - (get_local $$sub) - ) - (set_local $$tobool$i18 - (get_local $$tobool$i$16) + ) + (if + (get_local $$cmp3$14) + (block + (set_local $$1 + (i32.sub + (get_local $$w) + (get_local $$l) ) - (loop $while-in - (block $while-out - (if - (get_local $$tobool$i18) - (block - (drop - (call $___fwritex - (get_local $$pad) - (i32.const 256) - (get_local $$f) - ) - ) - (set_local $$$pre - (i32.load - (get_local $$f) - ) + ) + (set_local $$4 + (get_local $$0) + ) + (set_local $$l$addr$017 + (get_local $$sub) + ) + (set_local $$tobool$i18 + (get_local $$tobool$i$16) + ) + (loop $while-in + (block $while-out + (if + (get_local $$tobool$i18) + (block + (drop + (call $___fwritex + (get_local $$pad) + (i32.const 256) + (get_local $$f) ) - (set_local $$2 - (get_local $$$pre) + ) + (set_local $$$pre + (i32.load + (get_local $$f) ) ) (set_local $$2 - (get_local $$4) + (get_local $$$pre) ) ) - (set_local $$sub5 - (i32.add - (get_local $$l$addr$017) - (i32.const -256) - ) + (set_local $$2 + (get_local $$4) ) - (set_local $$cmp3 - (i32.gt_u - (get_local $$sub5) - (i32.const 255) - ) + ) + (set_local $$sub5 + (i32.add + (get_local $$l$addr$017) + (i32.const -256) ) - (set_local $$and$i - (i32.and + ) + (set_local $$cmp3 + (i32.gt_u + (get_local $$sub5) + (i32.const 255) + ) + ) + (set_local $$and$i + (i32.and + (get_local $$2) + (i32.const 32) + ) + ) + (set_local $$tobool$i + (i32.eq + (get_local $$and$i) + (i32.const 0) + ) + ) + (if + (get_local $$cmp3) + (block + (set_local $$4 (get_local $$2) - (i32.const 32) ) - ) - (set_local $$tobool$i - (i32.eq - (get_local $$and$i) - (i32.const 0) + (set_local $$l$addr$017 + (get_local $$sub5) ) - ) - (if - (get_local $$cmp3) - (block - (set_local $$4 - (get_local $$2) - ) - (set_local $$l$addr$017 - (get_local $$sub5) - ) - (set_local $$tobool$i18 - (get_local $$tobool$i) - ) + (set_local $$tobool$i18 + (get_local $$tobool$i) ) - (br $while-out) ) - (br $while-in) - ) - ) - (set_local $$3 - (i32.and - (get_local $$1) - (i32.const 255) + (br $while-out) ) + (br $while-in) ) - (if - (get_local $$tobool$i) - (set_local $$l$addr$0$lcssa21 - (get_local $$3) - ) - (br $do-once) + ) + (set_local $$3 + (i32.and + (get_local $$1) + (i32.const 255) ) ) (if - (get_local $$tobool$i$16) + (get_local $$tobool$i) (set_local $$l$addr$0$lcssa21 - (get_local $$sub) + (get_local $$3) ) (br $do-once) ) ) + (if + (get_local $$tobool$i$16) + (set_local $$l$addr$0$lcssa21 + (get_local $$sub) + ) + (br $do-once) + ) + ) + (drop (call $___fwritex (get_local $$pad) (get_local $$l$addr$0$lcssa21) diff --git a/test/emcc_hello_world.fromasm.no-opts b/test/emcc_hello_world.fromasm.no-opts index 8b59cb29bdb..2c3a2b99d6a 100644 --- a/test/emcc_hello_world.fromasm.no-opts +++ b/test/emcc_hello_world.fromasm.no-opts @@ -4529,31 +4529,31 @@ ) (if (get_local $$cmp4) - (drop - (block i32 - (set_local $$seek - (i32.add - (get_local $$f) - (i32.const 40) - ) - ) - (set_local $$6 - (i32.load - (get_local $$seek) - ) - ) - (set_local $$sub$ptr$lhs$cast - (get_local $$4) + (block + (set_local $$seek + (i32.add + (get_local $$f) + (i32.const 40) ) - (set_local $$sub$ptr$rhs$cast - (get_local $$5) + ) + (set_local $$6 + (i32.load + (get_local $$seek) ) - (set_local $$sub$ptr$sub - (i32.sub - (get_local $$sub$ptr$lhs$cast) - (get_local $$sub$ptr$rhs$cast) - ) + ) + (set_local $$sub$ptr$lhs$cast + (get_local $$4) + ) + (set_local $$sub$ptr$rhs$cast + (get_local $$5) + ) + (set_local $$sub$ptr$sub + (i32.sub + (get_local $$sub$ptr$lhs$cast) + (get_local $$sub$ptr$rhs$cast) ) + ) + (drop (call_indirect $FUNCSIG$iiii (get_local $$f) (get_local $$sub$ptr$sub) @@ -12256,17 +12256,17 @@ ) (if (get_local $$tobool$i$443$i) - (drop - (block i32 - (set_local $$sub$ptr$rhs$cast695$i - (get_local $$s668$1$i) - ) - (set_local $$sub$ptr$sub696$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast695$i) - ) + (block + (set_local $$sub$ptr$rhs$cast695$i + (get_local $$s668$1$i) + ) + (set_local $$sub$ptr$sub696$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast695$i) ) + ) + (drop (call $___fwritex (get_local $$s668$1$i) (get_local $$sub$ptr$sub696$i) @@ -12313,31 +12313,31 @@ (i32.eqz (get_local $$251) ) - (drop - (block i32 - (set_local $$252 - (i32.load - (get_local $$f) - ) + (block + (set_local $$252 + (i32.load + (get_local $$f) ) - (set_local $$and$i$448$i - (i32.and - (get_local $$252) - (i32.const 32) - ) + ) + (set_local $$and$i$448$i + (i32.and + (get_local $$252) + (i32.const 32) ) - (set_local $$tobool$i$449$i - (i32.eq - (get_local $$and$i$448$i) - (i32.const 0) - ) + ) + (set_local $$tobool$i$449$i + (i32.eq + (get_local $$and$i$448$i) + (i32.const 0) ) - (if - (i32.eqz - (get_local $$tobool$i$449$i) - ) - (br $do-once107) + ) + (if + (i32.eqz + (get_local $$tobool$i$449$i) ) + (br $do-once107) + ) + (drop (call $___fwritex (i32.const 4143) (i32.const 1) @@ -12457,21 +12457,21 @@ ) (if (get_local $$tobool$i$455$i) - (drop - (block i32 - (set_local $$cmp727$i - (i32.gt_s - (get_local $$p$addr$4489$i) - (i32.const 9) - ) + (block + (set_local $$cmp727$i + (i32.gt_s + (get_local $$p$addr$4489$i) + (i32.const 9) ) - (set_local $$cond732$i - (if i32 - (get_local $$cmp727$i) - (i32.const 9) - (get_local $$p$addr$4489$i) - ) + ) + (set_local $$cond732$i + (if i32 + (get_local $$cmp727$i) + (i32.const 9) + (get_local $$p$addr$4489$i) ) + ) + (drop (call $___fwritex (get_local $$s715$0$lcssa$i) (get_local $$cond732$i) @@ -12549,386 +12549,386 @@ (i32.const 0) ) ) - (drop - (block i32 - (set_local $$add$ptr742$i - (i32.add - (get_local $$a$9$ph$i) - (i32.const 4) - ) + (block + (set_local $$add$ptr742$i + (i32.add + (get_local $$a$9$ph$i) + (i32.const 4) ) - (set_local $$z$7$add$ptr742$i - (if i32 - (get_local $$cmp450$lcssa$i) - (get_local $$z$7$i$lcssa) - (get_local $$add$ptr742$i) - ) + ) + (set_local $$z$7$add$ptr742$i + (if i32 + (get_local $$cmp450$lcssa$i) + (get_local $$z$7$i$lcssa) + (get_local $$add$ptr742$i) ) - (set_local $$cmp748$499$i - (i32.gt_s + ) + (set_local $$cmp748$499$i + (i32.gt_s + (get_local $$p$addr$3$i) + (i32.const -1) + ) + ) + (if + (get_local $$cmp748$499$i) + (block + (set_local $$tobool781$i + (i32.eq + (get_local $$and610$pre$phi$iZ2D) + (i32.const 0) + ) + ) + (set_local $$d$7500$i + (get_local $$a$9$ph$i) + ) + (set_local $$p$addr$5501$i (get_local $$p$addr$3$i) - (i32.const -1) ) - ) - (if - (get_local $$cmp748$499$i) - (block - (set_local $$tobool781$i - (i32.eq - (get_local $$and610$pre$phi$iZ2D) - (i32.const 0) + (loop $while-in114 + (block $while-out113 + (set_local $$258 + (i32.load + (get_local $$d$7500$i) + ) ) - ) - (set_local $$d$7500$i - (get_local $$a$9$ph$i) - ) - (set_local $$p$addr$5501$i - (get_local $$p$addr$3$i) - ) - (loop $while-in114 - (block $while-out113 - (set_local $$258 - (i32.load - (get_local $$d$7500$i) - ) + (set_local $$259 + (call $_fmt_u + (get_local $$258) + (i32.const 0) + (get_local $$add$ptr671$i) ) - (set_local $$259 - (call $_fmt_u - (get_local $$258) - (i32.const 0) - (get_local $$add$ptr671$i) - ) + ) + (set_local $$cmp760$i + (i32.eq + (get_local $$259) + (get_local $$add$ptr671$i) ) - (set_local $$cmp760$i - (i32.eq - (get_local $$259) - (get_local $$add$ptr671$i) + ) + (if + (get_local $$cmp760$i) + (block + (i32.store8 + (get_local $$incdec$ptr689$i) + (i32.const 48) + ) + (set_local $$s753$0$i + (get_local $$incdec$ptr689$i) ) ) + (set_local $$s753$0$i + (get_local $$259) + ) + ) + (set_local $$cmp765$i + (i32.eq + (get_local $$d$7500$i) + (get_local $$a$9$ph$i) + ) + ) + (block $do-once115 (if - (get_local $$cmp760$i) + (get_local $$cmp765$i) (block - (i32.store8 - (get_local $$incdec$ptr689$i) - (i32.const 48) + (set_local $$incdec$ptr776$i + (i32.add + (get_local $$s753$0$i) + (i32.const 1) + ) ) - (set_local $$s753$0$i - (get_local $$incdec$ptr689$i) + (set_local $$260 + (i32.load + (get_local $$f) + ) ) - ) - (set_local $$s753$0$i - (get_local $$259) - ) - ) - (set_local $$cmp765$i - (i32.eq - (get_local $$d$7500$i) - (get_local $$a$9$ph$i) - ) - ) - (block $do-once115 - (if - (get_local $$cmp765$i) - (block - (set_local $$incdec$ptr776$i - (i32.add + (set_local $$and$i$460$i + (i32.and + (get_local $$260) + (i32.const 32) + ) + ) + (set_local $$tobool$i$461$i + (i32.eq + (get_local $$and$i$460$i) + (i32.const 0) + ) + ) + (if + (get_local $$tobool$i$461$i) + (drop + (call $___fwritex (get_local $$s753$0$i) (i32.const 1) - ) - ) - (set_local $$260 - (i32.load (get_local $$f) ) ) - (set_local $$and$i$460$i - (i32.and - (get_local $$260) - (i32.const 32) - ) - ) - (set_local $$tobool$i$461$i - (i32.eq - (get_local $$and$i$460$i) - (i32.const 0) - ) - ) - (if - (get_local $$tobool$i$461$i) - (drop - (call $___fwritex - (get_local $$s753$0$i) - (i32.const 1) - (get_local $$f) - ) - ) + ) + (set_local $$cmp777$i + (i32.lt_s + (get_local $$p$addr$5501$i) + (i32.const 1) ) - (set_local $$cmp777$i - (i32.lt_s - (get_local $$p$addr$5501$i) - (i32.const 1) - ) + ) + (set_local $$or$cond401$i + (i32.and + (get_local $$tobool781$i) + (get_local $$cmp777$i) ) - (set_local $$or$cond401$i - (i32.and - (get_local $$tobool781$i) - (get_local $$cmp777$i) + ) + (if + (get_local $$or$cond401$i) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) ) + (br $do-once115) ) - (if - (get_local $$or$cond401$i) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) - ) - (br $do-once115) - ) + ) + (set_local $$261 + (i32.load + (get_local $$f) ) - (set_local $$261 - (i32.load - (get_local $$f) - ) + ) + (set_local $$and$i$466$i + (i32.and + (get_local $$261) + (i32.const 32) ) - (set_local $$and$i$466$i - (i32.and - (get_local $$261) - (i32.const 32) - ) + ) + (set_local $$tobool$i$467$i + (i32.eq + (get_local $$and$i$466$i) + (i32.const 0) ) - (set_local $$tobool$i$467$i - (i32.eq - (get_local $$and$i$466$i) - (i32.const 0) - ) + ) + (if + (i32.eqz + (get_local $$tobool$i$467$i) ) - (if - (i32.eqz - (get_local $$tobool$i$467$i) - ) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) - ) - (br $do-once115) + (block + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) ) + (br $do-once115) ) - (drop - (call $___fwritex - (i32.const 4143) - (i32.const 1) - (get_local $$f) - ) + ) + (drop + (call $___fwritex + (i32.const 4143) + (i32.const 1) + (get_local $$f) ) - (set_local $$s753$2$i - (get_local $$incdec$ptr776$i) + ) + (set_local $$s753$2$i + (get_local $$incdec$ptr776$i) + ) + ) + (block + (set_local $$cmp770$495$i + (i32.gt_u + (get_local $$s753$0$i) + (get_local $$buf$i) ) ) - (block - (set_local $$cmp770$495$i - (i32.gt_u - (get_local $$s753$0$i) - (get_local $$buf$i) - ) + (if + (get_local $$cmp770$495$i) + (set_local $$s753$1496$i + (get_local $$s753$0$i) ) - (if - (get_local $$cmp770$495$i) - (set_local $$s753$1496$i + (block + (set_local $$s753$2$i (get_local $$s753$0$i) ) - (block - (set_local $$s753$2$i - (get_local $$s753$0$i) - ) - (br $do-once115) - ) + (br $do-once115) ) - (loop $while-in118 - (block $while-out117 - (set_local $$incdec$ptr773$i - (i32.add - (get_local $$s753$1496$i) - (i32.const -1) - ) + ) + (loop $while-in118 + (block $while-out117 + (set_local $$incdec$ptr773$i + (i32.add + (get_local $$s753$1496$i) + (i32.const -1) ) - (i32.store8 + ) + (i32.store8 + (get_local $$incdec$ptr773$i) + (i32.const 48) + ) + (set_local $$cmp770$i + (i32.gt_u (get_local $$incdec$ptr773$i) - (i32.const 48) + (get_local $$buf$i) ) - (set_local $$cmp770$i - (i32.gt_u - (get_local $$incdec$ptr773$i) - (get_local $$buf$i) - ) + ) + (if + (get_local $$cmp770$i) + (set_local $$s753$1496$i + (get_local $$incdec$ptr773$i) ) - (if - (get_local $$cmp770$i) - (set_local $$s753$1496$i + (block + (set_local $$s753$2$i (get_local $$incdec$ptr773$i) ) - (block - (set_local $$s753$2$i - (get_local $$incdec$ptr773$i) - ) - (br $while-out117) - ) + (br $while-out117) ) - (br $while-in118) ) + (br $while-in118) ) ) ) ) - (set_local $$sub$ptr$rhs$cast788$i - (get_local $$s753$2$i) - ) - (set_local $$sub$ptr$sub789$i - (i32.sub - (get_local $$sub$ptr$lhs$cast694$i) - (get_local $$sub$ptr$rhs$cast788$i) - ) + ) + (set_local $$sub$ptr$rhs$cast788$i + (get_local $$s753$2$i) + ) + (set_local $$sub$ptr$sub789$i + (i32.sub + (get_local $$sub$ptr$lhs$cast694$i) + (get_local $$sub$ptr$rhs$cast788$i) ) - (set_local $$262 - (i32.load - (get_local $$f) - ) + ) + (set_local $$262 + (i32.load + (get_local $$f) ) - (set_local $$and$i$472$i - (i32.and - (get_local $$262) - (i32.const 32) - ) + ) + (set_local $$and$i$472$i + (i32.and + (get_local $$262) + (i32.const 32) ) - (set_local $$tobool$i$473$i - (i32.eq - (get_local $$and$i$472$i) - (i32.const 0) - ) + ) + (set_local $$tobool$i$473$i + (i32.eq + (get_local $$and$i$472$i) + (i32.const 0) ) - (if - (get_local $$tobool$i$473$i) + ) + (if + (get_local $$tobool$i$473$i) + (block + (set_local $$cmp790$i + (i32.gt_s + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) + ) + ) + (set_local $$cond800$i + (if i32 + (get_local $$cmp790$i) + (get_local $$sub$ptr$sub789$i) + (get_local $$p$addr$5501$i) + ) + ) (drop - (block i32 - (set_local $$cmp790$i - (i32.gt_s - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) - ) - (set_local $$cond800$i - (if i32 - (get_local $$cmp790$i) - (get_local $$sub$ptr$sub789$i) - (get_local $$p$addr$5501$i) - ) - ) - (call $___fwritex - (get_local $$s753$2$i) - (get_local $$cond800$i) - (get_local $$f) - ) + (call $___fwritex + (get_local $$s753$2$i) + (get_local $$cond800$i) + (get_local $$f) ) ) ) - (set_local $$sub806$i - (i32.sub - (get_local $$p$addr$5501$i) - (get_local $$sub$ptr$sub789$i) - ) + ) + (set_local $$sub806$i + (i32.sub + (get_local $$p$addr$5501$i) + (get_local $$sub$ptr$sub789$i) ) - (set_local $$incdec$ptr808$i - (i32.add - (get_local $$d$7500$i) - (i32.const 4) - ) + ) + (set_local $$incdec$ptr808$i + (i32.add + (get_local $$d$7500$i) + (i32.const 4) ) - (set_local $$cmp745$i - (i32.lt_u + ) + (set_local $$cmp745$i + (i32.lt_u + (get_local $$incdec$ptr808$i) + (get_local $$z$7$add$ptr742$i) + ) + ) + (set_local $$cmp748$i + (i32.gt_s + (get_local $$sub806$i) + (i32.const -1) + ) + ) + (set_local $$263 + (i32.and + (get_local $$cmp745$i) + (get_local $$cmp748$i) + ) + ) + (if + (get_local $$263) + (block + (set_local $$d$7500$i (get_local $$incdec$ptr808$i) - (get_local $$z$7$add$ptr742$i) ) - ) - (set_local $$cmp748$i - (i32.gt_s + (set_local $$p$addr$5501$i (get_local $$sub806$i) - (i32.const -1) - ) - ) - (set_local $$263 - (i32.and - (get_local $$cmp745$i) - (get_local $$cmp748$i) ) ) - (if - (get_local $$263) - (block - (set_local $$d$7500$i - (get_local $$incdec$ptr808$i) - ) - (set_local $$p$addr$5501$i - (get_local $$sub806$i) - ) - ) - (block - (set_local $$p$addr$5$lcssa$i - (get_local $$sub806$i) - ) - (br $while-out113) + (block + (set_local $$p$addr$5$lcssa$i + (get_local $$sub806$i) ) + (br $while-out113) ) - (br $while-in114) ) + (br $while-in114) ) ) - (set_local $$p$addr$5$lcssa$i - (get_local $$p$addr$3$i) - ) ) - (set_local $$add810$i - (i32.add - (get_local $$p$addr$5$lcssa$i) - (i32.const 18) - ) + (set_local $$p$addr$5$lcssa$i + (get_local $$p$addr$3$i) ) - (call $_pad - (get_local $$f) - (i32.const 48) - (get_local $$add810$i) + ) + (set_local $$add810$i + (i32.add + (get_local $$p$addr$5$lcssa$i) (i32.const 18) - (i32.const 0) - ) - (set_local $$264 - (i32.load - (get_local $$f) - ) ) - (set_local $$and$i$i - (i32.and - (get_local $$264) - (i32.const 32) - ) + ) + (call $_pad + (get_local $$f) + (i32.const 48) + (get_local $$add810$i) + (i32.const 18) + (i32.const 0) + ) + (set_local $$264 + (i32.load + (get_local $$f) ) - (set_local $$tobool$i$i - (i32.eq - (get_local $$and$i$i) - (i32.const 0) - ) + ) + (set_local $$and$i$i + (i32.and + (get_local $$264) + (i32.const 32) ) - (if - (i32.eqz - (get_local $$tobool$i$i) - ) - (br $do-once99) + ) + (set_local $$tobool$i$i + (i32.eq + (get_local $$and$i$i) + (i32.const 0) ) - (set_local $$sub$ptr$rhs$cast812$i - (get_local $$estr$2$i) + ) + (if + (i32.eqz + (get_local $$tobool$i$i) ) - (set_local $$sub$ptr$sub813$i - (i32.sub - (get_local $$sub$ptr$lhs$cast160$i) - (get_local $$sub$ptr$rhs$cast812$i) - ) + (br $do-once99) + ) + (set_local $$sub$ptr$rhs$cast812$i + (get_local $$estr$2$i) + ) + (set_local $$sub$ptr$sub813$i + (i32.sub + (get_local $$sub$ptr$lhs$cast160$i) + (get_local $$sub$ptr$rhs$cast812$i) ) + ) + (drop (call $___fwritex (get_local $$estr$2$i) (get_local $$sub$ptr$sub813$i) @@ -16117,164 +16117,164 @@ (block $do-once (if (get_local $$or$cond) - (drop - (block i32 - (set_local $$sub - (i32.sub - (get_local $$w) - (get_local $$l) - ) + (block + (set_local $$sub + (i32.sub + (get_local $$w) + (get_local $$l) ) - (set_local $$cmp1 - (i32.gt_u - (get_local $$sub) - (i32.const 256) - ) + ) + (set_local $$cmp1 + (i32.gt_u + (get_local $$sub) + (i32.const 256) ) - (set_local $$cond - (if i32 - (get_local $$cmp1) - (i32.const 256) - (get_local $$sub) - ) + ) + (set_local $$cond + (if i32 + (get_local $$cmp1) + (i32.const 256) + (get_local $$sub) ) - (drop - (call $_memset - (get_local $$pad) - (get_local $$c) - (get_local $$cond) - ) + ) + (drop + (call $_memset + (get_local $$pad) + (get_local $$c) + (get_local $$cond) ) - (set_local $$cmp3$14 - (i32.gt_u - (get_local $$sub) - (i32.const 255) - ) + ) + (set_local $$cmp3$14 + (i32.gt_u + (get_local $$sub) + (i32.const 255) ) - (set_local $$0 - (i32.load - (get_local $$f) - ) + ) + (set_local $$0 + (i32.load + (get_local $$f) ) - (set_local $$and$i$15 - (i32.and - (get_local $$0) - (i32.const 32) - ) + ) + (set_local $$and$i$15 + (i32.and + (get_local $$0) + (i32.const 32) ) - (set_local $$tobool$i$16 - (i32.eq - (get_local $$and$i$15) - (i32.const 0) - ) + ) + (set_local $$tobool$i$16 + (i32.eq + (get_local $$and$i$15) + (i32.const 0) ) - (if - (get_local $$cmp3$14) - (block - (set_local $$1 - (i32.sub - (get_local $$w) - (get_local $$l) - ) - ) - (set_local $$4 - (get_local $$0) - ) - (set_local $$l$addr$017 - (get_local $$sub) - ) - (set_local $$tobool$i18 - (get_local $$tobool$i$16) + ) + (if + (get_local $$cmp3$14) + (block + (set_local $$1 + (i32.sub + (get_local $$w) + (get_local $$l) ) - (loop $while-in - (block $while-out - (if - (get_local $$tobool$i18) - (block - (drop - (call $___fwritex - (get_local $$pad) - (i32.const 256) - (get_local $$f) - ) - ) - (set_local $$$pre - (i32.load - (get_local $$f) - ) + ) + (set_local $$4 + (get_local $$0) + ) + (set_local $$l$addr$017 + (get_local $$sub) + ) + (set_local $$tobool$i18 + (get_local $$tobool$i$16) + ) + (loop $while-in + (block $while-out + (if + (get_local $$tobool$i18) + (block + (drop + (call $___fwritex + (get_local $$pad) + (i32.const 256) + (get_local $$f) ) - (set_local $$2 - (get_local $$$pre) + ) + (set_local $$$pre + (i32.load + (get_local $$f) ) ) (set_local $$2 - (get_local $$4) + (get_local $$$pre) ) ) - (set_local $$sub5 - (i32.add - (get_local $$l$addr$017) - (i32.const -256) - ) + (set_local $$2 + (get_local $$4) ) - (set_local $$cmp3 - (i32.gt_u - (get_local $$sub5) - (i32.const 255) - ) + ) + (set_local $$sub5 + (i32.add + (get_local $$l$addr$017) + (i32.const -256) ) - (set_local $$and$i - (i32.and + ) + (set_local $$cmp3 + (i32.gt_u + (get_local $$sub5) + (i32.const 255) + ) + ) + (set_local $$and$i + (i32.and + (get_local $$2) + (i32.const 32) + ) + ) + (set_local $$tobool$i + (i32.eq + (get_local $$and$i) + (i32.const 0) + ) + ) + (if + (get_local $$cmp3) + (block + (set_local $$4 (get_local $$2) - (i32.const 32) ) - ) - (set_local $$tobool$i - (i32.eq - (get_local $$and$i) - (i32.const 0) + (set_local $$l$addr$017 + (get_local $$sub5) ) - ) - (if - (get_local $$cmp3) - (block - (set_local $$4 - (get_local $$2) - ) - (set_local $$l$addr$017 - (get_local $$sub5) - ) - (set_local $$tobool$i18 - (get_local $$tobool$i) - ) + (set_local $$tobool$i18 + (get_local $$tobool$i) ) - (br $while-out) ) - (br $while-in) - ) - ) - (set_local $$3 - (i32.and - (get_local $$1) - (i32.const 255) + (br $while-out) ) + (br $while-in) ) - (if - (get_local $$tobool$i) - (set_local $$l$addr$0$lcssa21 - (get_local $$3) - ) - (br $do-once) + ) + (set_local $$3 + (i32.and + (get_local $$1) + (i32.const 255) ) ) (if - (get_local $$tobool$i$16) + (get_local $$tobool$i) (set_local $$l$addr$0$lcssa21 - (get_local $$sub) + (get_local $$3) ) (br $do-once) ) ) + (if + (get_local $$tobool$i$16) + (set_local $$l$addr$0$lcssa21 + (get_local $$sub) + ) + (br $do-once) + ) + ) + (drop (call $___fwritex (get_local $$pad) (get_local $$l$addr$0$lcssa21) diff --git a/test/min.fromasm.imprecise.no-opts b/test/min.fromasm.imprecise.no-opts index 69d292ff616..6e8a1c9ead7 100644 --- a/test/min.fromasm.imprecise.no-opts +++ b/test/min.fromasm.imprecise.no-opts @@ -41,24 +41,22 @@ ) (func $bitcasts (param $i i32) (param $f f32) (drop - (block i32 - (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) - ) - ) - ) - (i32.reinterpret/f32 - (get_local $f) + (f32.reinterpret/i32 + (get_local $i) + ) + ) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) ) ) ) + (drop + (i32.reinterpret/f32 + (get_local $f) + ) + ) ) (func $ctzzzz (result i32) (return diff --git a/test/min.fromasm.no-opts b/test/min.fromasm.no-opts index 69d292ff616..6e8a1c9ead7 100644 --- a/test/min.fromasm.no-opts +++ b/test/min.fromasm.no-opts @@ -41,24 +41,22 @@ ) (func $bitcasts (param $i i32) (param $f f32) (drop - (block i32 - (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) - ) - ) - ) - (i32.reinterpret/f32 - (get_local $f) + (f32.reinterpret/i32 + (get_local $i) + ) + ) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) ) ) ) + (drop + (i32.reinterpret/f32 + (get_local $f) + ) + ) ) (func $ctzzzz (result i32) (return diff --git a/test/unit.fromasm b/test/unit.fromasm index 5ba4b35b59d..fc1a6e114dc 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -1106,13 +1106,11 @@ (call $return_int) ) (func $dropIgnoredImportInIf (param $0 i32) (param $1 i32) (param $2 i32) - (block $do-once - (if - (get_local $0) - (drop - (call $lb - (get_local $2) - ) + (if + (get_local $0) + (drop + (call $lb + (get_local $2) ) ) ) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index 6ccfb5b2087..0350ea0842b 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -1082,13 +1082,11 @@ (call $return_int) ) (func $dropIgnoredImportInIf (param $0 i32) (param $1 i32) (param $2 i32) - (block $do-once - (if - (get_local $0) - (drop - (call $lb - (get_local $2) - ) + (if + (get_local $0) + (drop + (call $lb + (get_local $2) ) ) ) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index d98bc45e5d3..5cdb2719ac6 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -392,27 +392,25 @@ (local $y f32) (local $z f64) (drop - (block f32 - (drop - (f32.demote/f64 - (get_local $z) - ) - ) - (drop - (get_local $y) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (f32.const 0) + (f32.demote/f64 + (get_local $z) ) ) + (drop + (get_local $y) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) ) (func $negZero (result f64) (return @@ -674,28 +672,26 @@ (func $bitcasts (param $i i32) (param $f f32) (local $d f64) (drop - (block i32 - (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) - ) - ) - ) - (drop - (i32.reinterpret/f32 - (get_local $f) - ) + (f32.reinterpret/i32 + (get_local $i) + ) + ) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) ) - (i32.reinterpret/f32 - (f32.demote/f64 - (get_local $d) - ) + ) + ) + (drop + (i32.reinterpret/f32 + (get_local $f) + ) + ) + (drop + (i32.reinterpret/f32 + (f32.demote/f64 + (get_local $d) ) ) ) @@ -1768,21 +1764,20 @@ ) (func $dropIgnoredImportInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (drop - (if i32 - (get_local $$0) - (block i32 - (set_local $$0 - (i32.const 1) - ) + (if + (get_local $$0) + (block + (set_local $$0 + (i32.const 1) + ) + (drop (call $lb (get_local $$2) ) ) - (br $do-once) ) + (br $do-once) ) - (nop) ) (return) ) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index e7fc1bb7121..706bcaeaf08 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -398,27 +398,25 @@ (local $y f32) (local $z f64) (drop - (block f32 - (drop - (f32.demote/f64 - (get_local $z) - ) - ) - (drop - (get_local $y) - ) - (drop - (f32.const 5) - ) - (drop - (f32.const 0) - ) - (drop - (f32.const 5) - ) - (f32.const 0) + (f32.demote/f64 + (get_local $z) ) ) + (drop + (get_local $y) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) + (drop + (f32.const 5) + ) + (drop + (f32.const 0) + ) ) (func $negZero (result f64) (return @@ -680,28 +678,26 @@ (func $bitcasts (param $i i32) (param $f f32) (local $d f64) (drop - (block i32 - (drop - (f32.reinterpret/i32 - (get_local $i) - ) - ) - (drop - (f64.promote/f32 - (f32.reinterpret/i32 - (get_local $i) - ) - ) - ) - (drop - (i32.reinterpret/f32 - (get_local $f) - ) + (f32.reinterpret/i32 + (get_local $i) + ) + ) + (drop + (f64.promote/f32 + (f32.reinterpret/i32 + (get_local $i) ) - (i32.reinterpret/f32 - (f32.demote/f64 - (get_local $d) - ) + ) + ) + (drop + (i32.reinterpret/f32 + (get_local $f) + ) + ) + (drop + (i32.reinterpret/f32 + (f32.demote/f64 + (get_local $d) ) ) ) @@ -1774,21 +1770,20 @@ ) (func $dropIgnoredImportInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (drop - (if i32 - (get_local $$0) - (block i32 - (set_local $$0 - (i32.const 1) - ) + (if + (get_local $$0) + (block + (set_local $$0 + (i32.const 1) + ) + (drop (call $lb (get_local $$2) ) ) - (br $do-once) ) + (br $do-once) ) - (nop) ) (return) ) diff --git a/test/wasm-only.asm.js b/test/wasm-only.asm.js index 35ce30dc43e..14159fdf2e5 100644 --- a/test/wasm-only.asm.js +++ b/test/wasm-only.asm.js @@ -24,6 +24,8 @@ function asm(global, env, buffer) { var _fabsf = env._fabsf; var do_i64 = env.do_i64; + var STACKTOP = 0; + function loads() { var i = 0, f = fround(0), d = +0; i = load1(100); @@ -303,6 +305,28 @@ function asm(global, env, buffer) { } } + function _pthread_mutex_lock(x) { x = x | 0; return 0; } + function _pthread_cond_wait(x, y) { x = x | 0; y = y | 0; return 0; } + + function __ZNSt3__211__call_onceERVmPvPFvS2_E($flag,$arg,$func) { + $flag = $flag|0; + $arg = $arg|0; + $func = $func|0; + var $0 = 0, $1 = 0, $cmp = 0, sp = 0; + sp = STACKTOP; + (_pthread_mutex_lock((21396|0))|0); + while(1) { + $0 = load4($flag); + $cmp = ($0|0)==(1); + if (!($cmp)) { + break; + } + (_pthread_cond_wait((21424|0),(21396|0))|0); // must be dropped properly + } + $1 = load4($flag); + return; + } + function keepAlive() { loads(); stores(); @@ -317,6 +341,7 @@ function asm(global, env, buffer) { switch64(i64(0)) | 0; unreachable_leftovers(0, 0, 0); propagateFallthrough() | 0; + __ZNSt3__211__call_onceERVmPvPFvS2_E(0, 0, 0); } function __emscripten_dceable_type_decls() { // dce-able, but this defines the type of fabsf which has no other use diff --git a/test/wasm-only.fromasm b/test/wasm-only.fromasm index 3fd5bc8946a..4cb68e750f1 100644 --- a/test/wasm-only.fromasm +++ b/test/wasm-only.fromasm @@ -377,57 +377,92 @@ (get_local $0) ) ) - (func $keepAlive + (func $_pthread_mutex_lock (param $0 i32) (result i32) + (i32.const 0) + ) + (func $_pthread_cond_wait (param $0 i32) (param $1 i32) (result i32) + (i32.const 0) + ) + (func $__ZNSt3__211__call_onceERVmPvPFvS2_E (param $0 i32) (param $1 i32) (param $2 i32) (drop - (block i32 - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) - ) - (drop - (call $call2 - (i64.const 0) - ) - ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) - ) - ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (call $_pthread_mutex_lock + (i32.const 21396) + ) + ) + (loop $while-in + (if + (i32.eq + (i32.load + (get_local $0) ) + (i32.const 1) ) - (drop - (call $switch64 - (i64.const 0) + (block + (drop + (call $_pthread_cond_wait + (i32.const 21424) + (i32.const 21396) + ) ) + (br $while-in) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - (call $propagateFallthrough) ) ) ) + (func $keepAlive + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (drop + (call $propagateFallthrough) + ) + (call $__ZNSt3__211__call_onceERVmPvPFvS2_E + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam (get_local $0) diff --git a/test/wasm-only.fromasm.imprecise b/test/wasm-only.fromasm.imprecise index 4a6b456edb8..dc2e8996c16 100644 --- a/test/wasm-only.fromasm.imprecise +++ b/test/wasm-only.fromasm.imprecise @@ -305,57 +305,92 @@ (get_local $0) ) ) - (func $keepAlive + (func $_pthread_mutex_lock (param $0 i32) (result i32) + (i32.const 0) + ) + (func $_pthread_cond_wait (param $0 i32) (param $1 i32) (result i32) + (i32.const 0) + ) + (func $__ZNSt3__211__call_onceERVmPvPFvS2_E (param $0 i32) (param $1 i32) (param $2 i32) (drop - (block i32 - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) - ) - (drop - (call $call2 - (i64.const 0) - ) - ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) - ) - ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (call $_pthread_mutex_lock + (i32.const 21396) + ) + ) + (loop $while-in + (if + (i32.eq + (i32.load + (get_local $0) ) + (i32.const 1) ) - (drop - (call $switch64 - (i64.const 0) + (block + (drop + (call $_pthread_cond_wait + (i32.const 21424) + (i32.const 21396) + ) ) + (br $while-in) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - (call $propagateFallthrough) ) ) ) + (func $keepAlive + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (drop + (call $propagateFallthrough) + ) + (call $__ZNSt3__211__call_onceERVmPvPFvS2_E + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam (get_local $0) diff --git a/test/wasm-only.fromasm.imprecise.no-opts b/test/wasm-only.fromasm.imprecise.no-opts index 5f991dc94c7..8e56c7066e4 100644 --- a/test/wasm-only.fromasm.imprecise.no-opts +++ b/test/wasm-only.fromasm.imprecise.no-opts @@ -18,6 +18,7 @@ (import "env" "table" (table 3 3 anyfunc)) (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) + (global $STACKTOP (mut i32) (i32.const 0)) (global $tempRet0 (mut i32) (i32.const 0)) (elem (get_global $tableBase) $legalfunc$illegalImport $legalfunc$_fabsf $legalfunc$do_i64) (export "test64" (func $test64)) @@ -923,68 +924,127 @@ ) ) ) - (func $keepAlive + (func $_pthread_mutex_lock (param $x i32) (result i32) + (return + (i32.const 0) + ) + ) + (func $_pthread_cond_wait (param $x i32) (param $y i32) (result i32) + (return + (i32.const 0) + ) + ) + (func $__ZNSt3__211__call_onceERVmPvPFvS2_E (param $$flag i32) (param $$arg i32) (param $$func i32) + (local $$0 i32) + (local $$1 i32) + (local $$cmp i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) (drop - (block i32 - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) - ) - (drop - (call $call2 - (i64.const 0) + (call $_pthread_mutex_lock + (i32.const 21396) + ) + ) + (loop $while-in + (block $while-out + (set_local $$0 + (i32.load + (get_local $$flag) ) ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) + (set_local $$cmp + (i32.eq + (get_local $$0) + (i32.const 1) ) ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (if + (i32.eqz + (get_local $$cmp) ) + (br $while-out) ) (drop - (call $switch64 - (i64.const 0) + (call $_pthread_cond_wait + (i32.const 21424) + (i32.const 21396) ) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - (call $propagateFallthrough) + (br $while-in) ) ) + (set_local $$1 + (i32.load + (get_local $$flag) + ) + ) + (return) + ) + (func $keepAlive + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (drop + (call $propagateFallthrough) + ) + (call $__ZNSt3__211__call_onceERVmPvPFvS2_E + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) ) (func $__emscripten_dceable_type_decls (drop - (block i64 - (drop - (call $legalfunc$_fabsf - (f32.const 0) - ) - ) - (call $legalfunc$do_i64) + (call $legalfunc$_fabsf + (f32.const 0) ) ) + (drop + (call $legalfunc$do_i64) + ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.no-opts b/test/wasm-only.fromasm.no-opts index 0b81307a02e..5aceaf34dc0 100644 --- a/test/wasm-only.fromasm.no-opts +++ b/test/wasm-only.fromasm.no-opts @@ -18,6 +18,7 @@ (import "env" "table" (table 3 3 anyfunc)) (import "env" "memoryBase" (global $memoryBase i32)) (import "env" "tableBase" (global $tableBase i32)) + (global $STACKTOP (mut i32) (i32.const 0)) (global $tempRet0 (mut i32) (i32.const 0)) (elem (get_global $tableBase) $legalfunc$illegalImport $legalfunc$_fabsf $legalfunc$do_i64) (export "test64" (func $test64)) @@ -971,68 +972,127 @@ ) ) ) - (func $keepAlive + (func $_pthread_mutex_lock (param $x i32) (result i32) + (return + (i32.const 0) + ) + ) + (func $_pthread_cond_wait (param $x i32) (param $y i32) (result i32) + (return + (i32.const 0) + ) + ) + (func $__ZNSt3__211__call_onceERVmPvPFvS2_E (param $$flag i32) (param $$arg i32) (param $$func i32) + (local $$0 i32) + (local $$1 i32) + (local $$cmp i32) + (local $sp i32) + (set_local $sp + (get_global $STACKTOP) + ) (drop - (block i32 - (call $loads) - (call $stores) - (call $test) - (drop - (call $imports) - ) - (call $arg - (i64.const 0) - ) - (drop - (call $call1 - (i64.const 0) - ) - ) - (drop - (call $call2 - (i64.const 0) + (call $_pthread_mutex_lock + (i32.const 21396) + ) + ) + (loop $while-in + (block $while-out + (set_local $$0 + (i32.load + (get_local $$flag) ) ) - (drop - (call $returnCastConst) - ) - (drop - (call $ifValue64 - (i64.const 0) - (i64.const 0) + (set_local $$cmp + (i32.eq + (get_local $$0) + (i32.const 1) ) ) - (drop - (call $ifValue32 - (i32.const 0) - (i32.const 0) + (if + (i32.eqz + (get_local $$cmp) ) + (br $while-out) ) (drop - (call $switch64 - (i64.const 0) + (call $_pthread_cond_wait + (i32.const 21424) + (i32.const 21396) ) ) - (call $unreachable_leftovers - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - (call $propagateFallthrough) + (br $while-in) ) ) + (set_local $$1 + (i32.load + (get_local $$flag) + ) + ) + (return) + ) + (func $keepAlive + (call $loads) + (call $stores) + (call $test) + (drop + (call $imports) + ) + (call $arg + (i64.const 0) + ) + (drop + (call $call1 + (i64.const 0) + ) + ) + (drop + (call $call2 + (i64.const 0) + ) + ) + (drop + (call $returnCastConst) + ) + (drop + (call $ifValue64 + (i64.const 0) + (i64.const 0) + ) + ) + (drop + (call $ifValue32 + (i32.const 0) + (i32.const 0) + ) + ) + (drop + (call $switch64 + (i64.const 0) + ) + ) + (call $unreachable_leftovers + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + (drop + (call $propagateFallthrough) + ) + (call $__ZNSt3__211__call_onceERVmPvPFvS2_E + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) ) (func $__emscripten_dceable_type_decls (drop - (block i64 - (drop - (call $legalfunc$_fabsf - (f32.const 0) - ) - ) - (call $legalfunc$do_i64) + (call $legalfunc$_fabsf + (f32.const 0) ) ) + (drop + (call $legalfunc$do_i64) + ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam From 0e7da4823daef2520b51864b3ddb5dcf024a45ac Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Sun, 5 Feb 2017 17:10:13 -0800 Subject: [PATCH 04/17] explicitly drop children of blocks, ifs and loops, and validate that their children must have the same type as them if they are concretely typed --- src/asm2wasm.h | 17 +++++------ src/ast_utils.h | 4 +++ src/wasm-validator.h | 20 ++++++++++-- test/unit.fromasm | 12 +++----- test/unit.fromasm.imprecise | 12 +++----- test/unit.fromasm.imprecise.no-opts | 47 ++++++++++++++--------------- test/unit.fromasm.no-opts | 47 ++++++++++++++--------------- 7 files changed, 86 insertions(+), 73 deletions(-) diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 0eb7bd251ec..0fd1d4c7878 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1509,8 +1509,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { abort_on("bad unary", ast); } else if (what == IF) { auto* condition = process(ast[1]); - auto* ifTrue = process(ast[2]); - return builder.makeIf(truncateToInt32(condition), ifTrue, !!ast[3] ? process(ast[3]) : nullptr); + auto* ifTrue = builder.dropIfConcretelyTyped(process(ast[2])); + auto* ifFalse = !!ast[3] ? builder.dropIfConcretelyTyped(process(ast[3])) : nullptr; + return builder.makeIf(truncateToInt32(condition), ifTrue, ifFalse); } else if (what == CALL) { if (ast[1]->isString()) { IString name = ast[1]->getIString(); @@ -1885,7 +1886,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { continuer->name = ret->name; block->list.push_back(continuer); block->finalize(); - ret->body = block; + ret->body = builder.dropIfConcretelyTyped(block); ret->finalize(); continueStack.pop_back(); breakStack.pop_back(); @@ -1906,7 +1907,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { Name more = nameMapper.pushLabelName("unlikely-continue"); breakStack.push_back(stop); continueStack.push_back(more); - auto child = process(ast[2]); + auto child = builder.dropIfConcretelyTyped(process(ast[2])); continueStack.pop_back(); breakStack.pop_back(); nameMapper.popLabelName(more); @@ -1947,7 +1948,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { loop->name = in; breakStack.push_back(out); continueStack.push_back(in); - loop->body = process(ast[2]); + loop->body = builder.dropIfConcretelyTyped(process(ast[2])); continueStack.pop_back(); breakStack.pop_back(); nameMapper.popLabelName(in); @@ -1990,7 +1991,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { body->list.push_back(process(fbody)); body->list.push_back(process(finc)); body->finalize(); - ret->body = body; + ret->body = builder.dropIfConcretelyTyped(body); // loops do not automatically loop, add a branch back auto continuer = allocator.alloc(); continuer->name = ret->name; @@ -2271,9 +2272,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { block->list.push_back(process(ast[i])); } // if the last element has a value, we must drop it - a list of statements never falls through in asm.js - if (isConcreteWasmType(block->list.back()->type)) { - block->list.back() = builder.makeDrop(block->list.back()); - } + block->list.back() = builder.dropIfConcretelyTyped(block->list.back()); block->finalize(); return block; }; diff --git a/src/ast_utils.h b/src/ast_utils.h index f20143a54c1..1221c5b9467 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -270,6 +270,10 @@ struct ExpressionAnalyzer { return !curr->condition && !curr->value; } + static bool isControlFlowStructure(Expression* curr) { + return curr->is() || curr->is() || curr->is(); + } + // Checks if an expression does not flow out in an obvious way. // We return true if it cannot flow out. If it can flow out, we // might still return true, as the analysis here is simple and fast. diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 28e575ca48d..80f61595384 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -41,6 +41,7 @@ #include "wasm.h" #include "wasm-printing.h" +#include "ast_utils.h" namespace wasm { @@ -127,8 +128,14 @@ struct WasmValidator : public PostWalker> } } } - if (!isConcreteWasmType(curr->type) && curr->list.size() > 0) { - shouldBeFalse(isConcreteWasmType(curr->list.back()->type), curr, "block with no value cannot have a last element with a value"); + if (curr->list.size() > 0) { + auto* last = curr->list.back(); + if (!isConcreteWasmType(curr->type)) { + shouldBeFalse(isConcreteWasmType(last->type), curr, "block with no value cannot have a last element with a value"); + } else { + // if we return, then control flow children must have that type, not even unreachable + if (ExpressionAnalyzer::isControlFlowStructure(last)) shouldBeEqual(last->type, curr->type, curr, "block fallthrough must have right type"); + } } } @@ -149,6 +156,10 @@ struct WasmValidator : public PostWalker> if (curr->type == none) { shouldBeFalse(isConcreteWasmType(curr->body->type), curr, "bad body for a loop that has no value"); } + // if we return, then control flow children must have that type, not even unreachable + if (isConcreteWasmType(curr->type)) { + if (ExpressionAnalyzer::isControlFlowStructure(curr->body)) shouldBeEqual(curr->body->type, curr->type, curr, "loop child must have right type"); + } } void visitIf(If *curr) { @@ -156,6 +167,11 @@ struct WasmValidator : public PostWalker> if (!curr->ifFalse) { shouldBeFalse(isConcreteWasmType(curr->ifTrue->type), curr, "if without else must not return a value in body"); } + // if we return, then control flow children must have that type, not even unreachable + if (isConcreteWasmType(curr->type)) { + if (ExpressionAnalyzer::isControlFlowStructure(curr->ifTrue)) shouldBeEqual(curr->ifTrue->type, curr->type, curr, "ifTrue child must have right type"); + if (ExpressionAnalyzer::isControlFlowStructure(curr->ifFalse)) shouldBeEqual(curr->ifFalse->type, curr->type, curr, "ifFalse child must have right type"); + } } // override scan to add a pre and a post check task to all nodes diff --git a/test/unit.fromasm b/test/unit.fromasm index fc1a6e114dc..76e383ac839 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -543,13 +543,11 @@ ) ) (func $smallIf - (block $do-once - (if - (call $return_int) - (drop - (call $lb - (i32.const 3) - ) + (if + (call $return_int) + (drop + (call $lb + (i32.const 3) ) ) ) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index 0350ea0842b..82718805392 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -519,13 +519,11 @@ ) ) (func $smallIf - (block $do-once - (if - (call $return_int) - (drop - (call $lb - (i32.const 3) - ) + (if + (call $return_int) + (drop + (call $lb + (i32.const 3) ) ) ) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index 5cdb2719ac6..3bc6482b78d 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -922,16 +922,15 @@ ) (func $smallIf (block $do-once - (drop - (if i32 - (call $return_int) + (if + (call $return_int) + (drop (call $lb (i32.const 3) ) - (br $do-once) ) + (br $do-once) ) - (nop) ) ) (func $dropCall (result i32) @@ -996,27 +995,26 @@ ) (func $breakThroughMany (param $$s i32) (block $label$break$L1 - (drop - (if i32 - (get_local $$s) - (loop $while-in - (block $while-out - (if - (i32.eqz - (get_local $$s) - ) - (br $label$break$L1) - ) - (call $zeroInit - (i32.const 0) + (if + (get_local $$s) + (loop $while-in + (block $while-out + (if + (i32.eqz + (get_local $$s) ) - (br $while-in) + (br $label$break$L1) + ) + (call $zeroInit + (i32.const 0) ) + (br $while-in) ) + ) + (drop (i32.const 1337) ) ) - (nop) ) ) (func $ifChainEmpty (param $label i32) (result i32) @@ -1788,18 +1786,19 @@ ) (func $dropIgnoredImportsInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (drop - (if i32 - (get_local $$0) + (if + (get_local $$0) + (drop (call $lb (get_local $$1) ) + ) + (drop (call $lb (get_local $$2) ) ) ) - (nop) ) (return) ) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index 706bcaeaf08..437301587b1 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -928,16 +928,15 @@ ) (func $smallIf (block $do-once - (drop - (if i32 - (call $return_int) + (if + (call $return_int) + (drop (call $lb (i32.const 3) ) - (br $do-once) ) + (br $do-once) ) - (nop) ) ) (func $dropCall (result i32) @@ -1002,27 +1001,26 @@ ) (func $breakThroughMany (param $$s i32) (block $label$break$L1 - (drop - (if i32 - (get_local $$s) - (loop $while-in - (block $while-out - (if - (i32.eqz - (get_local $$s) - ) - (br $label$break$L1) - ) - (call $zeroInit - (i32.const 0) + (if + (get_local $$s) + (loop $while-in + (block $while-out + (if + (i32.eqz + (get_local $$s) ) - (br $while-in) + (br $label$break$L1) + ) + (call $zeroInit + (i32.const 0) ) + (br $while-in) ) + ) + (drop (i32.const 1337) ) ) - (nop) ) ) (func $ifChainEmpty (param $label i32) (result i32) @@ -1794,18 +1792,19 @@ ) (func $dropIgnoredImportsInIf (param $$0 i32) (param $$1 i32) (param $$2 i32) (block $do-once - (drop - (if i32 - (get_local $$0) + (if + (get_local $$0) + (drop (call $lb (get_local $$1) ) + ) + (drop (call $lb (get_local $$2) ) ) ) - (nop) ) (return) ) From 5e34c065c07970d7c12a55c82f4bfc91f907a2d9 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Sun, 5 Feb 2017 20:10:28 -0800 Subject: [PATCH 05/17] propagate types in finalize() (without a param) as well --- src/wasm.h | 3 +++ src/wasm/wasm.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/wasm.h b/src/wasm.h index 117ca3c45f6..64da40a7bb7 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -975,6 +975,7 @@ class Block : public SpecificExpression { // set the type purely based on its contents. this scans the block, so it is not fast. // if the type is already something concrete, we do not alter it, so that if our // contents to not imply a result but the parent does, then we remain valid + // we also propage a new concrete type to children as needed. void finalize(); }; @@ -998,6 +999,7 @@ class If : public SpecificExpression { // set the type purely based on its contents. // if the type is already something concrete, we do not alter it, so that if our // contents to not imply a result but the parent does, then we remain valid + // we also propage a new concrete type to children as needed. void finalize(); }; @@ -1020,6 +1022,7 @@ class Loop : public SpecificExpression { // set the type purely based on its contents. // if the type is already something concrete, we do not alter it, so that if our // contents to not imply a result but the parent does, then we remain valid + // we also propage a new concrete type to children as needed. void finalize(); }; diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index a087c9a99ee..72e45c51c33 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -187,6 +187,10 @@ void Block::finalize() { TypeSeeker seeker(this, this->name); type = mergeTypes(seeker.types); + + if (isConcreteWasmType(type)) { + propagateConcreteTypeToChildren(this, type); + } } void If::finalize(WasmType type_) { @@ -209,8 +213,10 @@ void If::finalize() { type = ifTrue->type; } else if (isConcreteWasmType(ifTrue->type) && ifFalse->type == unreachable) { type = ifTrue->type; + propagateConcreteTypeToChildren(this, type); } else if (isConcreteWasmType(ifFalse->type) && ifTrue->type == unreachable) { type = ifFalse->type; + propagateConcreteTypeToChildren(this, type); } else { type = none; } @@ -233,6 +239,10 @@ void Loop::finalize() { // if already set to a concrete value, keep it if (isConcreteWasmType(type)) return; type = body->type; + + if (isConcreteWasmType(type)) { + propagateConcreteTypeToChildren(this, type); + } } } // namespace wasm From bf28b72b26eb4ffb3b58a0ae27939560fcd8862e Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Sun, 5 Feb 2017 20:10:45 -0800 Subject: [PATCH 06/17] fix up finalize and dropping in asm2wasm, in particular in switches --- src/asm2wasm.h | 32 +++++++++---------- test/wasm-only.asm.js | 18 +++++++++++ test/wasm-only.fromasm | 30 ++++++++++++++++++ test/wasm-only.fromasm.imprecise | 30 ++++++++++++++++++ test/wasm-only.fromasm.imprecise.no-opts | 39 ++++++++++++++++++++++++ test/wasm-only.fromasm.no-opts | 39 ++++++++++++++++++++++++ 6 files changed, 172 insertions(+), 16 deletions(-) diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 0fd1d4c7878..a64fdda4b9d 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1833,7 +1833,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { block = allocator.alloc(); block->name = name; block->list.push_back(ret); - block->finalize(); + block->finalize(none); ret = block; } } @@ -1877,7 +1877,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { auto body = allocator.alloc(); body->list.push_back(condition); body->list.push_back(process(ast[2])); - body->finalize(); + body->finalize(none); ret->body = body; } // loops do not automatically loop, add a branch back @@ -1885,7 +1885,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { auto continuer = allocator.alloc(); continuer->name = ret->name; block->list.push_back(continuer); - block->finalize(); + block->finalize(none); ret->body = builder.dropIfConcretelyTyped(block); ret->finalize(); continueStack.pop_back(); @@ -1922,13 +1922,13 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { block->list.push_back(builder.makeNop()); // ensure a nop at the end, so the block has guaranteed none type and no values fall through } block->name = stop; - block->finalize(); + block->finalize(none); return block; } else { auto loop = allocator.alloc(); loop->body = child; loop->name = more; - loop->finalize(); + loop->finalize(none); return builder.blockifyWithName(loop, stop); } } @@ -1958,7 +1958,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { continuer->condition = process(ast[1]); Block *block = builder.blockifyWithName(loop->body, out, continuer); loop->body = block; - loop->finalize(); + loop->finalize(none); return loop; } else if (what == FOR) { Ref finit = ast[1], @@ -1990,7 +1990,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { body->list.push_back(condition); body->list.push_back(process(fbody)); body->list.push_back(process(finc)); - body->finalize(); + body->finalize(none); ret->body = builder.dropIfConcretelyTyped(body); // loops do not automatically loop, add a branch back auto continuer = allocator.alloc(); @@ -2006,7 +2006,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { // add an outer block for the init as well outer->list.push_back(process(finit)); outer->list.push_back(ret); - outer->finalize(); + outer->finalize(none); return outer; } else if (what == LABEL) { assert(parentLabel.isNull()); @@ -2142,7 +2142,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } top->list.push_back(br); - top->finalize(); + top->finalize(none); for (unsigned i = 0; i < cases->size(); i++) { Ref curr = cases[i]; @@ -2166,9 +2166,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } auto next = allocator.alloc(); top->name = name; - next->list.push_back(top); - next->list.push_back(case_); - next->finalize(); + next->list.push_back(builder.dropIfConcretelyTyped(top)); + next->list.push_back(builder.dropIfConcretelyTyped(case_)); + next->finalize(none); top = next; nameMapper.popLabelName(name); } @@ -2215,9 +2215,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } auto next = allocator.alloc(); top->name = name; - next->list.push_back(top); - next->list.push_back(case_); - next->finalize(); + next->list.push_back(builder.dropIfConcretelyTyped(top)); + next->list.push_back(builder.dropIfConcretelyTyped(case_)); + next->finalize(none); top = next; nameMapper.popLabelName(name); } @@ -2233,7 +2233,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { first->ifFalse = builder.makeBreak(br->default_); brHolder->list.push_back(chain); - brHolder->finalize(); + brHolder->finalize(none); } breakStack.pop_back(); diff --git a/test/wasm-only.asm.js b/test/wasm-only.asm.js index 14159fdf2e5..fbdb727d851 100644 --- a/test/wasm-only.asm.js +++ b/test/wasm-only.asm.js @@ -327,6 +327,23 @@ function asm(global, env, buffer) { return; } + function vii(x, y) { x = x | 0; y = y | 0; return; } + + function lua_switch($L) { + $L = $L|0; + var $call = 0; + $call = (_pthread_cond_wait($L,2)|0); + switch ($call|0) { + case 0: { + break; + } + default: { + (_pthread_cond_wait($L,11217)|0); + } + } + return 1; + } + function keepAlive() { loads(); stores(); @@ -342,6 +359,7 @@ function asm(global, env, buffer) { unreachable_leftovers(0, 0, 0); propagateFallthrough() | 0; __ZNSt3__211__call_onceERVmPvPFvS2_E(0, 0, 0); + lua_switch(0) | 0; } function __emscripten_dceable_type_decls() { // dce-able, but this defines the type of fabsf which has no other use diff --git a/test/wasm-only.fromasm b/test/wasm-only.fromasm index 4cb68e750f1..9c7771a643e 100644 --- a/test/wasm-only.fromasm +++ b/test/wasm-only.fromasm @@ -409,6 +409,31 @@ ) ) ) + (func $lua_switch (param $0 i32) (result i32) + (block $switch + (block $switch-default + (block $switch-case + (br_table $switch-case $switch-default + (i32.sub + (call $_pthread_cond_wait + (get_local $0) + (i32.const 2) + ) + (i32.const 0) + ) + ) + ) + (br $switch) + ) + (drop + (call $_pthread_cond_wait + (get_local $0) + (i32.const 11217) + ) + ) + ) + (i32.const 1) + ) (func $keepAlive (call $loads) (call $stores) @@ -462,6 +487,11 @@ (i32.const 0) (i32.const 0) ) + (drop + (call $lua_switch + (i32.const 0) + ) + ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.imprecise b/test/wasm-only.fromasm.imprecise index dc2e8996c16..2a8281991ed 100644 --- a/test/wasm-only.fromasm.imprecise +++ b/test/wasm-only.fromasm.imprecise @@ -337,6 +337,31 @@ ) ) ) + (func $lua_switch (param $0 i32) (result i32) + (block $switch + (block $switch-default + (block $switch-case + (br_table $switch-case $switch-default + (i32.sub + (call $_pthread_cond_wait + (get_local $0) + (i32.const 2) + ) + (i32.const 0) + ) + ) + ) + (br $switch) + ) + (drop + (call $_pthread_cond_wait + (get_local $0) + (i32.const 11217) + ) + ) + ) + (i32.const 1) + ) (func $keepAlive (call $loads) (call $stores) @@ -390,6 +415,11 @@ (i32.const 0) (i32.const 0) ) + (drop + (call $lua_switch + (i32.const 0) + ) + ) ) (func $legalstub$illegalParam (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (call $illegalParam diff --git a/test/wasm-only.fromasm.imprecise.no-opts b/test/wasm-only.fromasm.imprecise.no-opts index 8e56c7066e4..de143e5841e 100644 --- a/test/wasm-only.fromasm.imprecise.no-opts +++ b/test/wasm-only.fromasm.imprecise.no-opts @@ -982,6 +982,40 @@ ) (return) ) + (func $vii (param $x i32) (param $y i32) + (return) + ) + (func $lua_switch (param $$L i32) (result i32) + (local $$call i32) + (set_local $$call + (call $_pthread_cond_wait + (get_local $$L) + (i32.const 2) + ) + ) + (block $switch + (block $switch-default + (block $switch-case + (br_table $switch-case $switch-default + (i32.sub + (get_local $$call) + (i32.const 0) + ) + ) + ) + (br $switch) + ) + (drop + (call $_pthread_cond_wait + (get_local $$L) + (i32.const 11217) + ) + ) + ) + (return + (i32.const 1) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -1035,6 +1069,11 @@ (i32.const 0) (i32.const 0) ) + (drop + (call $lua_switch + (i32.const 0) + ) + ) ) (func $__emscripten_dceable_type_decls (drop diff --git a/test/wasm-only.fromasm.no-opts b/test/wasm-only.fromasm.no-opts index 5aceaf34dc0..fe713820db9 100644 --- a/test/wasm-only.fromasm.no-opts +++ b/test/wasm-only.fromasm.no-opts @@ -1030,6 +1030,40 @@ ) (return) ) + (func $vii (param $x i32) (param $y i32) + (return) + ) + (func $lua_switch (param $$L i32) (result i32) + (local $$call i32) + (set_local $$call + (call $_pthread_cond_wait + (get_local $$L) + (i32.const 2) + ) + ) + (block $switch + (block $switch-default + (block $switch-case + (br_table $switch-case $switch-default + (i32.sub + (get_local $$call) + (i32.const 0) + ) + ) + ) + (br $switch) + ) + (drop + (call $_pthread_cond_wait + (get_local $$L) + (i32.const 11217) + ) + ) + ) + (return + (i32.const 1) + ) + ) (func $keepAlive (call $loads) (call $stores) @@ -1083,6 +1117,11 @@ (i32.const 0) (i32.const 0) ) + (drop + (call $lua_switch + (i32.const 0) + ) + ) ) (func $__emscripten_dceable_type_decls (drop From cdbc8d31ceb3abd7849e341e613dd310387cfbc7 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Sun, 5 Feb 2017 21:55:54 -0800 Subject: [PATCH 07/17] comment --- src/asm2wasm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/asm2wasm.h b/src/asm2wasm.h index a64fdda4b9d..db2745ff730 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -691,7 +691,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { passRunner.setValidateGlobally(false); } // run autodrop first, before optimizations - passRunner.add(); + passRunner.add(); // TODO: we can likely remove this, and speed up the build a little // optimize relooper label variable usage at the wasm level, where it is easy passRunner.add("relooper-jump-threading"); }, debug, false /* do not validate globally yet */); From ffc9fa11a235ef1165e629f18246b9b88f3b006a Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 11:39:37 -0800 Subject: [PATCH 08/17] validate the fallthrough of a function, so that if the function returns, the fallthrough must be typed that way (unreachable is not acceptable any more). this requires changing the binaryen C API to allow forcing the type of a block --- src/binaryen-c.cpp | 6 +++--- src/binaryen-c.h | 4 ++-- src/s2wasm.h | 2 +- src/wasm-validator.h | 8 +++----- src/wasm/wasm-s-parser.cpp | 7 +++++++ test/example/c-api-kitchen-sink.c | 11 +++++----- test/example/c-api-kitchen-sink.txt | 14 ++++++------- test/example/c-api-kitchen-sink.txt.txt | 2 +- test/example/c-api-unused-mem.cpp | 6 +++--- test/example/relooper-fuzz.c | 22 ++++++++++---------- test/example/relooper-fuzz1.c | 24 +++++++++++----------- test/passes/inlining.txt | 6 ++++-- test/passes/remove-unused-names_vacuum.txt | 4 +++- 13 files changed, 63 insertions(+), 53 deletions(-) diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index c618f9d1448..b76234ed824 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -299,13 +299,13 @@ BinaryenOp BinaryenCurrentMemory(void) { return CurrentMemory; } BinaryenOp BinaryenGrowMemory(void) { return GrowMemory; } BinaryenOp BinaryenHasFeature(void) { return HasFeature; } -BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module, const char* name, BinaryenExpressionRef* children, BinaryenIndex numChildren) { +BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module, const char* name, BinaryenExpressionRef* children, BinaryenIndex numChildren, BinaryenType resultType) { auto* ret = ((Module*)module)->allocator.alloc(); if (name) ret->name = name; for (BinaryenIndex i = 0; i < numChildren; i++) { ret->list.push_back((Expression*)children[i]); } - ret->finalize(); + ret->finalize(WasmType(resultType)); if (tracing) { std::cout << " {\n"; @@ -319,7 +319,7 @@ BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module, const char* name, auto id = noteExpression(ret); std::cout << " expressions[" << id << "] = BinaryenBlock(the_module, "; traceNameOrNULL(name); - std::cout << ", children, " << numChildren << ");\n"; + std::cout << ", children, " << numChildren << ", " << resultType << ");\n"; std::cout << " }\n"; } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 9ecb3f40936..26503548d2d 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -261,8 +261,8 @@ BinaryenOp BinaryenHasFeature(void); typedef void* BinaryenExpressionRef; -// Block: name can be NULL -BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module, const char* name, BinaryenExpressionRef* children, BinaryenIndex numChildren); +// Block: name can be NULL. type must be explicitly provided, per the wasm type rules +BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module, const char* name, BinaryenExpressionRef* children, BinaryenIndex numChildren, BinaryenType resultType); // If: ifFalse can be NULL BinaryenExpressionRef BinaryenIf(BinaryenModuleRef module, BinaryenExpressionRef condition, BinaryenExpressionRef ifTrue, BinaryenExpressionRef ifFalse); BinaryenExpressionRef BinaryenLoop(BinaryenModuleRef module, const char* in, BinaryenExpressionRef body); diff --git a/src/s2wasm.h b/src/s2wasm.h index faa31ae922d..de1bf1b81de 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -1283,7 +1283,7 @@ class S2WasmBuilder { bstack.pop_back(); // remove the base block for the function body assert(bstack.empty()); assert(estack.empty()); - func->body->dynCast()->finalize(); + func->body->dynCast()->finalize(func->result); wasm->addFunction(func); } diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 80f61595384..65a4ddf9f1c 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -429,15 +429,13 @@ struct WasmValidator : public PostWalker> } void visitFunction(Function *curr) { - // if function has no result, it is ignored - // if body is unreachable, it might be e.g. a return - if (curr->body->type != unreachable) { + if (curr->result != none) { shouldBeEqual(curr->result, curr->body->type, curr->body, "function body type must match, if function returns"); - } - if (curr->result != none) { // TODO: over previous too? if (returnType != unreachable) { shouldBeEqual(curr->result, returnType, curr->body, "function result must match, if function returns"); } + } else { + shouldBeTrue(!isConcreteWasmType(curr->body->type), curr->body, "if function does not return, body cannot be concretely typed"); } returnType = unreachable; labelNames.clear(); diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 3fcb85c6b9e..d8450cd8bd0 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -556,6 +556,13 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { body = allocator.alloc(); } if (currFunction->result != result) throw ParseException("bad func declaration", s.line, s.col); + // if the function returns, the fallthrough must have the right type + if (currFunction->result != none && body->type != currFunction->result) { + auto* block = allocator.alloc(); + block->list.push_back(body); + block->finalize(currFunction->result); + body = block; + } currFunction->body = body; currFunction->type = type; wasm.addFunction(currFunction.release()); diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index 77e7f0b05bf..1ede638ec46 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -182,7 +182,7 @@ void test_core() { makeBinary(module, BinaryenGtFloat64(), 4), makeBinary(module, BinaryenGeFloat32(), 3), // All the rest - BinaryenBlock(module, NULL, NULL, 0), // block with no name + BinaryenBlock(module, NULL, NULL, 0, BinaryenNone()), // block with no name BinaryenIf(module, temp1, temp2, temp3), BinaryenIf(module, temp4, temp5, NULL), BinaryenLoop(module, "in", makeInt32(module, 0)), @@ -224,11 +224,11 @@ void test_core() { BinaryenExpressionPrint(valueList[3]); // test printing a standalone expression // Make the main body of the function. and one block with a return value, one without - BinaryenExpressionRef value = BinaryenBlock(module, "the-value", valueList, sizeof(valueList) / sizeof(BinaryenExpressionRef)); + BinaryenExpressionRef value = BinaryenBlock(module, "the-value", valueList, sizeof(valueList) / sizeof(BinaryenExpressionRef), BinaryenInt32()); BinaryenExpressionRef droppedValue = BinaryenDrop(module, value); - BinaryenExpressionRef nothing = BinaryenBlock(module, "the-nothing", &droppedValue, 1); + BinaryenExpressionRef nothing = BinaryenBlock(module, "the-nothing", &droppedValue, 1, BinaryenNone()); BinaryenExpressionRef bodyList[] = { nothing, makeInt32(module, 42) }; - BinaryenExpressionRef body = BinaryenBlock(module, "the-body", bodyList, 2); + BinaryenExpressionRef body = BinaryenBlock(module, "the-body", bodyList, 2, BinaryenInt32()); // Create the function BinaryenType localTypes[] = { BinaryenInt32() }; @@ -456,8 +456,9 @@ void test_relooper() { { // return in a block RelooperRef relooper = RelooperCreate(); + BinaryenExpressionRef listList[] = { makeCallCheck(module, 42), BinaryenReturn(module, makeInt32(module, 1337)) }; - BinaryenExpressionRef list = BinaryenBlock(module, "the-list", listList, 2); + BinaryenExpressionRef list = BinaryenBlock(module, "the-list", listList, 2, BinaryenInt32()); RelooperBlockRef block = RelooperAddBlock(relooper, list); BinaryenExpressionRef body = RelooperRenderAndDispose(relooper, block, 0, module); BinaryenFunctionRef sinker = BinaryenAddFunction(module, "return", i, localTypes, 1, body); diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 760ae2571ce..05011f354e7 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -1011,7 +1011,7 @@ raw: ) (func $return (type $i) (result i32) (local $0 i32) - (block $the-list + (block $the-list i32 (call $check (i32.const 42) ) @@ -1278,7 +1278,7 @@ int main() { expressions[196] = BinaryenBinary(the_module, 62, expressions[195], expressions[194]); { BinaryenExpressionRef children[] = { 0 }; - expressions[197] = BinaryenBlock(the_module, NULL, children, 0); + expressions[197] = BinaryenBlock(the_module, NULL, children, 0, 0); } expressions[198] = BinaryenIf(the_module, expressions[13], expressions[14], expressions[15]); expressions[199] = BinaryenIf(the_module, expressions[16], expressions[17], expressions[0]); @@ -1346,17 +1346,17 @@ int main() { ) { BinaryenExpressionRef children[] = { expressions[30], expressions[32], expressions[34], expressions[36], expressions[38], expressions[40], expressions[42], expressions[44], expressions[46], expressions[48], expressions[50], expressions[52], expressions[54], expressions[56], expressions[58], expressions[60], expressions[62], expressions[64], expressions[66], expressions[68], expressions[70], expressions[72], expressions[74], expressions[76], expressions[78], expressions[80], expressions[82], expressions[84], expressions[86], expressions[88], expressions[90], expressions[92], expressions[94], expressions[96], expressions[98], expressions[100], expressions[103], expressions[106], expressions[109], expressions[112], expressions[115], expressions[118], expressions[121], expressions[124], expressions[127], expressions[130], expressions[133], expressions[136], expressions[139], expressions[142], expressions[145], expressions[148], expressions[151], expressions[154], expressions[157], expressions[160], expressions[163], expressions[166], expressions[169], expressions[172], expressions[175], expressions[178], expressions[181], expressions[184], expressions[187], expressions[190], expressions[193], expressions[196], expressions[197], expressions[198], expressions[199], expressions[201], expressions[203], expressions[204], expressions[206], expressions[208], expressions[209], expressions[210], expressions[212], expressions[214], expressions[217], expressions[220], expressions[222], expressions[224], expressions[227], expressions[229], expressions[231], expressions[233], expressions[235], expressions[236], expressions[237], expressions[238], expressions[240], expressions[241], expressions[242] }; - expressions[243] = BinaryenBlock(the_module, "the-value", children, 95); + expressions[243] = BinaryenBlock(the_module, "the-value", children, 95, 1); } expressions[244] = BinaryenDrop(the_module, expressions[243]); { BinaryenExpressionRef children[] = { expressions[244] }; - expressions[245] = BinaryenBlock(the_module, "the-nothing", children, 1); + expressions[245] = BinaryenBlock(the_module, "the-nothing", children, 1, 0); } expressions[246] = BinaryenConst(the_module, BinaryenLiteralInt32(42)); { BinaryenExpressionRef children[] = { expressions[245], expressions[246] }; - expressions[247] = BinaryenBlock(the_module, "the-body", children, 2); + expressions[247] = BinaryenBlock(the_module, "the-body", children, 2, 1); } { BinaryenType varTypes[] = { 1 }; @@ -2376,7 +2376,7 @@ int main() { expressions[139] = BinaryenReturn(the_module, expressions[138]); { BinaryenExpressionRef children[] = { expressions[137], expressions[139] }; - expressions[140] = BinaryenBlock(the_module, "the-list", children, 2); + expressions[140] = BinaryenBlock(the_module, "the-list", children, 2, 1); } relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[140]); expressions[141] = RelooperRenderAndDispose(the_relooper, relooperBlocks[0], 0, the_module); @@ -2862,7 +2862,7 @@ raw: ) (func $return (type $i) (result i32) (local $0 i32) - (block $the-list + (block $the-list i32 (call $check (i32.const 42) ) diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt index 934c7e62051..a624a71fa26 100644 --- a/test/example/c-api-kitchen-sink.txt.txt +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -1005,7 +1005,7 @@ ) (func $return (type $i) (result i32) (local $0 i32) - (block $the-list + (block $the-list i32 (call $check (i32.const 42) ) diff --git a/test/example/c-api-unused-mem.cpp b/test/example/c-api-unused-mem.cpp index 69bee351ffb..2890ad2f2ab 100644 --- a/test/example/c-api-unused-mem.cpp +++ b/test/example/c-api-unused-mem.cpp @@ -22,7 +22,7 @@ int main() { the_relooper = RelooperCreate(); { BinaryenExpressionRef children[] = { 0 }; - expressions[1] = BinaryenBlock(the_module, "bb0", children, 0); + expressions[1] = BinaryenBlock(the_module, "bb0", children, 0, BinaryenNone()); } relooperBlocks[0] = RelooperAddBlock(the_relooper, expressions[1]); expressions[2] = BinaryenGetLocal(the_module, 0, 1); @@ -31,7 +31,7 @@ int main() { expressions[5] = BinaryenReturn(the_module, expressions[0]); { BinaryenExpressionRef children[] = { expressions[4], expressions[5] }; - expressions[6] = BinaryenBlock(the_module, "bb1", children, 2); + expressions[6] = BinaryenBlock(the_module, "bb1", children, 2, BinaryenNone()); } relooperBlocks[1] = RelooperAddBlock(the_relooper, expressions[6]); RelooperAddBranch(relooperBlocks[0], relooperBlocks[1], expressions[0], expressions[0]); @@ -69,7 +69,7 @@ int main() { } { BinaryenExpressionRef children[] = { expressions[13], expressions[14] }; - expressions[15] = BinaryenBlock(the_module, NULL, children, 2); + expressions[15] = BinaryenBlock(the_module, NULL, children, 2, BinaryenNone()); } BinaryenAddExport(the_module, "__wasm_start", "rust_entry"); { diff --git a/test/example/relooper-fuzz.c b/test/example/relooper-fuzz.c index 9fd11096fc9..83552b6b965 100644 --- a/test/example/relooper-fuzz.c +++ b/test/example/relooper-fuzz.c @@ -56,7 +56,7 @@ int main() { BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), BinaryenConst(module, BinaryenLiteralInt32(4))) ); BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger, returner }; - BinaryenExpressionRef checkBody = BinaryenBlock(module, NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef)); + BinaryenExpressionRef checkBody = BinaryenBlock(module, NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef), BinaryenInt32()); BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i", BinaryenInt32(), NULL, 0); BinaryenAddFunction(module, "check", i, NULL, 0, checkBody); @@ -72,7 +72,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b1; @@ -82,7 +82,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b2; @@ -92,7 +92,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b3; @@ -102,7 +102,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b4; @@ -112,7 +112,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b5; @@ -122,7 +122,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b5 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b5 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b6; @@ -132,7 +132,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b6 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b6 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b7; @@ -142,7 +142,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperBlockRef b8; @@ -152,7 +152,7 @@ int main() { BinaryenCallImport(module, "print", args, 1, BinaryenNone()), BinaryenSetLocal(module, 0, BinaryenCall(module, "check", NULL, 0, BinaryenInt32())) }; - b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } RelooperAddBranch(b0, b5, BinaryenBinary(module, @@ -242,7 +242,7 @@ int main() { } } full[numDecisions] = body; - BinaryenExpressionRef all = BinaryenBlock(module, NULL, full, numDecisions + 1); + BinaryenExpressionRef all = BinaryenBlock(module, NULL, full, numDecisions + 1, BinaryenNone()); BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v", BinaryenNone(), NULL, 0); BinaryenType localTypes[] = { BinaryenInt32(), BinaryenInt32() }; // state, free-for-label diff --git a/test/example/relooper-fuzz1.c b/test/example/relooper-fuzz1.c index cca61e4f451..aebfbdb6135 100644 --- a/test/example/relooper-fuzz1.c +++ b/test/example/relooper-fuzz1.c @@ -64,7 +64,7 @@ int main() { BinaryenExpressionRef checkBodyList[] = { halter, incer, debugger, returner }; BinaryenExpressionRef checkBody = BinaryenBlock(module, - NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef) + NULL, checkBodyList, sizeof(checkBodyList) / sizeof(BinaryenExpressionRef), BinaryenInt32() ); BinaryenFunctionTypeRef i = BinaryenAddFunctionType(module, "i", BinaryenInt32(), @@ -87,7 +87,7 @@ int main() { BinaryenInt32())) }; - b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b0 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -102,7 +102,7 @@ int main() { BinaryenInt32())) }; - b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b1 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -117,7 +117,7 @@ int main() { BinaryenInt32())) }; - b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b2 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -132,7 +132,7 @@ int main() { BinaryenInt32())) }; - b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b3 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -147,7 +147,7 @@ int main() { BinaryenInt32())) }; - b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b4 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -162,7 +162,7 @@ int main() { BinaryenInt32())) }; - b5 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b5 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -177,7 +177,7 @@ int main() { BinaryenInt32())) }; - b6 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b6 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -192,7 +192,7 @@ int main() { BinaryenInt32())) }; - b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b7 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -207,7 +207,7 @@ int main() { BinaryenInt32())) }; - b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b8 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -222,7 +222,7 @@ int main() { BinaryenInt32())) }; - b9 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2)); + b9 = RelooperAddBlock(relooper, BinaryenBlock(module, NULL, list, 2, BinaryenNone())); } @@ -296,7 +296,7 @@ int main() { } full[numDecisions] = body; BinaryenExpressionRef all = BinaryenBlock(module, NULL, full, - numDecisions + 1); + numDecisions + 1, BinaryenNone()); BinaryenFunctionTypeRef v = BinaryenAddFunctionType(module, "v", BinaryenNone(), diff --git a/test/passes/inlining.txt b/test/passes/inlining.txt index 51d7c234770..68440ef7f73 100644 --- a/test/passes/inlining.txt +++ b/test/passes/inlining.txt @@ -57,8 +57,10 @@ ) (drop (block $__inlined_func$return i32 - (br $__inlined_func$return - (i32.const 5) + (block i32 + (br $__inlined_func$return + (i32.const 5) + ) ) ) ) diff --git a/test/passes/remove-unused-names_vacuum.txt b/test/passes/remove-unused-names_vacuum.txt index 4da159f92c2..14ab4d4cca8 100644 --- a/test/passes/remove-unused-names_vacuum.txt +++ b/test/passes/remove-unused-names_vacuum.txt @@ -3,6 +3,8 @@ (memory $0 0) (func $return-i32-but-body-is-unreachable3 (type $0) (result i32) (local $label i32) - (unreachable) + (loop $while-in$1 i32 + (br $while-in$1) + ) ) ) From b019f536c08d9d3e6d7940af018018a093aedb7f Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 11:43:23 -0800 Subject: [PATCH 09/17] improve a test --- test/passes/remove-unused-names_vacuum.txt | 5 +++++ test/passes/remove-unused-names_vacuum.wast | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/test/passes/remove-unused-names_vacuum.txt b/test/passes/remove-unused-names_vacuum.txt index 14ab4d4cca8..b1fd9ad2cc5 100644 --- a/test/passes/remove-unused-names_vacuum.txt +++ b/test/passes/remove-unused-names_vacuum.txt @@ -7,4 +7,9 @@ (br $while-in$1) ) ) + (func $return-i32-but-body-is-unreachable4 (type $0) (result i32) + (local $label i32) + (unreachable) + (i32.const 0) + ) ) diff --git a/test/passes/remove-unused-names_vacuum.wast b/test/passes/remove-unused-names_vacuum.wast index 04b08c332e8..8b73960d820 100644 --- a/test/passes/remove-unused-names_vacuum.wast +++ b/test/passes/remove-unused-names_vacuum.wast @@ -1,11 +1,20 @@ (module (func $return-i32-but-body-is-unreachable3 (result i32) + (local $label i32) + (block i32 ;; without a name here, vaccum had a too-eager bug + (loop $while-in$1 i32 + (br $while-in$1) + ) + ) + ) + (func $return-i32-but-body-is-unreachable4 (result i32) (local $label i32) (block ;; without a name here, vaccum had a too-eager bug (loop $while-in$1 (br $while-in$1) ) ) + (i32.const 0) ) ) From a2cbb0bda13f2eacefa5689549b7f090aaa40f91 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 12:19:48 -0800 Subject: [PATCH 10/17] fix validation rule - unreachable is ok for the function fallthrough, it is just on control flow structures that it isn't --- src/wasm-validator.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 65a4ddf9f1c..c4e769125e0 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -430,7 +430,11 @@ struct WasmValidator : public PostWalker> void visitFunction(Function *curr) { if (curr->result != none) { - shouldBeEqual(curr->result, curr->body->type, curr->body, "function body type must match, if function returns"); + // if the body is concretely typed, it must be correct. + // if it is a control flow structure, then it must always be correct, even unreachable is bad + if (curr->body->type != unreachable || ExpressionAnalyzer::isControlFlowStructure(curr->body)) { + shouldBeEqual(curr->result, curr->body->type, curr->body, "function body type must match, if function returns"); + } if (returnType != unreachable) { shouldBeEqual(curr->result, returnType, curr->body, "function result must match, if function returns"); } From 494d1ad969aa8ad962c1a778d87bf3c2631cce8c Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 15:21:21 -0800 Subject: [PATCH 11/17] add empty() on ArenaVector --- src/mixed_arena.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mixed_arena.h b/src/mixed_arena.h index 52e47fbde4d..eeec46d2ded 100644 --- a/src/mixed_arena.h +++ b/src/mixed_arena.h @@ -171,6 +171,10 @@ class ArenaVectorBase { return usedElements; } + bool empty() const { + return size() == 0; + } + void resize(size_t size) { if (size > allocatedElements) { reallocate(size); From 1cf5aa085bdc9172d4c3ece3fe91cbc4219cd208 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 15:21:39 -0800 Subject: [PATCH 12/17] s2wasm should not emit empty blocks with types, as wasm disallows it --- src/s2wasm.h | 4 ++++ test/dot_s/unreachable_blocks.wast | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/s2wasm.h b/src/s2wasm.h index de1bf1b81de..49e2566a532 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -1175,6 +1175,10 @@ class S2WasmBuilder { bstack.push_back(curr); } else if (match("end_block")) { auto* block = bstack.back()->cast(); + // wasm disallows an empty block with a type + if (isConcreteWasmType(block->type) && block->list.empty()) { + block->list.push_back(builder.makeUnreachable()); + } block->finalize(block->type); bstack.pop_back(); } else if (peek(".LBB")) { diff --git a/test/dot_s/unreachable_blocks.wast b/test/dot_s/unreachable_blocks.wast index 3c7b0d158eb..8e3e3a7388a 100644 --- a/test/dot_s/unreachable_blocks.wast +++ b/test/dot_s/unreachable_blocks.wast @@ -15,6 +15,7 @@ (i32.const 2) ) (block $label$0 i32 + (unreachable) ) ) (func $unreachable_block_i64 (result i64) @@ -22,6 +23,7 @@ (i64.const 3) ) (block $label$0 i64 + (unreachable) ) ) (func $unreachable_block_f32 (result f32) @@ -29,6 +31,7 @@ (f32.const 4.5) ) (block $label$0 f32 + (unreachable) ) ) (func $unreachable_block_f64 (result f64) @@ -36,6 +39,7 @@ (f64.const 5.5) ) (block $label$0 f64 + (unreachable) ) ) (func $unreachable_loop_void From acac2ca8ad6bdffad2c4dc51c94a5fb29404e412 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 15:22:05 -0800 Subject: [PATCH 13/17] improve validation of blocks --- src/wasm-validator.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wasm-validator.h b/src/wasm-validator.h index c4e769125e0..d018f9cd519 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -134,9 +134,15 @@ struct WasmValidator : public PostWalker> shouldBeFalse(isConcreteWasmType(last->type), curr, "block with no value cannot have a last element with a value"); } else { // if we return, then control flow children must have that type, not even unreachable - if (ExpressionAnalyzer::isControlFlowStructure(last)) shouldBeEqual(last->type, curr->type, curr, "block fallthrough must have right type"); + // non-control flow lasts can be unreachable, but if they are not, must be equal + if (last->type != unreachable || ExpressionAnalyzer::isControlFlowStructure(last)) { + shouldBeEqual(last->type, curr->type, curr, "block fallthrough must have right type"); + } } } + if (isConcreteWasmType(curr->type)) { + shouldBeTrue(curr->list.size() > 0, curr, "a block with a type cannot be empty"); + } } static void visitPreLoop(WasmValidator* self, Expression** currp) { From 8bdfcf0a253917da72df6e32b927c7e991a0c9f6 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 19:47:42 -0800 Subject: [PATCH 14/17] improve pass debug tools --- src/passes/pass.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 32b596eef1a..4540be170c0 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -138,7 +138,8 @@ void PassRunner::addDefaultGlobalOptimizationPasses() { } void PassRunner::run() { - if (options.debug) { + static int passDebug = getenv("BINARYEN_PASS_DEBUG") ? atoi(getenv("BINARYEN_PASS_DEBUG")) : 0; + if (options.debug || passDebug) { // for debug logging purposes, run each pass in full before running the other auto totalTime = std::chrono::duration(0); size_t padding = 0; @@ -146,11 +147,10 @@ void PassRunner::run() { for (auto pass : passes) { padding = std::max(padding, pass->name.size()); } - bool passDebug = getenv("BINARYEN_PASS_DEBUG") && getenv("BINARYEN_PASS_DEBUG")[0] != '0'; for (auto* pass : passes) { // ignoring the time, save a printout of the module before, in case this pass breaks it, so we can print the before and after std::stringstream moduleBefore; - if (passDebug) { + if (passDebug >= 2) { WasmPrinter::printModule(wasm, moduleBefore); } // prepare to run @@ -174,10 +174,10 @@ void PassRunner::run() { // validate, ignoring the time std::cerr << "[PassRunner] (validating)\n"; if (!WasmValidator().validate(*wasm, false, options.validateGlobally)) { - if (passDebug) { + if (passDebug >= 2) { std::cerr << "Last pass (" << pass->name << ") broke validation. Here is the module before: \n" << moduleBefore.str() << "\n"; } else { - std::cerr << "Last pass (" << pass->name << ") broke validation. Run with BINARYEN_PASS_DEBUG=1 in the env to see the earlier state\n"; + std::cerr << "Last pass (" << pass->name << ") broke validation. Run with BINARYEN_PASS_DEBUG=2 in the env to see the earlier state\n"; } abort(); } From 89b118355fa75a13e16419f522117428fa732995 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 20:05:21 -0800 Subject: [PATCH 15/17] finalize in remove-unused-brs when we conditionalize a br - we may have put an if at the end of a block, and if the block if is typed, then so now must be the if (it must have both arms of unreachable type, so this is ok to do) --- src/passes/RemoveUnusedBrs.cpp | 4 ++++ test/passes/remove-unused-brs.txt | 18 ++++++++++++++++++ test/passes/remove-unused-brs.wast | 16 ++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 69a7c4ff117..a3c9a76ffd9 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -219,6 +219,7 @@ struct RemoveUnusedBrs : public WalkerPassifTrue)) { iff->ifFalse = builder.stealSlice(block, i + 1, list.size()); + block->finalize(block->type); return true; } } else { @@ -227,9 +228,11 @@ struct RemoveUnusedBrs : public WalkerPasstype)); // can't be, since in the middle of a block if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifTrue)) { iff->ifFalse = builder.blockifyMerge(iff->ifFalse, builder.stealSlice(block, i + 1, list.size())); + block->finalize(block->type); return true; } else if (ExpressionAnalyzer::obviouslyDoesNotFlowOut(iff->ifFalse)) { iff->ifTrue = builder.blockifyMerge(iff->ifTrue, builder.stealSlice(block, i + 1, list.size())); + block->finalize(block->type); return true; } } @@ -256,6 +259,7 @@ struct RemoveUnusedBrs : public WalkerPasscondition, builder.makeBreak(brIf->name), builder.stealSlice(block, i + 1, list.size())); + block->finalize(block->type); return true; } } diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt index b95ace90d6c..edfca2a5dee 100644 --- a/test/passes/remove-unused-brs.txt +++ b/test/passes/remove-unused-brs.txt @@ -937,4 +937,22 @@ ) ) ) + (func $loop-if (type $2) (result i32) + (block $outer i32 + (loop $typed i32 + (if i32 + (i32.const 2) + (block $block i32 + (drop + (call $loop-if) + ) + (br $outer + (i32.const 0) + ) + ) + (br $typed) + ) + ) + ) + ) ) diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast index 8b0ad357bed..4bd100b904c 100644 --- a/test/passes/remove-unused-brs.wast +++ b/test/passes/remove-unused-brs.wast @@ -831,5 +831,21 @@ ) ) ) + (func $loop-if (result i32) + (block $outer i32 + (loop $typed i32 + ;; we can move the br after us into our if-else, but that then means we are the final + ;; element in the block, and so must be typed + (if + (i32.const 2) + (block + (drop (call $loop-if)) + (br $outer (i32.const 0)) + ) + ) + (br $typed) + ) + ) + ) ) From 3bc799d607ba4976f85a4aecf6cf89686161fb51 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 21:25:16 -0800 Subject: [PATCH 16/17] fix BINARYEN_PASS_DEBUG=2, we must not infinitely recurse the pass printer pass while debugging --- src/pass.h | 5 +++-- src/passes/pass.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pass.h b/src/pass.h index dc9159aa063..49d0627346e 100644 --- a/src/pass.h +++ b/src/pass.h @@ -238,8 +238,9 @@ class Printer : public Pass { std::ostream& o; public: - Printer() : o(std::cout) {} - Printer(std::ostream* o) : o(*o) {} + Printer(std::ostream* o = nullptr) : o(o ? *o : std::cout) { + name = "printer"; + } void run(PassRunner* runner, Module* module) override; }; diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 4540be170c0..7abe91ca212 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -139,7 +139,8 @@ void PassRunner::addDefaultGlobalOptimizationPasses() { void PassRunner::run() { static int passDebug = getenv("BINARYEN_PASS_DEBUG") ? atoi(getenv("BINARYEN_PASS_DEBUG")) : 0; - if (options.debug || passDebug) { + // debug the passes if relevant. be careful to not debug a single print pass, as that is how we print (we would infinitely recurse) + if ((options.debug || passDebug) && !(passes.size() == 1 && passes[0]->name == "printer")) { // for debug logging purposes, run each pass in full before running the other auto totalTime = std::chrono::duration(0); size_t padding = 0; From ac0fb4bc5c07003322b5b0857c68939a18bc7d48 Mon Sep 17 00:00:00 2001 From: "Alon Zakai (kripken)" Date: Mon, 6 Feb 2017 22:05:01 -0800 Subject: [PATCH 17/17] fix a corner case in merge-blocks --- src/passes/MergeBlocks.cpp | 5 +++++ .../vacuum_remove-unused-names_merge-blocks.txt | 12 ++++++++++++ .../vacuum_remove-unused-names_merge-blocks.wast | 16 ++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 test/passes/vacuum_remove-unused-names_merge-blocks.txt create mode 100644 test/passes/vacuum_remove-unused-names_merge-blocks.wast diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index eb992512d53..c3f030ff8c1 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -227,6 +227,11 @@ struct MergeBlocks : public WalkerPasslist.back() = curr; block->finalize(curr->type); // last block element was our input, and is now our output + if (block->type == unreachable && curr == getFunction()->body && getFunction()->result != none) { + // corner case: if the block isn't typed (e.g. ends in a return now), and is about to + // be placed as the function's fallthrough, then it must be typed if the function returns + block->finalize(getFunction()->result); + } replaceCurrent(block); return block; } else { diff --git a/test/passes/vacuum_remove-unused-names_merge-blocks.txt b/test/passes/vacuum_remove-unused-names_merge-blocks.txt new file mode 100644 index 00000000000..a351c443b4a --- /dev/null +++ b/test/passes/vacuum_remove-unused-names_merge-blocks.txt @@ -0,0 +1,12 @@ +(module + (type $0 (func (param i32) (result i32))) + (memory $0 0) + (func $return-block (type $0) (param $x i32) (result i32) + (set_local $x + (get_local $x) + ) + (return + (get_local $x) + ) + ) +) diff --git a/test/passes/vacuum_remove-unused-names_merge-blocks.wast b/test/passes/vacuum_remove-unused-names_merge-blocks.wast new file mode 100644 index 00000000000..0793091538d --- /dev/null +++ b/test/passes/vacuum_remove-unused-names_merge-blocks.wast @@ -0,0 +1,16 @@ +(module + ;; vacuum and remove-unused names leave us with a return at the top, and then + ;; merge-blocks wants to move the first line of the block into an outer block + ;; that then becomes the fallthrough of the function, so it must be properly typed! + ;; and here the new last element is a return, with unreachable type, bad for a block + ;; in that position + (func $return-block (param $x i32) (result i32) + (return + (block i32 + (set_local $x (get_local $x)) + (get_local $x) + ) + ) + ) +) +