diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-04-29 16:30:40 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-04-29 16:30:40 -0700 |
commit | 199c7d3e558d4c2f3dc6be1e0fc826ca45b52b8f (patch) | |
tree | c3a7cc43a52a5b006d2ae6acd9470c18a778d15d | |
parent | eb2ea67bf52eac93de977922763a0ee3787be240 (diff) | |
parent | af6b1a77673b1c49f4501918385bd463c50cb28b (diff) | |
download | binaryen-199c7d3e558d4c2f3dc6be1e0fc826ca45b52b8f.tar.gz binaryen-199c7d3e558d4c2f3dc6be1e0fc826ca45b52b8f.tar.bz2 binaryen-199c7d3e558d4c2f3dc6be1e0fc826ca45b52b8f.zip |
Merge pull request #416 from WebAssembly/full-validation-nice
Full validation
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rwxr-xr-x | build-js.sh | 4 | ||||
-rwxr-xr-x | check.py | 1 | ||||
-rw-r--r-- | src/ast_utils.h | 2 | ||||
-rw-r--r-- | src/binaryen-shell.cpp | 1 | ||||
-rw-r--r-- | src/wasm-binary.h | 6 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 3 | ||||
-rw-r--r-- | src/wasm-validator.h | 183 | ||||
-rw-r--r-- | src/wasm.cpp | 84 | ||||
-rw-r--r-- | src/wasm.h | 17 | ||||
-rw-r--r-- | test/dot_s/exit.s | 1 | ||||
-rw-r--r-- | test/dot_s/exit.wast | 1 | ||||
-rw-r--r-- | test/llvm_autogenerated/i64-load-store-alignment.s | 4 | ||||
-rw-r--r-- | test/llvm_autogenerated/i64-load-store-alignment.wast | 4 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.txt | 4 | ||||
-rw-r--r-- | test/passes/remove-unused-brs.wast | 4 |
16 files changed, 285 insertions, 42 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e6834c57..b948328f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,7 @@ SET(binaryen-shell_SOURCES src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/passes/Metrics.cpp + src/wasm.cpp ) ADD_EXECUTABLE(binaryen-shell ${binaryen-shell_SOURCES}) @@ -129,6 +130,7 @@ SET(asm2wasm_SOURCES src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp + src/wasm.cpp ) ADD_EXECUTABLE(asm2wasm ${asm2wasm_SOURCES}) @@ -142,6 +144,7 @@ SET(wasm2asm_SOURCES src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp + src/wasm.cpp ) ADD_EXECUTABLE(wasm2asm ${wasm2asm_SOURCES}) @@ -155,6 +158,7 @@ SET(s2wasm_SOURCES src/passes/Print.cpp src/wasm-linker.cpp src/s2wasm-main.cpp + src/wasm.cpp ) ADD_EXECUTABLE(s2wasm ${s2wasm_SOURCES}) @@ -164,7 +168,10 @@ SET_PROPERTY(TARGET s2wasm PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS s2wasm DESTINATION bin) SET(wasm_as_SOURCES + src/pass.cpp + src/passes/Print.cpp src/wasm-as.cpp + src/wasm.cpp ) ADD_EXECUTABLE(wasm-as ${wasm_as_SOURCES}) @@ -177,6 +184,7 @@ SET(wasm_dis_SOURCES src/pass.cpp src/passes/Print.cpp src/wasm-dis.cpp + src/wasm.cpp ) ADD_EXECUTABLE(wasm-dis ${wasm_dis_SOURCES}) diff --git a/build-js.sh b/build-js.sh index c4dc57b27..ce8038f51 100755 --- a/build-js.sh +++ b/build-js.sh @@ -6,9 +6,9 @@ echo "building wasm.js" -em++ -std=c++11 src/wasm-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/OptimizeInstructions.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp -Isrc/ -o bin/wasm.js -s MODULARIZE=1 -s 'EXPORT_NAME="WasmJS"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 #-DWASM_JS_DEBUG -DWASM_INTERPRETER_DEBUG=2 +em++ -std=c++11 src/wasm-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/OptimizeInstructions.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp src/wasm.cpp -Isrc/ -o bin/wasm.js -s MODULARIZE=1 -s 'EXPORT_NAME="WasmJS"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 #-DWASM_JS_DEBUG -DWASM_INTERPRETER_DEBUG=2 echo "building binaryen.js" python ~/Dev/emscripten/tools/webidl_binder.py src/js/binaryen.idl glue -em++ -std=c++11 src/binaryen-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp -Isrc/ -o bin/binaryen.js -s MODULARIZE=1 -s 'EXPORT_NAME="Binaryen"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 -s INVOKE_RUN=0 --post-js glue.js +em++ -std=c++11 src/binaryen-js.cpp src/pass.cpp src/passes/MergeBlocks.cpp src/passes/Print.cpp src/passes/RemoveUnusedBrs.cpp src/passes/RemoveUnusedNames.cpp src/passes/PostEmscripten.cpp src/passes/SimplifyLocals.cpp src/passes/ReorderLocals.cpp src/passes/Vacuum.cpp src/emscripten-optimizer/parser.cpp src/emscripten-optimizer/simple_ast.cpp src/emscripten-optimizer/optimizer-shared.cpp src/support/colors.cpp src/support/safe_integer.cpp src/support/bits.cpp src/support/threads.cpp src/asmjs/asm_v_wasm.cpp src/asmjs/shared-constants.cpp src/wasm.cpp -Isrc/ -o bin/binaryen.js -s MODULARIZE=1 -s 'EXPORT_NAME="Binaryen"' --memory-init-file 0 -Oz -s ALLOW_MEMORY_GROWTH=1 -profiling -s DEMANGLE_SUPPORT=1 -s INVOKE_RUN=0 --post-js glue.js @@ -572,6 +572,7 @@ print '\n[ checking example testcases... ]\n' cmd = [os.environ.get('CXX') or 'g++', '-std=c++11', os.path.join('test', 'example', 'find_div0s.cpp'), os.path.join('src', 'pass.cpp'), + os.path.join('src', 'wasm.cpp'), os.path.join('src', 'passes', 'Print.cpp'), '-Isrc', '-g', '-lasmjs', '-lsupport', '-Llib/.', '-pthread'] if os.environ.get('COMPILER_FLAGS'): diff --git a/src/ast_utils.h b/src/ast_utils.h index 5b569435e..8aacb62da 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -23,7 +23,7 @@ namespace wasm { struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { - Name target; // look for this one + Name target; // look for this one XXX looking by name may fall prey to duplicate names size_t found; BreakSeeker(Name target) : target(target), found(false) {} diff --git a/src/binaryen-shell.cpp b/src/binaryen-shell.cpp index 509bd97dc..f988379c4 100644 --- a/src/binaryen-shell.cpp +++ b/src/binaryen-shell.cpp @@ -217,6 +217,7 @@ int main(int argc, const char* argv[]) { std::unique_ptr<SExpressionWasmBuilder> builder( new SExpressionWasmBuilder(wasm, *root[i], [&]() { abort(); })); i++; + assert(WasmValidator().validate(wasm)); MixedArena moreModuleAllocations; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 0bd86ffb6..89073b8be 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -31,6 +31,7 @@ #include "asm_v_wasm.h" #include "wasm-builder.h" #include "ast_utils.h" +#include "wasm-validator.h" namespace wasm { @@ -1187,6 +1188,10 @@ public: } processFunctions(); + + if (!WasmValidator().validate(wasm)) { + abort(); + } } bool more() { @@ -1727,6 +1732,7 @@ public: curr->name = getBreakName(getU32LEB()); if (code == BinaryConsts::BrIf) curr->condition = popExpression(); if (arity == 1) curr->value = popExpression(); + curr->finalize(); } void visitSwitch(Switch *curr) { if (debug) std::cerr << "zz node: Switch" << std::endl; diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 674341d1e..05715f739 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -424,10 +424,10 @@ private: if (!autoBlock) { autoBlock = allocator.alloc<Block>(); autoBlock->list.push_back(body); - autoBlock->finalize(); body = autoBlock; } autoBlock->list.push_back(ex); + autoBlock->finalize(); } } } @@ -1023,6 +1023,7 @@ private: } else { ret->value = parseExpression(s[i]); } + ret->finalize(); return ret; } diff --git a/src/wasm-validator.h b/src/wasm-validator.h index ca168e48b..d71a3413a 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -22,6 +22,7 @@ #define wasm_wasm_validator_h #include "wasm.h" +#include "wasm-printing.h" namespace wasm { @@ -42,32 +43,50 @@ public: void visitBlock(Block *curr) { // if we are break'ed to, then the value must be right for us if (curr->name.is()) { - if (breakTypes.count(curr->name) > 0) { - shouldBeTrue(curr->type == breakTypes[curr->name]); - breakTypes.erase(curr->name); + // none or unreachable means a poison value that we should ignore - if consumed, it will error + if (breakTypes.count(curr->name) > 0 && isConcreteWasmType(breakTypes[curr->name]) && isConcreteWasmType(curr->type)) { + shouldBeEqual(curr->type, breakTypes[curr->name], curr, "block+breaks must have right type if breaks return a value"); } + breakTypes.erase(curr->name); } } void visitLoop(Loop *curr) { if (curr->in.is()) { LoopChildChecker childChecker(curr->in); childChecker.walk(curr->body); - shouldBeTrue(childChecker.valid); + shouldBeTrue(childChecker.valid, curr, "loop must return none"); + breakTypes.erase(curr->in); + } + if (curr->out.is()) { + breakTypes.erase(curr->out); } } - void visitBreak(Break *curr) { + void noteBreak(Name name, Expression* value) { WasmType valueType = none; - if (curr->value) { - valueType = curr->value->type; + if (value) { + valueType = value->type; } - if (breakTypes.count(curr->name) == 0) { - breakTypes[curr->name] = valueType; + if (breakTypes.count(name) == 0) { + breakTypes[name] = valueType; } else { - shouldBeTrue(valueType == breakTypes[curr->name]); + if (breakTypes[name] == unreachable) { + breakTypes[name] = valueType; + } else { + shouldBeEqual(valueType, breakTypes[name], name.str, "breaks to same target must have same type (ignoring unreachable)"); + } } } + void visitBreak(Break *curr) { + noteBreak(curr->name, curr->value); + } + void visitSwitch(Switch *curr) { + for (auto& target : curr->targets) { + noteBreak(target, curr->value); + } + noteBreak(curr->default_, curr->value); + } void visitSetLocal(SetLocal *curr) { - shouldBeTrue(curr->type == curr->value->type); + shouldBeTrue(curr->type == curr->value->type, curr, "set_local type might be correct"); } void visitLoad(Load *curr) { validateAlignment(curr->align); @@ -75,28 +94,77 @@ public: void visitStore(Store *curr) { validateAlignment(curr->align); } - void visitSwitch(Switch *curr) { + void visitBinary(Binary *curr) { + if (curr->left->type != unreachable && curr->right->type != unreachable) { + shouldBeEqual(curr->left->type, curr->right->type, curr, "binary child types must be equal"); + } } void visitUnary(Unary *curr) { - shouldBeTrue(curr->value->type == curr->type); + switch (curr->op) { + case Clz: + case Ctz: + case Popcnt: + case Neg: + case Abs: + case Ceil: + case Floor: + case Trunc: + case Nearest: + case Sqrt: { + //if (curr->value->type != unreachable) { + shouldBeEqual(curr->value->type, curr->type, curr, "non-conversion unaries must return the same type"); + //} + break; + } + case EqZ: { + shouldBeEqual(curr->type, i32, curr, "relational unaries must return i32"); + break; + } + case ExtendSInt32: + case ExtendUInt32: + case WrapInt64: + case TruncSFloat32: + case TruncUFloat32: + case TruncSFloat64: + case TruncUFloat64: + case ReinterpretFloat: + case ConvertUInt32: + case ConvertSInt32: + case ConvertUInt64: + case ConvertSInt64: + case PromoteFloat32: + case DemoteFloat64: + case ReinterpretInt: { + //if (curr->value->type != unreachable) { + shouldBeUnequal(curr->value->type, curr->type, curr, "conversion unaries must not return the same type"); + //} + break; + } + default: abort(); + } } void visitFunction(Function *curr) { - shouldBeTrue(curr->result == curr->body->type); + // if function has no result, it is ignored + // if body is unreachable, it might be e.g. a return + if (curr->result != none && curr->body->type != unreachable) { + shouldBeEqual(curr->result, curr->body->type, curr->body, "function result must match, if function returns"); + } } void visitMemory(Memory *curr) { - shouldBeFalse(curr->initial > curr->max); + shouldBeFalse(curr->initial > curr->max, "memory", "memory max >= initial"); size_t top = 0; for (auto& segment : curr->segments) { - shouldBeFalse(segment.offset < top); + shouldBeFalse(segment.offset < top, "memory", "segment offset is small enough"); top = segment.offset + segment.data.size(); } - shouldBeFalse(top > curr->initial); + shouldBeFalse(top > curr->initial * Memory::kPageSize, "memory", "total segments must be small enough"); } void visitModule(Module *curr) { // exports + std::set<Name> exportNames; for (auto& exp : curr->exports) { - Name name = exp->name; + Name name = exp->value; bool found = false; for (auto& func : curr->functions) { if (func->name == name) { @@ -104,17 +172,27 @@ public: break; } } - shouldBeTrue(found); + shouldBeTrue(found, name, "module exports must be found"); + Name exportName = exp->name; + shouldBeFalse(exportNames.count(exportName) > 0, exportName, "module exports must be unique"); + exportNames.insert(exportName); } // start if (curr->start.is()) { auto func = curr->checkFunction(curr->start); - if (shouldBeTrue(func)) { - shouldBeTrue(func->params.size() == 0); // must be nullary + if (shouldBeTrue(func, curr->start, "start must be found")) { + shouldBeTrue(func->params.size() == 0, curr, "start must have 0 params"); + shouldBeTrue(func->result == none, curr, "start must not return a value"); } } } + void walk(Expression*& root) { + //std::cerr << "start a function " << getFunction()->name << "\n"; + PostWalker<WasmValidator, Visitor<WasmValidator>>::walk(root); + shouldBeTrue(breakTypes.size() == 0, "break targets", "all break targets must be valid"); + } + private: // the "in" label has a none type, since no one can receive its value. make sure no one breaks to it with a value. @@ -133,15 +211,69 @@ private: // helpers - bool shouldBeTrue(bool result) { - if (!result) valid = false; + std::ostream& fail() { + Colors::red(std::cerr); + if (getFunction()) { + std::cerr << "[wasm-validator error in function "; + Colors::green(std::cerr); + std::cerr << getFunction()->name; + Colors::red(std::cerr); + std::cerr << "] "; + } else { + std::cerr << "[wasm-validator error in module] "; + } + Colors::normal(std::cerr); + return std::cerr; + } + + template<typename T> + bool shouldBeTrue(bool result, T curr, const char* text) { + if (!result) { + fail() << "unexpected false: " << text << ", on " << curr << std::endl; + valid = false; + return false; + } return result; } - bool shouldBeFalse(bool result) { - if (result) valid = false; + template<typename T> + bool shouldBeFalse(bool result, T curr, const char* text) { + if (result) { + fail() << "unexpected true: " << text << ", on " << curr << std::endl; + valid = false; + return false; + } return result; } + template<typename T, typename S> + bool shouldBeEqual(S left, S right, T curr, const char* text) { + if (left != right) { + fail() << "" << left << " != " << right << ": " << text << ", on " << curr << std::endl; + valid = false; + return false; + } + return true; + } + template<typename T, typename S, typename U> + bool shouldBeEqual(S left, S right, T curr, U other, const char* text) { + if (left != right) { + fail() << "" << left << " != " << right << ": " << text << ", on " << curr << " / " << other << std::endl; + valid = false; + return false; + } + return true; + } + + template<typename T, typename S> + bool shouldBeUnequal(S left, S right, T curr, const char* text) { + if (left == right) { + fail() << "" << left << " == " << right << ": " << text << ", on " << curr << std::endl; + valid = false; + return false; + } + return true; + } + void validateAlignment(size_t align) { switch (align) { case 1: @@ -149,6 +281,7 @@ private: case 4: case 8: break; default:{ + fail() << "bad alignment: " << align << std::endl; valid = false; break; } diff --git a/src/wasm.cpp b/src/wasm.cpp new file mode 100644 index 000000000..2157992e3 --- /dev/null +++ b/src/wasm.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wasm.h" +#include "wasm-traversal.h" +#include "ast_utils.h" + +namespace wasm { + +struct BlockTypeSeeker : public PostWalker<BlockTypeSeeker, Visitor<BlockTypeSeeker>> { + Block* target; // look for this one + WasmType type = unreachable; + + BlockTypeSeeker(Block* target) : target(target) {} + + void noteType(WasmType other) { + // once none, stop. it then indicates a poison value, that must not be consumed + // and ignore unreachable + if (type != none) { + if (other == none) { + type = none; + } else if (other != unreachable) { + type = other; + } + } + } + + void visitBreak(Break *curr) { + if (curr->name == target->name) { + noteType(curr->value ? curr->value->type : none); + } + } + + void visitSwitch(Switch *curr) { + for (auto name : curr->targets) { + if (name == target->name) noteType(curr->value ? curr->value->type : none); + } + } + + void visitBlock(Block *curr) { + if (curr == target) { + if (curr->list.size() > 0) noteType(curr->list.back()->type); + } else { + type = unreachable; // ignore all breaks til now, they were captured by someone with the same name + } + } +}; + +void Block::finalize() { + if (list.size() > 0) { + auto last = list.back()->type; + if (last != unreachable) { + // well that was easy + type = last; + return; + } + } + if (!name.is()) { + // that was rather silly + type = unreachable; + return; + } + // oh no this is hard + BlockTypeSeeker seeker(this); + Expression* temp = this; + seeker.walk(temp); + type = seeker.type; +} + +} // namespace wasm + diff --git a/src/wasm.h b/src/wasm.h index b5dee81b8..b13011bae 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -833,11 +833,13 @@ public: Name name; ExpressionList list; - void finalize() { - if (list.size() > 0) { - type = list.back()->type; - } + // set the type of a block if you already know it + void finalize(WasmType type_) { + type = type; } + + // set the type of a block based on its contents. this scans the block, so it is not fast + void finalize(); }; class If : public SpecificExpression<Expression::IfId> { @@ -877,6 +879,12 @@ public: Name name; Expression *value; Expression *condition; + + void finalize() { + if (condition) { + type = none; + } + } }; class Switch : public SpecificExpression<Expression::SwitchId> { @@ -1022,7 +1030,6 @@ public: if (isRelational()) { type = i32; } else { - assert(left->type != unreachable && right->type != unreachable ? left->type == right->type : true); type = getReachableWasmType(left->type, right->type); } } diff --git a/test/dot_s/exit.s b/test/dot_s/exit.s index 2fad9277f..bf24ead9e 100644 --- a/test/dot_s/exit.s +++ b/test/dot_s/exit.s @@ -7,5 +7,6 @@ main: .local i32 i32.const $push0=, 0 call exit@FUNCTION, $pop0 + unreachable .Lfunc_end0: .size main, .Lfunc_end0-main diff --git a/test/dot_s/exit.wast b/test/dot_s/exit.wast index 263fbf647..77fb13b0b 100644 --- a/test/dot_s/exit.wast +++ b/test/dot_s/exit.wast @@ -9,6 +9,7 @@ (call_import $exit (i32.const 0) ) + (unreachable) ) ) ;; METADATA: { "asmConsts": {},"staticBump": 12, "initializers": [] } diff --git a/test/llvm_autogenerated/i64-load-store-alignment.s b/test/llvm_autogenerated/i64-load-store-alignment.s index a61aa2965..2f290e044 100644 --- a/test/llvm_autogenerated/i64-load-store-alignment.s +++ b/test/llvm_autogenerated/i64-load-store-alignment.s @@ -60,7 +60,7 @@ ldi64: ldi64_a16: .param i32 .result i64 - i64.load $push0=, 0($0):p2align=4 + i64.load $push0=, 0($0):p2align=3 return $pop0 .endfunc .Lfunc_end5: @@ -219,7 +219,7 @@ sti64: .type sti64_a16,@function sti64_a16: .param i32, i64 - i64.store $discard=, 0($0):p2align=4, $1 + i64.store $discard=, 0($0):p2align=3, $1 return .endfunc .Lfunc_end20: diff --git a/test/llvm_autogenerated/i64-load-store-alignment.wast b/test/llvm_autogenerated/i64-load-store-alignment.wast index 9741e5a72..d6c76de7a 100644 --- a/test/llvm_autogenerated/i64-load-store-alignment.wast +++ b/test/llvm_autogenerated/i64-load-store-alignment.wast @@ -70,7 +70,7 @@ ) (func $ldi64_a16 (param $$0 i32) (result i64) (return - (i64.load align=16 + (i64.load (get_local $$0) ) ) @@ -174,7 +174,7 @@ (return) ) (func $sti64_a16 (param $$0 i32) (param $$1 i64) - (i64.store align=16 + (i64.store (get_local $$0) (get_local $$1) ) diff --git a/test/passes/remove-unused-brs.txt b/test/passes/remove-unused-brs.txt index a7bd70ecc..a8e7f29be 100644 --- a/test/passes/remove-unused-brs.txt +++ b/test/passes/remove-unused-brs.txt @@ -88,7 +88,7 @@ ) ) ) - (func $b12-yes (result i32) + (func $b12-yes (block $topmost (select (block $block1 @@ -144,7 +144,7 @@ ) ) ) - (func $b15 (result i32) + (func $b15 (block $topmost (br_if $topmost (i32.const 0) diff --git a/test/passes/remove-unused-brs.wast b/test/passes/remove-unused-brs.wast index dc67ad4da..8b9d42bc1 100644 --- a/test/passes/remove-unused-brs.wast +++ b/test/passes/remove-unused-brs.wast @@ -91,7 +91,7 @@ ) ) ) - (func $b12-yes (result i32) + (func $b12-yes (block $topmost (if_else (i32.const 1) (block @@ -149,7 +149,7 @@ ) ) ) - (func $b15 (result i32) + (func $b15 (block $topmost (if (i32.const 18) |