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 /src | |
parent | 5becae69e29c876f3ba46d6746764e409bd7fd9b (diff) | |
download | binaryen-a4baf2152d11c28964025759d2702fe7c48d321e.tar.gz binaryen-a4baf2152d11c28964025759d2702fe7c48d321e.tar.bz2 binaryen-a4baf2152d11c28964025759d2702fe7c48d321e.zip |
wasm2js: handle unreachable select and global.set (#2029)
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/I64ToI32Lowering.cpp | 21 |
1 files changed, 21 insertions, 0 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() { |