diff options
author | Alon Zakai <alonzakai@gmail.com> | 2019-04-18 17:05:30 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-18 17:05:30 -0700 |
commit | a4baf2152d11c28964025759d2702fe7c48d321e (patch) | |
tree | a59d35b75c52029d870733553df0c3bbed3d63c7 | |
parent | 5becae69e29c876f3ba46d6746764e409bd7fd9b (diff) | |
download | binaryen-a4baf2152d11c28964025759d2702fe7c48d321e.tar.gz binaryen-a4baf2152d11c28964025759d2702fe7c48d321e.tar.bz2 binaryen-a4baf2152d11c28964025759d2702fe7c48d321e.zip |
wasm2js: handle unreachable select and global.set (#2029)
-rw-r--r-- | src/passes/I64ToI32Lowering.cpp | 21 | ||||
-rw-r--r-- | test/passes/flatten_i64-to-i32-lowering.txt | 102 | ||||
-rw-r--r-- | test/passes/flatten_i64-to-i32-lowering.wast | 34 | ||||
-rw-r--r-- | test/wasm2js/br.2asm.js | 4 | ||||
-rw-r--r-- | test/wasm2js/br_table.2asm.js | 4 | ||||
-rw-r--r-- | test/wasm2js/br_table_temp.2asm.js | 4 | ||||
-rw-r--r-- | test/wasm2js/i64-select.2asm.js | 12 | ||||
-rw-r--r-- | test/wasm2js/i64-select.wast | 21 | ||||
-rw-r--r-- | test/wasm2js/select.2asm.js | 4 |
9 files changed, 195 insertions, 11 deletions
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp index a1686d27d..33bb7229e 100644 --- a/src/passes/I64ToI32Lowering.cpp +++ b/src/passes/I64ToI32Lowering.cpp @@ -28,6 +28,7 @@ #include "support/name.h" #include "wasm-builder.h" #include "ir/flat.h" +#include "ir/iteration.h" #include "ir/memory-utils.h" #include "ir/module-utils.h" #include "ir/names.h" @@ -464,6 +465,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { } void visitSetGlobal(SetGlobal* curr) { + if (handleUnreachable(curr)) return; if (!originallyI64Globals.count(curr->name)) return; TempVar highBits = fetchOutParam(curr->value); auto* setHigh = builder->makeSetGlobal( @@ -1578,6 +1580,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> { } void visitSelect(Select* curr) { + if (handleUnreachable(curr)) return; if (!hasOutParam(curr->ifTrue)) { assert(!hasOutParam(curr->ifFalse)); return; @@ -1669,6 +1672,24 @@ private: highBitVars.erase(e); return ret; } + + // If e.g. a select is unreachable, then one arm may have an out param + // but not the other. In this case dce should really have been run + // before; handle it in a simple way here. + bool handleUnreachable(Expression* curr) { + if (curr->type != unreachable) return false; + std::vector<Expression*> children; + for (auto* child : ChildIterator(curr)) { + if (isConcreteType(child->type)) { + child = builder->makeDrop(child); + } + children.push_back(child); + } + auto* block = builder->makeBlock(children); + assert(block->type == unreachable); + replaceCurrent(block); + return true; + } }; Pass *createI64ToI32LoweringPass() { diff --git a/test/passes/flatten_i64-to-i32-lowering.txt b/test/passes/flatten_i64-to-i32-lowering.txt index 6863be7e8..7d9ff6835 100644 --- a/test/passes/flatten_i64-to-i32-lowering.txt +++ b/test/passes/flatten_i64-to-i32-lowering.txt @@ -78,6 +78,69 @@ ) ) ) + (func $unreachable-select-i64 (; 2 ;) (type $FUNCSIG$j) (result i32) + (local $i64toi32_i32$0 i32) + (unreachable) + (block + (drop + (block (result i32) + (local.set $i64toi32_i32$0 + (i32.const 0) + ) + (i32.const 1) + ) + ) + (unreachable) + (drop + (i32.const 2) + ) + ) + (unreachable) + ) + (func $unreachable-select-i64-b (; 3 ;) (type $FUNCSIG$j) (result i32) + (local $i64toi32_i32$0 i32) + (unreachable) + (block + (unreachable) + (drop + (block (result i32) + (local.set $i64toi32_i32$0 + (i32.const 0) + ) + (i32.const 3) + ) + ) + (drop + (i32.const 4) + ) + ) + (unreachable) + ) + (func $unreachable-select-i64-c (; 4 ;) (type $FUNCSIG$j) (result i32) + (local $i64toi32_i32$0 i32) + (local $i64toi32_i32$1 i32) + (unreachable) + (block + (drop + (block (result i32) + (local.set $i64toi32_i32$0 + (i32.const 0) + ) + (i32.const 5) + ) + ) + (drop + (block (result i32) + (local.set $i64toi32_i32$1 + (i32.const 0) + ) + (i32.const 6) + ) + ) + (unreachable) + ) + (unreachable) + ) ) (module (type $0 (func (param i32 i32))) @@ -88,6 +151,7 @@ (global $g$hi (mut i32) (global.get $f$hi)) (global $i64toi32_i32$HIGH_BITS (mut i32) (i32.const 0)) (export "exp" (func $1)) + (export "unreach" (func $2)) (func $call (; 0 ;) (type $0) (param $0 i32) (param $0$hi i32) (nop) ) @@ -136,4 +200,42 @@ ) (nop) ) + (func $2 (; 2 ;) (type $1) + (local $0 i32) + (local $0$hi i32) + (local $1 i32) + (local $1$hi i32) + (local $i64toi32_i32$0 i32) + (block $label$1 + (unreachable) + (unreachable) + ) + (block + (local.set $1 + (block (result i32) + (local.set $i64toi32_i32$0 + (local.get $0$hi) + ) + (local.get $0) + ) + ) + (local.set $1$hi + (local.get $i64toi32_i32$0) + ) + ) + (block + (global.set $f + (block (result i32) + (local.set $i64toi32_i32$0 + (local.get $1$hi) + ) + (local.get $1) + ) + ) + (global.set $f$hi + (local.get $i64toi32_i32$0) + ) + ) + (nop) + ) ) diff --git a/test/passes/flatten_i64-to-i32-lowering.wast b/test/passes/flatten_i64-to-i32-lowering.wast index def4f3a34..29323d376 100644 --- a/test/passes/flatten_i64-to-i32-lowering.wast +++ b/test/passes/flatten_i64-to-i32-lowering.wast @@ -1,8 +1,29 @@ (module - (import "env" "func" (func $import (result i64))) - (func $defined (result i64) - (i64.add (i64.const 1) (i64.const 2)) + (import "env" "func" (func $import (result i64))) + (func $defined (result i64) + (i64.add (i64.const 1) (i64.const 2)) + ) + (func $unreachable-select-i64 (result i64) + (select + (i64.const 1) + (unreachable) + (i32.const 2) + ) + ) + (func $unreachable-select-i64-b (result i64) + (select + (unreachable) + (i64.const 3) + (i32.const 4) + ) + ) + (func $unreachable-select-i64-c (result i64) + (select + (i64.const 5) + (i64.const 6) + (unreachable) ) + ) ) (module (global $f (mut i64) (i64.const 0x12345678ABCDEFAF)) @@ -12,4 +33,11 @@ (call $call (global.get $f)) (global.set $f (i64.const 0x1122334455667788)) ) + (func "unreach" + (global.set $f + (block $label$1 (result i64) + (unreachable) + ) + ) + ) ) diff --git a/test/wasm2js/br.2asm.js b/test/wasm2js/br.2asm.js index c30b7d2de..01f5d3941 100644 --- a/test/wasm2js/br.2asm.js +++ b/test/wasm2js/br.2asm.js @@ -262,7 +262,7 @@ function asmFunc(global, env, buffer) { function $27($0, $1_1) { $0 = $0 | 0; $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0; block : { $2_1 = 5; break block; @@ -273,7 +273,7 @@ function asmFunc(global, env, buffer) { function $28($0, $1_1) { $0 = $0 | 0; $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0; block : { $2_1 = $0; $3_1 = 6; diff --git a/test/wasm2js/br_table.2asm.js b/test/wasm2js/br_table.2asm.js index 2a33ce688..7ff5e4c4d 100644 --- a/test/wasm2js/br_table.2asm.js +++ b/test/wasm2js/br_table.2asm.js @@ -49727,7 +49727,7 @@ function asmFunc(global, env, buffer) { function $34($0, $1_1) { $0 = $0 | 0; $1_1 = $1_1 | 0; - var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0; + var $3_1 = 0, $4_1 = 0, $5_1 = 0; block : { $3_1 = 5; switch (0 | 0) { @@ -49741,7 +49741,7 @@ function asmFunc(global, env, buffer) { function $35($0, $1_1) { $0 = $0 | 0; $1_1 = $1_1 | 0; - var $2_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0; + var $2_1 = 0, $4_1 = 0, $5_1 = 0; block : { $2_1 = $0; $4_1 = 6; diff --git a/test/wasm2js/br_table_temp.2asm.js b/test/wasm2js/br_table_temp.2asm.js index d12bfb2cb..a38640d64 100644 --- a/test/wasm2js/br_table_temp.2asm.js +++ b/test/wasm2js/br_table_temp.2asm.js @@ -49725,7 +49725,7 @@ function asmFunc(global, env, buffer) { function $34($0, $1_1) { $0 = $0 | 0; $1_1 = $1_1 | 0; - var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0; + var $3_1 = 0, $4_1 = 0, $5_1 = 0; block : { $3_1 = 5; switch (0 | 0) { @@ -49739,7 +49739,7 @@ function asmFunc(global, env, buffer) { function $35($0, $1_1) { $0 = $0 | 0; $1_1 = $1_1 | 0; - var $2_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0; + var $2_1 = 0, $4_1 = 0, $5_1 = 0; block : { $2_1 = $0; $4_1 = 6; diff --git a/test/wasm2js/i64-select.2asm.js b/test/wasm2js/i64-select.2asm.js index 414005b40..dc6889683 100644 --- a/test/wasm2js/i64-select.2asm.js +++ b/test/wasm2js/i64-select.2asm.js @@ -42,6 +42,18 @@ function asmFunc(global, env, buffer) { return i64toi32_i32$3 | 0; } + function unreachable_select_i64() { + return abort() | 0; + } + + function unreachable_select_i64_b() { + return abort() | 0; + } + + function unreachable_select_i64_c() { + return abort() | 0; + } + var FUNCTION_TABLE = []; return { diff --git a/test/wasm2js/i64-select.wast b/test/wasm2js/i64-select.wast index e5f3a6bab..1fc356c88 100644 --- a/test/wasm2js/i64-select.wast +++ b/test/wasm2js/i64-select.wast @@ -20,4 +20,25 @@ ) ) ) + (func $unreachable-select-i64 (result i64) + (select + (i64.const 1) + (unreachable) + (i32.const 268435456) + ) + ) + (func $unreachable-select-i64-b (result i64) + (select + (unreachable) + (i64.const 1) + (i32.const 268435456) + ) + ) + (func $unreachable-select-i64-c (result i64) + (select + (i64.const 1) + (i64.const 1) + (unreachable) + ) + ) ) diff --git a/test/wasm2js/select.2asm.js b/test/wasm2js/select.2asm.js index 1deedbbfd..893d6db56 100644 --- a/test/wasm2js/select.2asm.js +++ b/test/wasm2js/select.2asm.js @@ -65,13 +65,13 @@ function asmFunc(global, env, buffer) { function $4(cond) { cond = cond | 0; - var $1_1 = 0, $2_1 = 0; + var $1_1 = 0; return abort() | 0; } function $5(cond) { cond = cond | 0; - var $1_1 = 0, $2_1 = 0; + var $1_1 = 0; return abort() | 0; } |